-
Notifications
You must be signed in to change notification settings - Fork 141
Description
Problem
In the Python SDK, workflows must invoke activities explicitly via workflow.execute_activity() / start_activity(). This adds boilerplate at call sites (repeating options like timeouts/retries) and surprises users who expect decorator‑marked callables to be directly invocable inside workflows.
Why it matters
- Readability/teachability: code is less declarative;
@activity.defnlooks like a function you can call, but you can’t. - Ergonomics: the same options are repeated in every call site even when they’re identical.
- Consistency: other task/flow frameworks allow direct invocation of decorated tasks within flows, reducing ceremony.
Comparison with Prefect
Below are minimal examples showing how a similar pattern looks today.
Prefect (2.x):
from prefect import flow, task
@task
def fetch_article(url: str) -> str:
...
@flow
def pipeline(url: str):
# Direct call (sync semantics) or .submit() for concurrency
html = fetch_article(url)
# html = fetch_article.submit(url)
return htmlTemporal Python today:
from datetime import timedelta
from temporalio import workflow
from temporalio import activity
@activity.defn
async def fetch_article(url: str) -> str:
...
@workflow.defn
class Pipeline:
@workflow.run
async def run(self, url: str) -> str:
html = await workflow.execute_activity(
fetch_article,
url,
start_to_close_timeout=timedelta(seconds=30),
# plus any retry/heartbeat options at each call site
)
return htmlThis issue is to track interest in more ergonomic, decorator‑style activity invocation in Python workflows—while preserving Temporal’s determinism and activity semantics. No specific API is proposed here; the goal is to document the pain point and contrast with common expectations from Prefect‑style flows.