Python SDK
This page lists the public functions, decorators, classes, and settings of the AIO Python SDK, with their parameters, defaults, and the messages they produce.
Package
Item | Value |
Package name |
|
Import name |
|
Version |
|
Python |
|
Optional extra |
|
Console script |
|
For installation and a first trace, see Instrument your code.
init
init(service=None, tenant_id=None, project_id=None, endpoint=None, *,
aio_collector_endpoint=None, project_name=None, access_key=None,
secret_key=None, environment=None, instrument=True,
redaction=None) -> bool
Starts telemetry. Call it once, before you construct any HTTP or model client. You must give a nonblank tenant id and exactly one of project_id or project_name.
import acceldata_aio_tracer
enabled = acceldata_aio_tracer.init(
service="support-bot",
tenant_id="acme",
project_name="Support bot",
endpoint="https://aio.example.com",
access_key="EXAMPLE_ACCESS_KEY",
secret_key="EXAMPLE_SECRET_KEY",
environment="staging",
)
print("AIO telemetry enabled:", enabled)
Replace the tenant, project, endpoint, and keys with your own values. To get a key, see Create an API key.
Parameters
Parameter | Meaning | Environment fallback, in order | Default |
| Application name, set as |
|
|
| Tenant |
| None. Required. |
| Project id |
| None |
| Project, found by its exact name | None. Pass it as an argument only. | None |
| AIO server URL |
| None |
| OTLP/HTTP collector base URL |
| None |
| Gateway access key |
| None |
| Gateway secret key |
| None |
| Deployment environment, set as |
|
|
| Wrap supported libraries so they create spans automatically. Pass | None |
|
| A redaction policy built with | The |
|
- Arguments win over environment variables.
- Values in
OTEL_RESOURCE_ATTRIBUTESare URL-unquoted. - The access key and secret key are sent with every export only when both are set.
service,tenant_id,project_id, andendpointwon't be renamed. The keyword-only parameters may change in later versions.- Integrations for libraries that aren't installed are skipped.
- Content capture, which records prompt, response, and message content on spans, is on.
Important
Since version 1.0.0.dev2, endpoint means the AIO server. Before that, it meant the OTLP collector. If you upgrade from an earlier version, move your collector URL to aio_collector_endpoint.
Return value
init returns True when telemetry is enabled and False when it isn't. It never raises, except RedactionUnavailable. A second call returns True and does nothing.
Project by name
When you pass project_name, the SDK asks the AIO server at endpoint for its projects and picks the one whose name matches exactly.
- If no project matches, the SDK creates one with the description "Auto created by SDK", the "Acceldata hosted" storage mode, and 60 retention days. For retention, see Data retention.
- If another process creates the same project at the same moment, the SDK lists the projects once more.
- The lookup times out after 3.05 seconds to connect and 10.0 seconds to read.
A project_id that you pass is used as is, without any check against the server.
Messages
init logs these messages when it can't start telemetry. In each case it returns False.
Situation | Message |
Tenant id is blank | "aio: nonblank tenant_id is required; telemetry is disabled" |
Neither or both project selectors are given | "aio: exactly one nonblank project_id or project_name is required; telemetry is disabled" |
The project can't be resolved | "aio: project resolution failed (failed to list projects: HTTP 401); continuing without telemetry" |
Setup fails | "aio: telemetry setup failed; continuing without it" |
On success, init logs an info message that names the service, tenant, project, contract revision, and instrumentation setting.
When project resolution fails, the reason in parentheses is one of the following:
- "exactly one nonblank project_id or project_name is required"
- "endpoint is required when project_name is used"
- "failed to list projects: Read timed out."
- "failed to list projects: HTTP 503"
- "malformed list projects response"
- "duplicate exact project name"
- "failed to create project: Read timed out."
- "failed to create project: HTTP 403"
- "malformed create project response"
- "project 'Support bot' is still absent after create conflict"
- "project must contain a nonblank id"
These reasons come from ProjectResolutionError, a subclass of RuntimeError.
If your application already set up OpenTelemetry
- An existing OpenTelemetry SDK
TracerProvideris reused as is. If its resource doesn't carry the AIO tenant and project, the SDK warns you, and the telemetry lands under the default tenant. To avoid this, addaio.tenant_idandaio.project_idto that provider's resource, or callinitbefore you configure OpenTelemetry. - An existing
LoggerProvidermust have an empty synchronous processor pipeline. Otherwise the error is "aio: reused LoggerProvider must have an empty synchronous processor pipeline so attribution runs before export". A logger provider that the SDK can't attach to gives "aio: existing logger provider is not an attachable SDK LoggerProvider". - If redaction is configured and a
TracerProvideralready exists,initraisesRedactionUnavailable.
For sending data from your own OpenTelemetry pipeline, see OpenTelemetry.
root_span
root_span(conversation_id: str, *, tenant_id=None, project_id=None, user_id=None,
input_preview: str = "", name: str = "handle_message")
A context manager that opens the root span for one unit of work. Every span and log record created inside it gets the conversation id, user id, input preview, and identity.
import acceldata_aio_tracer
acceldata_aio_tracer.init(tenant_id="acme", project_id="0190f3a2-7c1e-7b8a-9d2f-1a2b3c4d5e6f")
question = "Where is my order?"
with acceldata_aio_tracer.root_span(
"conv-123",
user_id="user-42",
input_preview=question,
) as span:
print("Conversation:", acceldata_aio_tracer.current_conversation_id())
Parameter | Meaning | Default |
| The session key, set as | Required |
| Tenant for this operation | None |
| Project for this operation | None |
| The end user, set as | None |
| The user input, set as |
|
| Span name. Use a fixed, low-cardinality label. |
|
- It yields the span, or
Noneif it couldn't start one. - Call it once per unit of work.
- Its values overwrite matching attributes already on the spans inside it.
- Nested
root_spanblocks restore the outer values when they exit. - It does nothing when
inithasn't run. - It swallows its own failures and re-raises your application's exceptions.
current_conversation_id() -> str | None returns the conversation id of the open operation.
For how sessions group in the UI, see Track users and sessions.
Tracing helpers
@trace
A decorator that creates a CLIENT span named after the function, under the scope acceldata_aio_tracer. It sets gen_ai.output.messages, function.args, function.kwargs, service.name, and deployment.environment. When the function raises, the span gets ERROR status and records the exception, and the exception is re-raised.
Applying @trace to something that isn't callable raises TypeError "@trace can only be applied to callable objects, got <class 'str'>".
start_trace
start_trace(name) is a context manager that yields a TracedSpan. A TracedSpan has these methods:
set_result(result)set_metadata(dict)
Context helpers
Function | What it does |
| Sets |
| Sets |
| Works as both a context manager and a decorator |
| Takes a function and attributes |
Agent metrics
log_agent_invocation(source, target, system=None) and log_agent_tool_error(agent_name, tool_name, system=None, model=None) record metrics. They swallow any errors.
Redaction
Redaction withholds content inside your application before it's sent. Every switch is off by default. For what each option does in practice, see the redaction overview.
redaction_policy
redaction_policy(*, hide_system_instructions=False, hide_tool_definitions=False,
redact_tool_arguments=(), redact_tool_results=(),
redact_attributes=(), suppress_spans=(), patterns=(), allow=None)
Builds a RedactionPolicy to pass to init as redaction=. It's also available as redaction.policy_from.
import acceldata_aio_tracer
acceldata_aio_tracer.init(
tenant_id="acme",
project_id="0190f3a2-7c1e-7b8a-9d2f-1a2b3c4d5e6f",
redaction=acceldata_aio_tracer.redaction_policy(
hide_system_instructions=True,
redact_tool_arguments=["lookup_customer"],
patterns=[r"\b\d{16}\b"],
),
)
Parameter | Effect | Details |
| Replaces system instructions with a digest | |
| Replaces tool definitions with a digest | |
| Digests the arguments of the named tools | |
| Digests the results of the named tools | |
| Digests the named attributes on any span | |
| Leaves the named spans, and everything under them, out of the trace | |
| Replaces every regular expression match in message text and tool text with | |
| A function |
- A digest is a
sha256:<hex>value. - Tool lists accept a list or comma-separated values.
- Patterns are compiled when the policy is built, so an invalid pattern fails at startup. Patterns can't be set from the environment.
RedactionPolicyis a frozen dataclass. Its.activeproperty is true when any switch is set.
The redaction module also defines these constants:
Constant | Value |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Redaction environment variables
These variables apply only when init gets redaction=None.
Variable | Effect |
| Flag. Only |
| Flag. Only |
| Comma-separated tool names |
| Comma-separated tool names |
@redact_arguments
redact_arguments(tool=None, *, name=None)
A decorator that digests the arguments of one tool. Apply it to a tool class or a function, or call it with only name=.
- The tool name comes from, in order: the pydantic
model_fields["name"].default, then.name, then__name__. - If no name is found, the SDK warns that it couldn't find a tool name and that nothing will be redacted for it. Pass
name=to fix this. - It covers arguments only, never results.
- Marked tools are added to
redact_tool_arguments. - Import the tool before its spans are exported.
RedactionUnavailable
Raised by init when redaction is configured but your application already set up an OpenTelemetry TracerProvider. The message is "aio: redaction is configured, but this application already set up an OpenTelemetry TracerProvider. Redaction is applied by the span exporter, which that provider does not use, so span content would be exported unredacted. Call aio.init() before configuring OpenTelemetry."
Scores and threats
log_score
log_score(name, value, *, span=None, trace_id=None, span_id=None, comment=None,
idempotency_key=None, metadata=None) -> bool
Attaches a gen_ai.evaluation.result event to a span, and also emits a log event unless events are turned off.
Parameter | Recorded as |
|
|
| A number becomes a float in |
|
|
|
|
| Merged with the custom attributes. Only str, int, float, and bool values, or lists of them, are kept. |
The score is attached to the first of these that's available:
- The
spanyou pass. - The current recording span.
- The span given by
trace_id(32 hex characters) andspan_id(16 hex characters). - The current span.
Errors: "name is required", and TypeError "value must be numeric, boolean, or string". ValueError and TypeError are re-raised to you.
record_threat_detected
acceldata_aio_tracer.threat.record_threat_detected(rule_id, severity, threat_class, *,
span=None, **attributes) -> bool
Import it from acceldata_aio_tracer.threat. It isn't available at the top level.
- It adds a
gen_ai.agent.threat_detectedevent withgen_ai.agent.threat.rule_id,gen_ai.agent.threat.severity, andgen_ai.agent.threat.threat_class. severitymust below,medium,high, orcritical.- It returns
Falsewhen no span is recording.
Errors: "rule_id is required", "severity must be one of: critical, high, medium, low", and "threat_class is required".
Guards
A guard is an in-process check on a prompt or a response. Guards run only when you call them through a Pipeline. For an introduction, see the Guard overview.
Pipeline
Pipeline(guards=None, fail_open=True).evaluate(text, phase="preflight")
phaseispreflight, which checks the input before the model call, orpostflight, which checks the output after it.- Actions, from least to most severe, are
allow,warn,redact, anddeny. The most severe action wins. - A
denystops the remaining guards. It doesn't raise anything by itself: readPipelineResult.actionand decide what to do. - Redactions chain, so each guard sees the text the previous guard produced.
- With
fail_open=True, a guard that raises is treated asallow, and the pipeline logs a warning. - Each run emits a
guard_requestsmetric and aguard.evaluationspan event.
Results and errors
Name | Contents |
|
|
|
|
| Types for the action and phase values |
| Base guard error |
| Error that carries a result |
| Reserved |
| Invalid guard configuration |
Guard base class
Guard(action="deny", max_scan_length=102_400) is the base class for all guards. An invalid action raises GuardConfigError "Invalid action 'block'. Must be one of: allow, deny, redact, warn".
Built-in guards
Guard | Arguments and defaults | Phases | Behavior |
|
| preflight, postflight | 24 built-in patterns. Redaction writes |
|
| preflight | The explanation gives the score and classification. |
|
| preflight, postflight | Categories are any of |
|
| preflight | Topics are matched in lowercase. Explanations look like "Topic 'politics' is not in the allowed list" or "Topic 'politics' is in the denied list". |
|
| preflight, postflight | Profanity scores 0.7, and toxicity scores 0.95. Redaction replaces profanity only, with |
|
| postflight | Invalid JSON gives classification |
|
| As given | A pattern hit gives classification "pattern_match" and an explanation such as "Custom pattern matched: 'ORDER-1234'". Otherwise the callable's result is returned. |
Configuration errors:
TopicRestriction: "TopicRestriction requires a callable 'classifier'", "Provide either 'allowed' or 'denied', not both", and "Provide either 'allowed' or 'denied' topic list".Custom: "Custom guard needs at least 'pattern' or 'callable'".
Offline evaluations
Offline evaluations send a prompt and response pair to the AIO server, which scores it against eval types. For a walkthrough, see Run an eval.
eval
eval(prompt, response, contexts=None, eval_types=None, attributes=None,
threshold_score=None, store_results=None, run_id=None, metadata=None,
acceldata_aio_tracer_api_key=None, acceldata_aio_tracer_url=None,
print_results=True) -> OfflineEvalResult
- The API key comes from
acceldata_aio_tracer_api_key, thenAioConfig, thenAIO_API_KEY. The URL comes fromacceldata_aio_tracer_url, thenAioConfig, thenAIO_URL. A missing key or URL raisesValueError. - The request times out after 120 seconds. It's retried once on HTTP 429, on HTTP 5xx, and on a connection error.
- Attributes are merged in this order, with later entries winning:
OTEL_RESOURCE_ATTRIBUTESOTEL_SERVICE_NAMEAIO_ENVIRONMENTorOTEL_DEPLOYMENT_ENVIRONMENTAioConfig- The
attributesyou pass
- With
print_results=True, a summary is printed to stderr with the title "Acceldata AIO Offline Evaluation — PASSED" or "Acceldata AIO Offline Evaluation — FAILED".
Errors:
- "Authentication failed. Check your Acceldata AIO API key."
- "Server returned non-JSON response (HTTP 502)"
- "Request timed out after 120s. The evaluation may still be running on the server."
- "Cannot connect to Acceldata AIO server at https://aio.example.com: Connection refused"
- "Evaluation failed after retries: HTTP 503"
eval_batch
eval_batch(dataset, eval_types=None, attributes=None, threshold_score=None,
store_results=None, run_id=None, max_concurrent=5,
print_results=True) -> BatchEvalResult
datasetis a non-empty list of dicts. Each dict has the string keyspromptandresponse, and can overridecontexts,eval_types,attributes,threshold_score, andmetadata.- Items run in parallel, with up to
max_concurrentat a time. - The default
run_idisbatch_followed by 12 hex characters. It groups the evaluations of one batch. - The summary title is "Acceldata AIO Batch Evaluation — ALL PASSED" or, for example, "Acceldata AIO Batch Evaluation — 3 FAILED".
Errors:
- "dataset must be a non-empty list of prompt/response dicts"
TypeError"dataset[2] must be a dict, got <class 'str'>"- "dataset[2] must have a 'prompt' string key"
- "dataset[2] must have a 'response' string key"
get_eval_types
get_eval_types(acceldata_aio_tracer_api_key=None, acceldata_aio_tracer_url=None) returns a list of EvalType. It raises ValueError when authentication fails, ConnectionError, TimeoutError, or RuntimeError with a message that starts with "Failed to fetch eval types: ".
Result models
Model | Fields and members |
|
|
|
|
|
|
|
|
|
|
Prompts, secrets, and rule evaluation
These functions authenticate with a bearer token and time out after 120 seconds. The URL falls back to AIO_URL and the key to AIO_API_KEY. If either is missing, they raise RuntimeError "Missing Acceldata AIO URL: Provide as arg or set AIO_URL env var." or "Missing API key: Provide as arg or set AIO_API_KEY env var."
Function | What it does | On failure |
| Fetches a compiled prompt and returns the JSON | Logs an error and returns |
| Fetches secrets. With | Logs an error and returns |
| Evaluates a rule. | Logs an error and returns |
Configuration
AioConfig
AioConfig is a single shared configuration object. Its defaults include:
Setting | Default |
|
|
|
|
|
|
|
|
When max_content_length is a positive integer, captured content is cut to that length and "..." is appended. A value of 0 or less, or a value that isn't an integer, means no truncation.
Instrumentor names
Instrumentor names, such as the ones you pass to --disabled_instrumentors in the CLI, are matched without regard to case. Aliases are resolved, for example "aiohttp" to "aiohttp-client" and "http" to "httpx". An invalid name logs "Invalid instrumentor name 'opneai'. Did you mean: openai?" or "Invalid instrumentor name detected and ignored: 'opneai'". For the libraries AIO works with, see Supported providers and frameworks.
Environment variables
The SDK reads these variables. Arguments you pass in code win over them.
Variable | Used for |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Offline evaluation attributes |
| Redaction, when |
| Offline evaluations, prompts, secrets, and rule evaluation |
Constants
Name | Value |
|
|
|
|
| The installed package version, or |
| Constants for attribute names |
Every span's resource carries service.name, deployment.environment, telemetry.distro.name set to acceldata-aio-tracer, telemetry.distro.version, aio.tenant_id, and aio.project_id.

Have a suggestion?