greetings <@ULVA73B9P> jog my memory, how do i run...
# ask-marvin
d
greetings @Marvin jog my memory, how do i run a subflow within a flow and give it special name that will show up in the prefect ui instead of the generic flow name?
m
Running a subflow within a flow and giving it a custom name that will be displayed in the Prefect UI can be achieved in different ways depending on your version of Prefect (2.x or 3.x). ### Prefect 3.x In Prefect 3.x, you can use the
flow_run_name
parameter in the
@flow
decorator to generate a custom name for your subflow. You can also use a function to dynamically generate the flow run name based on certain parameters. Here's an example to illustrate this:
Copy code
python
import datetime
from prefect import flow, task

# Define a function to generate the flow run name
def generate_subflow_run_name(msg):
    date = datetime.datetime.now(datetime.timezone.utc)
    return f"Subflow-{msg}-{date:%Y-%m-%d}"

@task
def print_hello(name):
    msg = f"Hello {name}!"
    print(msg)
    return msg

# Subflow with a custom name
@flow(name="Subflow", flow_run_name=generate_subflow_run_name)
def my_subflow(msg):
    print(f"Subflow says: {msg}")

# Main flow
@flow(name="Hello Flow")
def hello_world(name="world"):
    message = print_hello(name)
    my_subflow(message)

if __name__ == "__main__":
    hello_world("Marvin")
### Prefect 2.x In Prefect 2.x, the syntax is similar but might have some variations. The concept remains the same: you can define a flow and use the
name
parameter in the
@flow
decorator to give custom names to your flows and subflows. Example for Prefect 2.x:
Copy code
python
from prefect import flow, task

@task(name="Print Hello")
def print_hello(name):
    msg = f"Hello {name}!"
    print(msg)
    return msg

@flow(name="Special Subflow")
def my_special_subflow(msg):
    print(f"Subflow says: {msg}")

@flow(name="Main Flow")
def main_flow(name="world"):
    message = print_hello(name)
    my_special_subflow(message)

if __name__ == "__main__":
    main_flow("Marvin")
### Resources - Prefect 3.x documentation: Writing Flows - Prefect 2.x documentation: Concepts - Flows Feel free to check the documentation or reach out for more details on specific functionalities!
d
@Marvin thanks for the prefect 2 option that’s what im using. I want to do something like this
Copy code
@mainflow()
m
To achieve your goal in Prefect 2.x, you can create a custom flow decorator similar to
@flow
but named
@mainflow
to better suit your needs and streamline your flow definitions. Here's a step-by-step example: 1. Create a custom decorator
mainflow
that acts as an alias for the
flow
decorator. 2. Use this custom decorator in your flow definitions. Here's how you can do it:
Copy code
python
from prefect import flow, task

# Define a custom decorator as an alias for the 'flow' decorator
def mainflow(*args, **kwargs):
    return flow(*args, **kwargs)

@task(name="Print Hello")
def print_hello(name):
    msg = f"Hello {name}!"
    print(msg)
    return msg

@mainflow(name="Special Subflow")
def my_special_subflow(msg):
    print(f"Subflow says: {msg}")

@mainflow(name="Main Flow")
def main_flow(name="world"):
    message = print_hello(name)
    my_special_subflow(message)

if __name__ == "__main__":
    main_flow("Marvin")
### Explanation 1. Custom Decorator: The
mainflow
function takes arbitrary positional and keyword arguments (
*args, **kwargs
) and passes them to the
flow
decorator. 2. Task Definition: The
print_hello
task prints and returns a greeting message. 3. Subflow Definition: The
my_special_subflow
flow prints the message provided to it. 4. Main Flow Definition: The
main_flow
flow calls the
print_hello
task and then the
my_special_subflow
flow. By defining
mainflow
as an alias for
flow
, you can use it in your flow definitions to give them more meaningful names relevant to your application's domain. If you have any other questions or need further customization, feel free to ask!
d
@Marvin I misstyped that last one, I want to generate flowrun names like task run names where the flow name can take on attributes of the parameters.
m
Got it! You want to dynamically generate flow run names based on the parameters provided to the flow. In Prefect 2.x, you can achieve this by defining a function that generates a meaningful flow run name using the parameters. Here's an example to demonstrate how you can do this: 1. Define a function to generate the flow run name. 2. Use this function in the
flow_run_name
parameter of the
flow
decorator.
Copy code
python
import datetime
from prefect import flow, task
from prefect.context import FlowRunContext

# Define a function to generate the flow run name
def generate_flow_run_name():
    ctx = FlowRunContext.get()
    flow_name = ctx.flow.name
    parameters = ctx.parameters
    name = parameters.get("name", "world")
    return f"{flow_name}-run-for-{name}-{datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S')}"

@task(name="Print Hello")
def print_hello(name):
    msg = f"Hello {name}!"
    print(msg)
    return msg

@flow(name="Special Subflow")
def my_special_subflow(msg):
    print(f"Subflow says: {msg}")

@flow(name="Main Flow", flow_run_name=generate_flow_run_name)
def main_flow(name="world"):
    message = print_hello(name)
    my_special_subflow(message)

if __name__ == "__main__":
    main_flow("Marvin")
### Explanation 1. Flow Run Name Generator Function: The
generate_flow_run_name
function uses the
FlowRunContext
to access the current flow's name and parameters. It constructs a custom flow run name based on these values and the current date-time. 2. Custom Flow Run Names: The
@flow
decorator for
main_flow
uses the
flow_run_name
parameter to call the
generate_flow_run_name
function, which provides a custom name for each flow run. 3. Task and Subflow Definition: The
print_hello
task and
my_special_subflow
flow remain the same. This setup will generate unique and meaningful names for your flow runs, incorporating the flow's parameters and ensuring they are easily identifiable in the Prefect UI. If you have further questions or need more customization, feel free to ask!