Eduardo Alfonso-Sierra
01/28/2024, 1:31 PMtask.fn()
to call a task outside of a flow, but that's exactly the point, that by turning a function into a @task, existing code -e.g. tests- that assumes a normal function will not work anymore).
One workaround for that is not to use the @task decorator at the function definition, but only within the flow definition. So I illustrate the idea here with a silly but reproducible example:
Let's say we have something like this
def foo():
return "foo"
def flow():
foo()
flow() # runs fine from everywhere, but no benefits from orchestrator
foo() # runs fine to try things out interactively or within a pytest function test_foo
And then we introduce Prefect, pretty easy, just add @task and @flow and there you go
from prefect import flow, task
@task
def foo():
return "foo"
@flow
def flow():
foo()
flow() # runs fine and you get all the perks of a prefectly orchestrated flow
foo() # but this fails with error "Tasks cannot be run outside of a flow" ¯\_(ツ)_/¯
So my question is how bad an idea is to do something like this:
from prefect import flow, task
# DO NOT DECORATE THIS FN AS A TASK
def foo():
return "foo"
@flow
def flow():
# BUT ONLY MAKE IT A TASK WITHIN THE FLOW DEFINITION
foo_task = task(foo)
foo_task()
flow() # runs fine
foo() # again, runs fin everywhere
That works, and you can keep using your little foo function everywhere. But not sure if such a thing is an anti-pattern that could come back to bite us later down the line.Nate
01/28/2024, 5:30 PMNate
01/28/2024, 5:33 PMwith_options
is also a useful class method on tasks and flows that allow you to configure existing task/flow objects dynamically that often circumvents the need to do something like task(**options)(my_fn)
Eduardo Alfonso-Sierra
01/28/2024, 6:17 PMEduardo Alfonso-Sierra
01/28/2024, 6:31 PMEduardo Alfonso-Sierra
01/28/2024, 6:32 PMNate
01/28/2024, 6:32 PMEduardo Alfonso-Sierra
01/28/2024, 6:36 PMNate
01/28/2024, 6:38 PM