Anyone know how to get the text in the Prefect UI ...
# prefect-ui
t
Anyone know how to get the text in the Prefect UI for parameters to be formatted in something other than a big blob of text?
n
hey @Tom Jordahl - yes! in short, pydantic models is the answer
if i understand the question
t
We just have a jumble of text in the web UI for our parameters. I would like to have a nice formatted list.
The dropdown is fine, its the docstring text above it that I want to at least be able to have line breaks in
n
can you show an example of what you mean?
i see. so basically the docstring of the pydantic model that you're using is annoying / in the way?
t
No, its valuable information, I just want it to be more readable
n
got it - thank you
t
Even just a
<br>
tag would work
(deleted the image ’cause I don’t want to leave it lying around)
👍 1
n
would you mind creating an enhancement issue about this? you can use this MRE
Copy code
from pydantic import BaseModel

from prefect import flow


class BadParams(BaseModel):
    """This is a realllllly long description that should be rendered as markdown


    Attributes:
        a: This is a really long description that should be rendered as markdown
        b: This is a really long description that should be rendered as markdown
        c: This is a really long description that should be rendered as markdown
        x: This is a really long description that should be rendered as markdown
        y: This is a really long description that should be rendered as markdown
        z: This is a really long description that should be rendered as markdown
    """

    a: int
    b: int
    c: int
    x: int
    y: int
    z: int


@flow
def bad_params_render(params: BadParams):
    pass


if __name__ == "__main__":
    bad_params_render.serve()
t
Sure. Do you have the link for creating issues handy?
thank you!
1
t
j
I mean, you don't know that everyone wants their docstrings in Markdown - some of us use sphinx and their docstrings are in RST?
t
Doesn’t matter to me, just some way to make it pretty
n
yes! this is why issues are useful to present the problem at hand, and discuss the best way to solve in general
👍 1
j
Hey @Tom Jordahl I ran into this while looking for more documentation on Parameter documentation formatting, and I'm a little confused about what you're asking about.
Hey @Tom Jordahl I ran into this while looking for more docs on parameter documentation (can't find any 😄), and I'm a little confused about what you're asking about. In your example you're adding 6 individual required parameters all of which take an
int
, but from what you're asking it seems more like you want a single parameter that requires users to choose from one of 6 predefined values and you want to document the meaning of each. Which is correct? Because if it's the former then you can try:
Copy code
class BadParams(BaseModel):
    """This is a realllllly long description that should be rendered as markdown"""

    a: int = Field(description="This is a really long description that should be rendered.")
    b: int = Field(description="This is a really long description that should be rendered.")
    c: int = Field(description="This is a really long description that should be rendered.")
    x: int = Field(description="This is a really long description that should be rendered.")
    y: int = Field(description="This is a really long description that should be rendered.")
    z: int = Field(description="This is a really long description that should be rendered.")
Then the descriptions will be rendered just below the parameter name like this (excuse my ASCII art) in the UI: > A > This is a really long description that should be rendered. > [ input box ]
t
@Jacob Blanco - We have an enumeration as a flow parameter, which presents as a dropdown list in the UI which is 👍 But the documentation for the enumeration has no way to make the information presented in the UI readable e.g. as a bulleted list. It is all run together in a blob.
j
Oh got it. Not that this solves your problem as you want it, but you can add links to the description and they will be clickable in the UI. We use this for more long-form guides that wouldn't make sense in the form.
n
perhaps this example is useful?
🚀 1
generally in the docstring you can just write markdown
j
This is awesome, and actually answers the question I posted as well.
catjam 1
t
🤔 - This is certainly close to what I want. We have the docstring in the Enum itself. So for your example the code would be this:
Copy code
class DataProcessingStage(Enum):
    """Input parameters for the data processing pipeline.
    ## *possible pipeline stage values:*
    Each stage represents a distinct processing phase:

    - RAW_INGESTION: Initial data load from source systems
    - CLEAN: Apply data cleaning and validation rules
...
    """
    RAW_INGESTION = "raw_ingestion"
    CLEAN = "clean"
    TRANSFORM = "transform"
    AGGREGATE = "aggregate"
    EXPORT = "export"
Can I do this? Can I use markdown in Prefect 2.x or is this a 3.x feature?
n
this is about how the UI renders deployment parameters, not the SDK. so should work now for either version of the SDK you have
t
ok, thanks.
@Nate So putting markdown in the enum docstring did not seem to work. I still get everything run together.
n
in my example I didn't put the markdown in the nested type i'd put the markdown you want to render in the function docstring
t
Right, not sure how that works for my flows. My enum is used in various flows
Copy code
@flow
def harvest(
    argument1: DataBricksHarvestDataSetIdentifier,
    target_identifier: TargetIdentifier,
)
Copy code
class TargetIdentifier(Enum):
    """
    The list of target identifiers.

    *Environments*:

    - DEV: Development environment
j
One approach we've just started to take is leveraging a model to create a standard set of re-usable parameters. You could do something similar like this
Copy code
class ReusableJobParameters(pydantic.BaseModel):
    target_identifier: TargetIdentifier = pydantic.Field(description="Your description of options here")
Then use the model in your flows.
Copy code
@flow
def flow_using_target_identifier(
    argument1: DataBricksHarvestDataSetIdentifier,
    target_parameters: ReusableJobParameters
):
    # Some flow code that uses `target_parameters.target_identifier`
This will include parameter level documentation in any flow that uses the enum this way and you can include additional standard parameters as well.
upvote 1