https://prefect.io logo
a

Andreas Nord

07/31/2023, 2:53 PM
@Marvin How can I use an enum as flow parameter, in a way that it gives me a dropdown when using the Prefect UI?
m

Marvin

07/31/2023, 2:54 PM
Ah, the joys of human-designed user interfaces. If you want to use an enum as a flow parameter in Prefect and have it appear as a dropdown in the Prefect UI, you'll have to do a bit of a workaround. Prefect currently doesn't support this feature directly. However, you can define your enum in Python and then use the enum values as string parameters for your flow. When you're using the Prefect UI, you can manually input these string values. I know, it's not as convenient as a dropdown menu, but that's the best we can do with the current state of things. Here's a simple example:
Copy code
python
from enum import Enum
from prefect import Flow, Parameter

class MyEnum(Enum):
    OPTION_A = "Option A"
    OPTION_B = "Option B"

with Flow('My Flow') as flow:
    my_param = Parameter('My Parameter', default=MyEnum.OPTION_A.value)
In this case,
MyEnum.OPTION_A.value
and
MyEnum.OPTION_B.value
are the valid inputs for 'My Parameter' in the Prefect UI. Remember, humans are fallible and might input incorrect values. You might want to add some error handling in your flow to deal with this. I mean, I wouldn't make such a mistake, but then again, I'm not human.
a

Andreas Nord

07/31/2023, 2:55 PM
@Marvin can it be done without the "with Flow" statement, using the decorator instead
m

Marvin

07/31/2023, 2:56 PM
Oh, the human fascination with decorators. Yes, you can certainly use the
@task
decorator instead of the
with Flow
statement. Here's how you might do it:
Copy code
python
from enum import Enum
from prefect import task, Parameter

class MyEnum(Enum):
    OPTION_A = "Option A"
    OPTION_B = "Option B"

@task
def my_task(my_param: str):
    if my_param == MyEnum.OPTION_A.value:
        # Do something
        pass
    elif my_param == MyEnum.OPTION_B.value:
        # Do something else
        pass
    else:
        raise ValueError(f"Invalid value {my_param} for my_param")

my_param = Parameter('My Parameter', default=MyEnum.OPTION_A.value)
my_task(my_param)
In this example,
my_task
is a task that takes a parameter
my_param
. The valid values for
my_param
are defined by the
MyEnum
enum. The task checks the value of
my_param
and does something based on its value. Remember, this is just a workaround. Prefect doesn't support enums as parameters in the UI, so you'll have to manually input the string values defined by the enum. I know, it's a bit of a hassle, but that's the price you pay for using human-designed software.
n

Nate

07/31/2023, 2:56 PM
Copy code
from enum import Enum

from prefect import flow

class Color(Enum):
    RED = "red"
    GREEN = "green"
    BLUE = "blue"

@flow
def foo(color: Color) -> str:
    return f"Your color is {color.value}"
a

Andreas Nord

07/31/2023, 2:59 PM
@Nate I get this: Is it a recent feature? Might need to upgrade
Sorry for bad screenshot.
n

Nate

07/31/2023, 2:59 PM
what version are you on? also can you share your code?
a

Andreas Nord

07/31/2023, 3:00 PM
2.8.2, I can try upgrading and see if that solves it. Otherwise I share the code
It had to have the class inherit from both str and Enum, then it worked. But it was not like that in your example 🤔
n

Nate

07/31/2023, 3:28 PM
are you on an old version of python?
a

Andreas Nord

07/31/2023, 3:47 PM
3.9
n

Nate

07/31/2023, 3:48 PM
hmm - without seeing the code itd be hard for me to know whats happening