Skip to main content

TLS LLM Observer Python SDK

OpenTelemetry-first tracing for manual instrumentation, decorators, and OpenAI clients. The first release exports traces only through OTLP/HTTP protobuf.

Install

Install the core tracing SDK and OpenTelemetry dependencies:

pip install tls-llm-observer

Install the OpenAI integration together with openai, packaging, and wrapt:

pip install "tls-llm-observer[openai]"

The default endpoint is http://localhost:4318/v1/traces. Configure it with TLS_TRACE_OTEL_ENDPOINT or the standard OTEL_EXPORTER_OTLP_TRACES_ENDPOINT. Applications configure tracing through TraceConfig; externally supplied providers or exporters are not accepted.

Manual instrumentation

from tls_llm_observer import TraceClient, trace

client = TraceClient()

with client.start_as_current_span("answer-question") as span:
    span.update(input={"question": "Why is the sky blue?"})
    span.update(output={"answer": "Rayleigh scattering"})

@trace(client=client)
def normalize(value: str) -> str:
    return value.strip().lower()

client.flush()
client.shutdown()

span.update(input=...) and span.update(output=...) write gen_ai.input.messages and gen_ai.output.messages. The supplied value is stored directly using the SDK's normal OpenTelemetry attribute conversion; values that do not match the GenAI message schemas are not wrapped or reshaped.

start_span() does not replace the current context. Use start_as_current_span() when new operations should automatically become children. Span names, kinds, attributes, and parenting remain user-controlled.

from opentelemetry.trace import SpanKind
from tls_llm_observer import TraceClient, propagate_attributes

client = TraceClient()
with propagate_attributes(session_id="session-1", conversation_id="conversation-1"):
    with client.start_as_current_span("request", kind=SpanKind.SERVER):
        child = client.start_span("background-work")
        child.update(output={"ok": True}).end()

The context manager also supports async with.

Use the tool-specific helpers for actual tool execution. They create an execute_tool {name} INTERNAL Span and set the required GenAI semantic attributes at Span creation time:

with client.start_as_current_tool_span(
    "get_weather",
    tool_call_id="call_123",
    arguments={"city": "Beijing"},
) as span:
    result = {"temperature": 28}
    span.set_tool_result(result)

@trace(span_type="tool") applies the same execute-tool defaults and records captured function arguments/results on gen_ai.tool.call.arguments and gen_ai.tool.call.result.

Decorator and streams

@trace supports sync/async functions, generators, async generators, and Starlette-style responses with a body_iterator. Streaming spans end on exhaustion or explicit close.

from tls_llm_observer import trace

@trace(name="token-stream")
def tokens():
    yield "hello"
    yield " world"

OpenAI

OpenAI is an optional dependency:

from tls_llm_observer import TraceClient
from tls_llm_observer.openai import OpenAI

client = TraceClient()
openai_client = OpenAI(trace_client=client)
response = openai_client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Hello"}],
)

The integration supports chat completions, completions, responses, embeddings, structured parse, synchronous and asynchronous calls, and streams. OpenAI, AsyncOpenAI, AzureOpenAI, and AsyncAzureOpenAI use the supplied TraceClient; clients created from the exported official openai module use the process default TraceClient.

Native openai.Stream and openai.AsyncStream objects keep their original type and identity. Streaming spans end on exhaustion, explicit close, context manager exit, cancellation, or iteration error.

Tracing-only keyword arguments are removed before the provider call:

response = openai_client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Hello"}],
    trace_name="welcome-message",
    trace_attributes={"tenant.id": "example"},
    capture_content=False,
)

Successful non-streaming raw responses retain their original response type. Raw streaming response APIs are not traced. Set TLS_TRACE_OPENAI_SKIP_RAW_RESPONSES=true to skip all raw-response calls. uninstrument_openai(client) disables tracing for one client; uninstrument_openai() disables the OpenAI integration globally.

OpenAI Assistants are intentionally not instrumented.

Environment variables

Variable Purpose
TLS_TRACE_ENABLED Enable or disable tracing
TLS_TRACE_SAMPLE_RATE Parent-based trace ratio, from 0.0 to 1.0
TLS_TRACE_CAPTURE_CONTENT Capture decorator/OpenAI input and output
TLS_TRACE_OPENAI_SKIP_RAW_RESPONSES Do not trace OpenAI raw-response APIs
TLS_TRACE_OTEL_ENDPOINT OTLP HTTP traces endpoint
TLS_TRACE_OTEL_HEADERS Comma-separated key=value headers
TLS_TRACE_OTEL_TRACE_TOPIC_ID / TLS_TRACE_TOPIC_ID TLS Trace Topic ID
TLS_TRACE_OTEL_REGION / TLS_REGION TLS region
TLS_TRACE_OTEL_AK / TLS_AK TLS access key
TLS_TRACE_OTEL_SK / TLS_SK TLS secret key
TLS_TRACE_OTEL_SECURITY_TOKEN / TLS_SECURITY_TOKEN Optional TLS STS token
TLS_TRACE_OTEL_API_KEY / TLS_API_KEY TLS API Key alternative to AK/SK
TLS_TRACE_OTEL_COMPRESSION none, gzip, or deflate
TLS_TRACE_MAX_QUEUE_SIZE BatchSpanProcessor queue capacity
TLS_TRACE_MAX_EXPORT_BATCH_SIZE Maximum spans per OTLP batch
TLS_TRACE_SCHEDULE_DELAY_MS Batch scheduling delay

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tls_llm_observer-0.1.1-py3-none-any.whl (38.2 kB view details)

Uploaded Python 3

File details

Details for the file tls_llm_observer-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for tls_llm_observer-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b1eb0a425a930a0e70fd20d28b772f1f3b9cb253d210a241859fc22403b56261
MD5 af6a5235a2c1e3ce985d27948d5a6bf1
BLAKE2b-256 d335a0fa599dcd1a07149a05eb1513b95e9f025617f96bc0b0b792aecceb8331

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.1 This release

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page