Skip to main content
Use the Hue Python SDK to trace your application with OpenTelemetry spans and correlated logs. Provider requests stay in your application. For option defaults and method signatures, see the Python API reference. Check the compatibility matrix, including the accepted OpenTelemetry range, before adding Hue to an existing application.

Install

Use Python 3.10 or later. Install the Python SDK, then configure your key below. Tests cover Python 3.10 and 3.14 with OpenTelemetry 1.45.1, the certified combination, and OpenTelemetry 1.40.0, the declared floor; the SDK accepts >=1.40,<2.

Configure your project

Set HUE_API_KEY in your server environment to a project key: a Read and write key from Settings → API keys. Use separate keys for development and production; Project keys covers each preset and rotation. The SDK connects to Hue Cloud by default; connection settings covers other origins. Pass the key as the api_key= keyword. The first positional parameter is base_url, so a bare key in that position raises TypeError naming api_key=. The constructor reads no environment variables.

Send your first trace

Save this as trace.py. It traces a deterministic addition tool without making a model call.
Run it with your environment already configured:
Open Traces in the project that owns the key. The root span and its execute_tool add child share the printed trace ID. Both show the input {"a": 2, "b": 2} and the output 4 because this example captures content.

Content capture

capture_content defaults to True, so helper spans record prompts and messages, responses and tool inputs and outputs. Set it to False for metadata-only capture; content is then omitted before it enters an OpenTelemetry queue, and recognized content attributes from other instrumentors on the same provider are stripped at export. Data privacy explains what each mode sends and how redactor(field, value) scrubs helper content; the content policy lists the exact fields. The helpers always exclude exception messages and stacks, retaining error type and status. A context manager records an escaping error and rethrows it. Images, audio and documents in recorded values upload automatically; Media covers Attachment, record_file and reading files back.

Model metadata and correlation

Use hue.model(model, provider=...) for a model operation; Traces and spans shows where it sits in a request. Report known token counts with span.set_usage(input_tokens=..., output_tokens=...); leave unavailable counts as None. Hue does not estimate missing usage. Use hue.context(session_id=..., user_id=...) around related helpers. These are observed application identifiers, not Hue account identities. Hue.inject(headers) and Hue.extract(headers) support W3C trace-context propagation across services. span.log_inference(input=..., output=...) emits a log correlated with that span. Use logs or span attributes for a given content event instead of storing identical copies in both. With capture enabled, an explicit None field keeps its key with an empty value, distinct from an absent field. With capture disabled, log_inference emits no record.

Verify

Finish a real application request and retain its trace ID and known span IDs. End its spans, flush the provider that owns them, then flush Hue. When borrowing a provider, flush that provider first. Verification does not run the app, invoke a model, or flush telemetry.
Only require fields the request should emit and your capture policy permits. Supported names are input, output, model, usage, and session. With content capture, add input and output to confirm the request’s content arrived. Omit them for metadata-only capture, and omit usage when the instrumentation does not report it. The receipt reports stored field presence, span counts, and missing expected spans. It contains no captured values. A successful result confirms the conditions you requested; inspect the trace in Hue to check the content and redaction. See the verification API for limits and failures.

Production setup

Keep tracing best effort in a serving application: an outage should reduce observability, not prevent an answer. Hue follows OpenTelemetry’s runtime error containment and bounded-resource principles. Use a Read and write project service key for application requests, with separate keys for development and production. The Python SDK suppresses its own export traffic from OpenTelemetry instrumentation. If its suppression key is unavailable, Hue warns once and exports without it while its queues still ignore export work. Verify your dependency and instrumentor combination in CI.

Verify setup outside request handling

Run the strict quickstart, connection check and trace receipt verification during setup, not in readiness or customer requests. Create one client per serving process with the safe constructor and background export. Initialize after fork, once per serving process. Use safe lifecycle methods at the lifecycle boundary; never rerun an agent after a telemetry error because tools may have caused side effects.
existing_agent is your function. Register shutdown in the process hook. When the process uploads files, give shutdown_safe() a budget that covers those uploads; see Flush and shutdown. For serverless, flush in the supported after-response lifecycle; do not shut down shared providers per request.

Async servers

In FastAPI, Starlette and other asyncio servers, Hue’s context is task-local, so a span opened in a request handler is the parent of the spans opened in the same task. Write a streaming body as an async generator and keep the request span inside it, so it ends when the stream ends. Close the generator in the streaming task when sending fails or the client disconnects. This ends the span with the output so far and records the interrupted stream as failed.
Starlette runs a synchronous generator body one next() at a time in a fresh thread context, so a span opened inside it loses its parent after the first item; use the async generator above. force_flush_safe and shutdown_safe block, so the example runs them off the event loop with asyncio.to_thread. The response closes its async generator and flushes in the streaming task, including when sending raises or disconnect cancellation interrupts the stream. Its shield lets cleanup finish under AnyIO cancellation. Keep one client for the process; do not shut it down per request. await asyncio.to_thread(fn) and Starlette’s run_in_threadpool(fn) copy the current context into the worker thread, so Hue spans fn opens stay under the request span. A bare executor.submit(fn) or loop.run_in_executor(executor, fn) does not; submit contextvars.copy_context().run, fn instead.

