<@ULVA73B9P> I have a flow that returns a string f...
# ask-marvin
m
@Marvin I have a flow that returns a string filepath. I want to call this as a subflow, how do I examine the state of the subflow when its finished?
m
To examine the state of a subflow in Prefect 3.x, you can use the
State
object, which is part of Prefect's top-level API. When a subflow completes, it returns a
State
object that you can inspect to determine the outcome and retrieve results. Here's a basic approach to achieve this: 1. Run the Subflow: When you call a flow as a subflow, it will return a
State
object. 2. Inspect the State: You can check the state type (e.g.,
Completed
,
Failed
) and retrieve the result. Here's a simple example:
Copy code
python
from prefect import flow, task, State

@flow
def my_subflow():
    return "path/to/file"

@flow
def parent_flow():
    subflow_state: State = my_subflow(return_state=True)
    if subflow_state.is_completed():
        result = subflow_state.result()
        print(f"Subflow completed with result: {result}")
    else:
        print(f"Subflow did not complete successfully. State: {subflow_state}")

parent_flow()
In this example,
my_subflow
is called within
parent_flow
, and its state is checked to determine if it completed successfully. You can then access the result directly from the state. For more details, you can refer to the Prefect documentation on flow states and the Prefect API.
m
@Marvin this is good, now I get "Completed()" as a return value from the subflow. How do I also retrieve the flow return value "path/to/file"?
m
To retrieve the return value from a subflow in Prefect 3.x, you should ensure that the subflow's result is accessed directly from the flow run's state. The state object of a flow run holds the result, and you can extract it using the
result()
method. Here's a general approach to achieve this: 1. Execute the Subflow: When you call a subflow, it returns a state object. 2. Access the Result: Use the
result()
method on the state object to fetch the actual return value. Here's a concise example:
Copy code
python
from prefect import flow

@flow
def subflow():
    return "path/to/file"

@flow
def main_flow():
    subflow_state = subflow(return_state=True)
    result = subflow_state.result()
    print(result)  # This should print "path/to/file"

main_flow()
Make sure you set
return_state=True
when calling the subflow to get the state object back. Then, use the
result()
method to extract the return value. For more details on handling flow results and states, you might want to check the Prefect documentation.
m
@Marvin This is almost working in an async context. My results for the flows are coming back from coroutines, so the subflow_state.result() is
Completed()
. But how can I retrieve the data portion? The subflow_state looks in the logs like ` result=UnpersistedResult(type='unpersisted', artifact_type='result', artifact_description='Unpersisted result of type `list`'))`
m
To retrieve the data portion of a
Completed
state when dealing with asynchronous contexts in Prefect 3.x, you can use the
get_state_result
function from the
prefect.states
module. This function is designed to extract the result from a state, even when it's wrapped in an
UnpersistedResult
. Here's how you can use it:
Copy code
python
from prefect import flow
from prefect.states import get_state_result

@flow
async def subflow():
    return "path/to/file"

@flow
async def main_flow():
    subflow_state = await subflow(return_state=True)
    result = await get_state_result(subflow_state)
    print(result)  # This should print "path/to/file"

import asyncio
asyncio.run(main_flow())
### Key Points: -
get_state_result
: This function is used to extract the result from a state object. It handles both persisted and unpersisted results. - Async/Await: Ensure that you're using
await
when calling asynchronous functions like
get_state_result
. For further details on managing results in Prefect, you can refer to the Prefect documentation on results.