Decorators (@workflow, @task)

Use decorators to create structured, nested traces that show how your app flows.
  1. Sign up — Create an account at platform.respan.ai
  2. Create an API key — Generate one on the API keys page
  3. Add credits or a provider key — Add credits on the Credits page or connect your own provider key on the Integrations page

Add the Docs MCP to your AI coding tool to get help building with Respan. No API key needed.

1{
2 "mcpServers": {
3 "respan-docs": {
4 "url": "https://mcp.respan.ai/mcp/docs"
5 }
6 }
7}

The Respan tracing SDK provides decorators and wrappers to instrument your code. This page covers the detailed features.


Decorators & span types

Use decorators (Python) or wrapper methods (JS/TS) to create spans. Each decorator creates a different span type in the trace tree.

DecoratorSpan typeUse for
@workflow / withWorkflowWorkflowTop-level parent span
@task / withTaskTaskIndividual steps within a workflow
@agent / withAgentAgentAgent-level operations
@tool / withToolToolTool/function calls
1from openai import OpenAI
2from respan import Respan
3from respan.decorators import workflow, task
4
5Respan()
6client = OpenAI()
7
8@task(name="joke_creation")
9def create_joke():
10 completion = client.chat.completions.create(
11 model="gpt-5.4",
12 messages=[{"role": "user", "content": "Tell me a joke about opentelemetry"}],
13 )
14 return completion.choices[0].message.content
15
16@task(name="pirate_joke_translation")
17def translate_joke_to_pirate(joke: str):
18 completion = client.chat.completions.create(
19 model="gpt-5.4",
20 messages=[{"role": "user", "content": "translate to pirate language:\n\n" + joke}],
21 )
22 return completion.choices[0].message.content
23
24@workflow(name="joke_workflow")
25def joke_workflow():
26 joke = create_joke()
27 pirate_joke = translate_joke_to_pirate(joke)
28 return pirate_joke
29
30result = joke_workflow()
31print(result)

For the full SDK API reference, see the Python SDK or TypeScript SDK.


Class-based workflows

Apply @workflow to a class with method_name to designate the entry point. Use @task on individual methods.

1from openai import OpenAI
2from respan import Respan
3from respan.decorators import workflow, task
4
5Respan()
6client = OpenAI()
7
8@workflow(name="joke_agent", method_name="run")
9class JokeAgent:
10 @task(name="joke_creation")
11 def create_joke(self):
12 completion = client.chat.completions.create(
13 model="gpt-5.4",
14 messages=[{"role": "user", "content": "Tell me a joke"}],
15 )
16 return completion.choices[0].message.content
17
18 def run(self):
19 return self.create_joke()
20
21agent = JokeAgent()
22result = agent.run()