Failure behavior

Hue omits unsafe content or redactor failures, records instrumentation failure and preserves application results and errors. Safe initialization returns a disabled client on setup failure; helpers still execute application work. Python redactors receive detached copies. When uploads are available, snapshots and redactors accept supported helper values up to 1 GB and 1,048,576 visited values and keys; otherwise snapshots are bounded to 4 MiB, depth 64 and 65,536 values and keys. Keep redactors deterministic and side-effect free. Safe lifecycle methods return failure results. A timeout neither proves delivery nor cancels an in-flight request. Hue, checks, verification and strict lifecycle methods remain diagnostic and may fail. Queues limit records and bytes, including in-flight records. max_queue_bytes defaults to 8 MiB per signal. Separately, the SDK can hold up to 128 MiB of over-limit strings in a span’s own attributes and recorded media and explicitly requested file uploads while they await upload; log records, other events, links and resources do not upload. This bounds queued telemetry, not process RSS. Overflow drops telemetry and updates counters without retrying business work. Network retries are bounded. Python keeps one worker per signal and one for live-span placeholders. An OS-blocked call can outlive the wait and retain one encoded request (up to 1 MiB) per worker outside queue counters. Shutdown counts discards; process kill, full queues, disabled clients and exporter failures can lose telemetry. There is no disk spool or delivery guarantee. HTTP 429 Retry-After responses keep records queued for up to 60 seconds; a longer wait is reported as a failed export. Upload fallbacks increment upload_fallbacks and create warnings without failing force_flush(). In-process code cannot prevent termination, OOM, stalls or third-party hooks. Keep redactors fast and offline. Safe construction cannot catch import or dependency failures, so verify startup in CI or guard the integration.

Kill switch and monitoring

The snippets read HUE_TRACING_ENABLED; set it to false and restart to bypass Hue without changing application code. It is not a remote flag. Strict constructors also accept enabled=False; a disabled client needs neither a key nor capture settings. Inspect hue.export_status for failures, drops, pending bytes, uploaded_values and upload_fallbacks. Counters are cumulative; pending bytes and records are current gauges. Emit only sanitized counts and status, never credentials, content or raw provider exceptions, and do not send health signals only through Hue. Before rollout, test your real entry point against a loopback receiver that returns 503, rejects its key, delays its response and exceeds queue capacity. Verify that each tool runs once, results and errors match an uninstrumented request, and shutdown meets your deadline. Start with a small canary.

Flush and shutdown

force_flush() sends both signals’ records first, then waits within the same deadline for the uploads accepted so far, and returns a boolean. It returns False for a timeout or any recorded failed export batch, dropped record or instrumentation failure during this client’s lifetime. Check hue.export_status for cumulative trace and log failure counts. HTTP errors, malformed acknowledgements, and OTLP partial rejections are failures; receiver error bodies are not echoed. A flush timeout bounds your wait, not the ongoing network request. Both signals share the remaining deadline, including time spent waiting behind another flush. Drain coordination is released when that budget expires, so a timed-out flush does not impose a fresh wait on later calls. Background exports and shutdown cleanup can continue. Before planned application shutdown, finish traced work and keep the process alive long enough to confirm completion. shutdown() sends records first, then gives pending uploads up to 30 seconds more once its processors stop, and abandons the rest, counted in upload_fallbacks. Repeated shutdown() calls wait for the same cleanup and report current failures and drops. Spans ending or external records emitted after Hue shuts down count as dropped, including records from a borrowed provider; new Hue helpers are no-ops. A context manager calls shutdown on exit, but you still need an explicit checked flush when your command’s exit status must reflect delivery failure. The SDK uses official OTLP HTTP exporters with protobuf encoding and their retry policy. Export requests are gzip-compressed and carry a hue-sdk-python/<version> User-Agent ahead of the exporter’s own token. Partial rejections are not retried wholesale. Queues are in memory, so process termination and overflow can lose records. A successful flush is not proof that every application operation was instrumented.

Existing OpenTelemetry provider

Pass your OpenTelemetry SDK tracer provider as tracer_provider=provider, and an existing SDK LoggerProvider as logger_provider=provider when the application already owns one. Hue adds its processors without setting the global providers. A provider Hue creates for the other signal reuses the borrowed provider’s resource, so spans and correlated logs report one service.name; service_name applies only when Hue creates both providers. An instrumentor that accepts a provider can use hue.tracer_provider explicitly. Use one Hue client per provider lifecycle; OpenTelemetry has no public processor-removal API. Hue shutdown leaves borrowed providers and their other processors usable. Your application remains responsible for those providers and their instrumentations.

Evaluate locally

Import the built-in evaluator bundle as from hue_sdk.evals import builtin_scorers. builtins remains an alias, but shadows the standard-library module in files that import it. builtin_scorers.json_schema needs pip install 'hue-run[evals]'; otherwise the helper raises ImportError and stored schema evaluators report SchemaValidatorUnavailable. The tracing core depends only on OpenTelemetry packages and requests. See Local evaluations and the Python API reference.

Managed runs

Expose a protected route around your existing application function with the managed target adapter. Hue dispatches frozen cases, saves real output files and verifies trace evidence; your application retains its provider, tools and existing telemetry. Local evaluation runners remain available.