> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mutagent.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Python SDK Tracing

> Add OTel-aligned observability to your Python LLM applications

# Python Tracing

The `mutagent.tracing` module provides OTel-aligned span instrumentation with no external collector required. It ships as part of `mutagent-sdk`.

## Install

```bash theme={null}
pip install mutagent-sdk
```

## Initialize

Call `init_tracing` once at application startup:

```python theme={null}
from mutagent.tracing import init_tracing

init_tracing(api_key="mt_xxxxxxxxxxxx")
```

Or use the `MUTAGENT_API_KEY` environment variable and skip the argument:

```python theme={null}
import os
from mutagent.tracing import init_tracing

init_tracing(api_key=os.environ["MUTAGENT_API_KEY"])
```

## Decorate Functions

The `@trace` decorator is the simplest way to add tracing. It captures the function's input arguments, return value, duration, and any exceptions:

```python theme={null}
from mutagent.tracing import init_tracing, trace

init_tracing(api_key="mt_xxxxxxxxxxxx")

@trace(kind="agent")
def run_support_agent(query: str) -> str:
    # All inputs, outputs, and timing are captured automatically
    response = call_llm(query)
    return response
```

Works with async functions too:

```python theme={null}
@trace(kind="agent")
async def run_async_agent(query: str) -> str:
    response = await call_llm_async(query)
    return response
```

### `@trace` Parameters

| Parameter | Type          | Default       | Description                 |
| --------- | ------------- | ------------- | --------------------------- |
| `kind`    | `SpanKind`    | `"custom"`    | Span kind — see table below |
| `name`    | `str \| None` | function name | Override the span name      |

## Span Kinds

| Kind             | Value              | Use Case             |
| ---------------- | ------------------ | -------------------- |
| `llm.chat`       | `"llm.chat"`       | Chat completions     |
| `llm.completion` | `"llm.completion"` | Text completions     |
| `llm.embedding`  | `"llm.embedding"`  | Embedding generation |
| `chain`          | `"chain"`          | Sequential pipelines |
| `agent`          | `"agent"`          | Agent execution      |
| `graph`          | `"graph"`          | Graph workflows      |
| `node`           | `"node"`           | Graph nodes          |
| `tool`           | `"tool"`           | Tool invocations     |
| `retrieval`      | `"retrieval"`      | RAG retrieval        |
| `guardrail`      | `"guardrail"`      | Safety checks        |
| `custom`         | `"custom"`         | Any other use case   |

## Low-Level API

For fine-grained control, use `start_span` and `end_span` directly:

```python theme={null}
from mutagent.tracing import (
    init_tracing,
    start_span,
    end_span,
    SpanOptions,
    SpanEndOptions,
    SpanIO,
    SpanMetrics,
    SpanKind,
    SpanStatus,
)

init_tracing(api_key="mt_xxxxxxxxxxxx")

span = start_span(SpanOptions(
    kind="chain",
    name="my-pipeline",
    input=SpanIO(text="user query here"),
))

# ... do work ...

if span:
    end_span(span, SpanEndOptions(
        status="ok",
        output=SpanIO(text="pipeline result"),
        metrics=SpanMetrics(
            model="gpt-4o",
            provider="openai",
            input_tokens=150,
            output_tokens=50,
            total_tokens=200,
        ),
    ))
```

## Shutdown

For scripts or short-lived applications, flush remaining buffered spans before exit:

```python theme={null}
import asyncio
from mutagent.tracing import shutdown_tracing

# shutdown_tracing is a coroutine — must be awaited
asyncio.run(shutdown_tracing())
# or, inside an async function:
# await shutdown_tracing()
```

<Note>
  The SDK registers an `atexit` handler that flushes remaining spans automatically. Calling `shutdown_tracing()` explicitly is recommended for serverless functions or any process that exits quickly after the last traced call.
</Note>

## `init_tracing` Options

| Parameter           | Type          | Default                   | Description                           |
| ------------------- | ------------- | ------------------------- | ------------------------------------- |
| `api_key`           | `str`         | Required                  | MutagenT API key (`mt_` prefix)       |
| `endpoint`          | `str`         | `https://api.mutagent.io` | API endpoint URL                      |
| `environment`       | `str \| None` | `None`                    | Environment name (e.g., `production`) |
| `batch_size`        | `int`         | `10`                      | Spans buffered before flush           |
| `batch_interval_ms` | `int`         | `5000`                    | Flush interval in milliseconds        |
| `debug`             | `bool`        | `False`                   | Log span events to stdout             |

## Framework Integrations

For automatic tracing without any code changes to your LLM calls, use the Python integration packages:

<CardGroup cols={2}>
  <Card title="Anthropic" icon="robot" href="/integrations/python/anthropic">
    `wrap_anthropic(client)` — zero-change tracing for Claude
  </Card>

  <Card title="OpenAI" icon="bolt" href="/integrations/python/openai">
    `MutagentOpenAI` — drop-in OpenAI client replacement
  </Card>

  <Card title="LangChain" icon="link" href="/integrations/python/langchain">
    `MutagentCallbackHandler` — traces chains, tools, and retrievers
  </Card>

  <Card title="LangGraph" icon="diagram-project" href="/integrations/python/langgraph">
    `MutagentCallbackHandler` — automatic graph node tracing
  </Card>
</CardGroup>

## TypeScript Equivalent

The TypeScript tracing module (`@mutagent/sdk/tracing`) provides the same concepts: `initTracing`, `shutdownTracing`, `@trace()` decorator, and `startSpan`/`endSpan`. See the [TypeScript tracing guide](/sdk/typescript/tracing).
