Skip to main content

OpenAI Integration (Python)

Alpha (v0.1.0) — This package is implemented and tested but not yet published to PyPI. Install from source or wait for the public release. See the Python overview for setup instructions.
The mutagent-openai package provides a drop-in wrapper around the official OpenAI Python client that automatically traces all chat completion calls.

Installation

Once published to PyPI:
pip install mutagent-openai
This installs mutagent-openai along with its dependencies: mutagent-tracing (core SDK) and openai (>= 1.0.0).

Quick Start

1

Initialize tracing

from mutagent_tracing import init_tracing

init_tracing(api_key="your-mutagent-api-key")
2

Use MutagentOpenAI instead of OpenAI

from mutagent_openai import MutagentOpenAI

client = MutagentOpenAI(api_key="your-openai-key")

response = client.chat.completions.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Hello!"}],
)

print(response.choices[0].message.content)
Every call to client.chat.completions.create() is automatically traced and sent to MutagenT. No additional code changes required.

Full Example

import os
from mutagent_tracing import init_tracing, shutdown_tracing
from mutagent_openai import MutagentOpenAI

# Initialize MutagenT tracing
init_tracing(
    api_key=os.environ["MUTAGENT_API_KEY"],
    environment="production",
)

# Create the traced OpenAI client
client = MutagentOpenAI(api_key=os.environ["OPENAI_API_KEY"])

# Use exactly like the standard OpenAI client
response = client.chat.completions.create(
    model="gpt-4",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What is the capital of France?"},
    ],
    temperature=0.7,
)

print(response.choices[0].message.content)

# Flush remaining spans on exit
shutdown_tracing()

Streaming

Streaming responses are fully supported. The wrapper accumulates streamed content and records the complete response in the span when the stream finishes.
stream = client.chat.completions.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Write a haiku about Python."}],
    stream=True,
)

for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
Streaming spans capture the accumulated output text after the stream completes. Token usage metrics are recorded when available from the model response.

What Gets Traced

Each call to chat.completions.create() generates a span with:

Input Messages

All messages sent to the model (system, user, assistant)

Output Messages

The model’s response content

Token Usage

Input tokens, output tokens, and total tokens

Model Info

Model name and provider (openai)

Latency

Request duration in milliseconds

Errors

Error messages with stack traces on failure

Span Details

FieldDescriptionExample
kindSpan typellm.chat
nameModel namegpt-4
input.messagesInput chat messagesSystem + user messages
output.messagesResponse messagesAssistant response
metrics.modelModel identifiergpt-4-0613
metrics.providerProvider nameopenai
metrics.input_tokensPrompt tokens150
metrics.output_tokensCompletion tokens50
metrics.total_tokensTotal tokens200

Constructor Options

MutagentOpenAI accepts the same parameters as the official openai.OpenAI client:
ParameterTypeDescription
api_keystr | NoneOpenAI API key (falls back to OPENAI_API_KEY env var)
organizationstr | NoneOpenAI organization ID
base_urlstr | NoneCustom API base URL
timeoutfloat | NoneRequest timeout in seconds
max_retriesint | NoneMaximum retry count for failed requests

Error Handling

When an API call fails, the span is automatically recorded with an ERROR status and the error message is captured:
try:
    response = client.chat.completions.create(
        model="gpt-4",
        messages=[{"role": "user", "content": "Hello!"}],
    )
except Exception as e:
    # Span is already recorded with status=ERROR
    print(f"Request failed: {e}")

Nested Spans

MutagentOpenAI works with the core tracing SDK’s context propagation. If you create a parent span, OpenAI calls will automatically nest under it:
from mutagent_tracing import start_span, end_span, SpanOptions, SpanEndOptions, SpanKind, SpanStatus

# Create a parent span
parent = start_span(SpanOptions(kind=SpanKind.CHAIN, name="my-pipeline"))

# This call is automatically nested under the parent span
response = client.chat.completions.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Hello!"}],
)

# End the parent span
if parent:
    end_span(parent, SpanEndOptions(status=SpanStatus.OK))

TypeScript Equivalent

For the TypeScript/Node.js OpenAI integration, see the TypeScript Integrations.