Python SDK API
Classes, methods, parameters, return values, configuration, and integrations for the Anectico Python SDK.
On this page
This is the application-developer API for anectico 0.1.x. The SDK supports Python 3.10+, synchronous
and asynchronous frameworks, OpenTelemetry signals, identity, diagnostic events, feature flags, and
LLM wrappers.
Use ingest:write for traces, metrics, logs, and errors. Add analytics:write for identity, groups,
events, and flag exposure events; add flags:read for flag decisions.
Create and run AnecticoClient
import os
import anectico
client = anectico.AnecticoClient(
api_key=os.environ['ANECTICO_API_KEY'],
service_name='orders-api',
)
client.start()
try:
run_application()
finally:
shutdown = client.stop()
if shutdown.success is False:
report_telemetry_delivery_failure(shutdown.errors)
| API | Parameters | Returns | Behavior |
|---|---|---|---|
AnecticoClient(...) |
core options below or config=AnecticoConfig(...) |
AnecticoClient |
Builds an unstarted client. A supplied config takes precedence over every other constructor argument. |
start() |
— | same AnecticoClient |
Validates configuration. Managed mode starts owned transports and the optional standard-library logging bridge; existing mode only enables helpers against application globals. Repeated calls are safe. |
stop() |
— | ShutdownResult |
Managed mode removes the log bridge and concurrently flushes/stops owned providers. Existing mode never touches application providers and returns an unattempted result. Repeated calls are safe. |
is_running |
property | bool |
Whether the client currently accepts telemetry. |
| context manager | with AnecticoClient(...) as client |
client | Starts on entry, captures an exception leaving the block, then stops. |
flush(timeout_ms=None) |
optional milliseconds | bool |
Flushes client-owned managed providers and the pending identity-event queue. True only when nothing was left unaccepted. Returns False in existing mode; the application must flush its providers. |
config |
property | AnecticoConfig |
Active configuration. Contains the API key; do not log or serialize it. |
stats |
property | dict[str,int] |
Counters for spans, metrics, logs, captured errors, and identity_events_dropped. |
flush() combines two halves and never turns an unknown into a success. The identity-event queue is
owned by the SDK end to end, so it reports real acceptance: a permanently rejected identify batch
makes flush() return False and increments stats['identity_events_dropped'], and a rejected
final batch makes stop() report a failed ShutdownResult rather than a silent success. The
telemetry half reports its provider flush outcome — buffered signals drained and exported — which is
not a per-request acceptance, and is passed through rather than reinterpreted.
Keep one client per process. Framework middleware supplies request-scoped identity and spans; do not construct a client per request.
ShutdownResult has attempted, flush_succeeded, shutdown_succeeded,
success, and a tuple of sanitized errors. success is True only when an
attempted shutdown fully delivered and stopped every enabled provider. It is
False for a provider False return, exception, or timeout, and None when
the client was already stopped. Boolean conversion is true only for full
success. A Python context manager cannot return its exit outcome; use explicit
start()/stop() when the process must record delivery evidence.
Constructor and AnecticoConfig
The constructor directly accepts the most common fields. AnecticoConfig exposes the complete set.
| Field | Type | Default/environment | Purpose |
|---|---|---|---|
api_key |
str |
ANECTICO_API_KEY; required |
Project-scoped Anectico API key. |
service_name |
str |
OTEL_SERVICE_NAME; required |
Logical service name. |
service_version |
str |
OTEL_SERVICE_VERSION; 0.0.0 |
Deployed version. |
environment |
str |
ANECTICO_ENVIRONMENT; development |
Deployment environment. |
endpoint |
str |
ANECTICO_ENDPOINT; https://api.anectico.com |
HTTP requires an absolute http(s) URL. gRPC accepts an http(s) authority URL without a path or host:port. |
open_telemetry_mode |
managed | existing |
ANECTICO_OTEL_MODE; managed |
Provider ownership. Existing mode uses application-registered globals and does not configure or own their lifecycle. |
protocol |
http | grpc |
OTEL_EXPORTER_OTLP_PROTOCOL; http |
OTLP transport. |
insecure |
bool |
OTEL_EXPORTER_OTLP_INSECURE; False |
Disable TLS; local development only. |
enable_traces, enable_metrics, enable_logs |
bool |
corresponding ANECTICO_ENABLE_*; True |
Enable each signal pipeline. |
trace_sample_rate |
float |
OTEL_TRACES_SAMPLER_ARG; 0.1 |
Trace sampling in the inclusive range 0–1. |
error_sample_rate |
float |
ANECTICO_ERROR_SAMPLE_RATE; 1 |
Non-fatal captured-error sampling. |
batch_timeout_ms |
int |
OTEL_BSP_SCHEDULE_DELAY; 5000 |
Maximum batching delay. |
batch_size |
int |
OTEL_BSP_MAX_EXPORT_BATCH_SIZE; 512 |
Maximum export batch size. |
max_queue_size |
int |
OTEL_BSP_MAX_QUEUE_SIZE; 2048 |
Queue capacity; must be at least batch_size. |
export_timeout_ms |
int |
OTEL_BSP_EXPORT_TIMEOUT; 30000 |
Per-export deadline; also the total HTTP same-batch retry window. |
shutdown_timeout_ms |
int |
OTEL_BSP_SHUTDOWN_TIMEOUT; 5000 |
One aggregate graceful flush/shutdown deadline across enabled providers. |
metric_export_interval_ms |
int |
OTEL_METRIC_EXPORT_INTERVAL; 60000 |
Metric push interval. |
bridge_stdlib_logging |
bool |
ANECTICO_BRIDGE_STDLIB_LOGGING; True |
Export normal logging records through this client. |
log_level |
str |
ANECTICO_LOG_LEVEL; info |
Minimum bridged log level. |
log_redaction_fields |
tuple[str,...] |
ANECTICO_LOG_REDACTION_FIELDS; empty |
Additional comma-separated structured-log field names to redact. Extends, never replaces, built-in credential and financial-account protection. |
attach_stack_trace |
bool |
ANECTICO_ATTACH_STACK_TRACE; True |
Attach exception frames. |
max_stack_trace_frames |
int |
ANECTICO_MAX_STACK_TRACE_FRAMES; 50 |
Maximum exception frames. |
instrument_http_clients |
bool |
ANECTICO_INSTRUMENT_HTTP_CLIENTS; False |
Globally instrument requests/httpx. Opt in only for trusted traffic. |
propagate_trace_header_urls |
tuple[str,...] |
ANECTICO_PROPAGATE_TRACE_HEADER_URLS; empty |
Absolute trusted prefixes allowed to receive trace/identity headers. |
trust_incoming_identity |
bool |
ANECTICO_TRUST_INCOMING_IDENTITY; False |
Adopt inbound Anectico identity baggage. Enable only behind a sanitizing authenticated gateway. |
resource_attributes |
dict[str,str] |
OTEL_RESOURCE_ATTRIBUTES; empty |
Extra resource attributes. |
headers |
dict[str,str] |
OTEL_EXPORTER_OTLP_HEADERS; empty |
Extra export headers. |
debug |
bool |
ANECTICO_DEBUG; False |
SDK diagnostic logging. |
AnecticoConfig.from_env(**overrides) resolves environment variables and applies explicit overrides.
Unknown override names raise ValueError. Queue sizes and stack-frame limits must be integers;
timeouts must be finite and positive. An explicitly empty service name is invalid even when the
environment contains a name. Authentication headers override custom headers case-insensitively.
validate() raises on missing/invalid configuration. get_endpoint_for_signal(signal),
get_headers(), and get_log_level() support custom integrations.
open_telemetry_mode accepts exactly managed or existing (case-sensitive).
In existing mode the application must register providers before
AnecticoClient.start(). Anectico creates no provider, exporter, export processor,
metric reader, propagator, HTTP instrumentation, or standard-library logging
bridge. Managed resource, sampling, endpoint, batching, exporter, propagation,
and logging settings do not reconfigure application providers; signal enable
flags still gate the corresponding Anectico helpers.
The enabled signal endpoints are resolved before validation, so
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, and
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT can replace the base endpoint for their
signals. Endpoint errors never echo the configured URL, which may contain
sensitive deployment information.
HTTP exporters retain the same serialized batch for connection loss and
retryable 408/5xx responses throughout the configured
export_timeout_ms window. Jittered exponential backoff is bounded by the
remaining deadline, interrupted by shutdown, and exhausted once without a
nested retry loop. Certificate verification, TLS configuration, and
client-certificate failures are classified as permanent, attempted once, and
logged with a sanitized diagnostic. Certificate verification is never disabled
implicitly.
Traces, metrics, logs, and AI operations
| Method/property | Parameters | Returns | Behavior |
|---|---|---|---|
tracer |
property | OTel Tracer |
Underlying tracer for advanced use. |
meter |
property | OTel Meter |
Underlying meter for advanced use. |
start_span(name, **kwargs) |
name; arguments forwarded to Tracer.start_as_current_span |
context manager yielding OTel Span |
Makes the span current for the with block, so nested spans, captured errors, and correlated logs inherit its trace context; yields a non-recording span before startup. For manual lifetime control, use client.tracer.start_span(...). |
record_metric(name, value, labels=None) |
name; float; string labels | None |
Creates a gauge and records one value. |
log_event(level, message, attrs=None) |
debug/info/warn/warning/error/fatal; body; attributes |
None |
Emits a structured OTLP log; no-op when logs are disabled. |
record_llm_call(model, **options) |
required model; options below | None |
Emits one completed gen_ai client span. |
record_tool_call(name, **options) |
required tool name; options below | None |
Emits one completed internal tool span. |
start_agent_run(agent, **options) |
agent; optional IDs | context manager yielding AgentRun |
Makes the agent span current so nested calls become children. Call run.end(status, reason_code); normal exit defaults to completed and exceptions safely record failed/exception. |
record_llm_call accepts response_model, provider, operation, token counts, cost_usd,
finish_reason, is_error, start_time, and end_time. messages and output opt into sensitive
content. record_tool_call accepts tool_type, call_id, conversation_id, agent_name,
is_error, arguments, and result; arguments/results are also opt-in content.
Agent-run status is completed, failed, timed_out, cancelled, or max_steps. Reason codes are
lowercase [a-z][a-z0-9_]{0,63} values, not exception/provider text. The first valid end call wins;
later calls are no-ops. Calling run.span.end() directly bypasses the terminal contract and leaves
Anectico to use its legacy inferred status.
start_agent_run(..., agent_version="checkout-agent@2026.08.24") optionally declares the release
that produced the run. It is recorded as the standard gen_ai.agent.version span attribute. Leave
it unset when the release is unknown; Anectico reports that as undeclared rather than treating it as
an error or silently filtering the run away.
Context assembly events
The run handle exposes record_context_assembly(value), record_context_compaction(value), and
record_context_cache(value). Call them while a recording model span is current and carries
gen_ai.operation.name = chat | text_completion | generate_content | embeddings | fetch_response.
The SDK raises ValueError for the run span, a tool span, an ended span, or no active span. It
validates every field before adding the one event, so a rejected value records nothing.
with client.start_agent_run("support-planner") as run:
with client.tracer.start_as_current_span(
"chat gpt-4o",
kind=SpanKind.CLIENT,
attributes={"gen_ai.operation.name": "chat"},
):
run.record_context_assembly(
ContextAssembly(
budget_tokens=8192,
reserved_output_tokens=1024,
assembled_tokens=6144,
overflow="none",
assembly_sha256=assembly_sha256,
sources=[ContextSource(
kind="memory", id="memory:item-7", sensitivity="confidential",
tokens=512, position=3, visibility="included",
)],
)
)
See Context events for exact bounds. Never send compaction ratio; the server derives it. OpenAI and Anthropic wrappers add cache hit/miss events when cache fields are present. A reported zero is a miss, while an absent field produces no event.
Managed mode bridges standard-library logging by default. Those records
inherit active OTel trace context; prefer ordinary logger.info(...) inside
application code. Existing mode installs no bridge: ordinary logs use the
application's logging setup, while log_event() uses the registered global
Logger Provider and safely no-ops without a real provider. When a framework
logs the same exception after capture_error, the managed bridge links that log
with the canonical error.id: the log remains searchable without creating a
second Issue. Independent error logs still create Issues.
Application values supplied through logging(..., extra={...}) are exported as structured
attributes. Safe top-level strings, booleans, integers, floats, and homogeneous primitive sequences
retain their OpenTelemetry types. Nested mappings or mixed/nested sequences are recursively
sanitized, then stored as bounded canonical JSON because OpenTelemetry attributes do not support
nested objects. The bridge excludes Python's reserved LogRecord fields and private keys.
Before export, field names such as password, authorization/Bearer, token/API key, cookie, secret,
bank/routing/account number, IBAN, card, and PIN are replaced with [REDACTED], including inside
nested mappings and sequences. Credential forms in the message and exception stack text are also
redacted. Add domain-specific names without weakening the built-ins:
client = AnecticoClient(
api_key=os.environ["ANECTICO_API_KEY"],
service_name="payroll",
log_redaction_fields=["payroll_reference"],
)
The equivalent environment value is
ANECTICO_LOG_REDACTION_FIELDS=payroll_reference,employee_private_code.
Errors, messages, users, and breadcrumbs
Breadcrumbs snapshot nested JSON data when added. If optional data cannot be serialized, the breadcrumb is retained without that data so error reporting can still include the trail.
| Method | Parameters | Returns | Behavior |
|---|---|---|---|
capture_error(error, *, user=None, tags=None, extra=None, fingerprint=None, level='error') |
exception and optional context | str |
Captures the exception and returns its ID; '' before startup or when sampled out. fatal bypasses sampling. |
capture_message(message, level='error', *, user=None, tags=None, extra=None) |
message, severity, optional context | str |
Captures a message and returns its ID. |
add_breadcrumb(category, message, *, level='info', data=None) |
breadcrumb fields | None |
Adds to the 100-entry trail attached atomically to the next error. |
set_user(user) |
User |
None |
Sets global error user context. |
get_user() |
— | User | None |
Returns request-local user first, then global user. |
clear_user() |
— | None |
Clears global error user context. |
Capture tags keys are encoded as indexed anectico.tag.* telemetry attributes automatically.
Capture severity is also indexed as error.level for Issue filtering and context.
User fields are id, email, username, ip_address, segment, and data. Use
set_context_user(user)/get_context_user() for an async request-local error user. The cross-signal
person identity remains distinct_id, managed separately below.
Identity and groups
| API | Parameters | Returns | Behavior |
|---|---|---|---|
client.identify(distinct_id, properties=None) |
stable ID; person properties | None |
Switches shared identity and performs best-effort canonical-person sync. Raises ValueError for an empty ID. |
client.sync_person(distinct_id, properties=None) |
stable ID; person properties | None |
Performs best-effort canonical-person sync without an anonymous alias or any process-wide identity mutation. Use at trusted server authentication/profile boundaries. |
client.group(group_type, group_key, properties=None) |
type/key; group properties | None |
Associates the person with an account and sends a membership assertion. Empty type/key is ignored. |
client.reset() |
— | None |
Logout: creates a new anonymous identity and clears groups, global error-user context, and uncaptured breadcrumbs. Already-captured telemetry remains queued with its original attribution. |
shared_identity() |
— | IdentityManager |
Returns the process-wide identity holder shared by signals and analytics. |
set_context_distinct_id(id) |
stable ID | DistinctIDScope |
Sets async-safe request identity; reset with the returned token. |
reset_context_distinct_id(token) |
scope token | None |
Restores the prior request identity. |
resolve_distinct_id_for(context=None, identity=None) |
optional OTel context/manager | str |
Resolves request scope, baggage, then shared identity. |
adopt_distinct_id_from_baggage(context=None) |
OTel context | DistinctIDScope | None |
Promotes trusted baggage into request scope. Never call directly on untrusted public input. |
IdentityManager exposes get_distinct_id, get_anon_id, is_identified, identify, group,
get_groups, and reset. Use the module-level helpers for request scope.
Diagnostic events: AnalyticsClient
Capture snapshots event properties when enqueueing. Later mutations do not change queued events. Properties must be JSON-serializable; invalid events are rejected before they enter the queue. The built-in analytics and feature-flag HTTP clients do not follow redirects: configure the final API endpoint directly so project credentials stay at that endpoint.
events = anectico.AnalyticsClient(
endpoint='https://api.anectico.com',
api_key=os.environ['ANECTICO_API_KEY'],
release=os.environ.get('MY_APP_RELEASE'),
app_version=os.environ.get('MY_APP_VERSION'),
)
release and app_version are stamped as the reserved $release/$app_version string
properties on every capture()'d event when set; the SDK never auto-detects a server
deployment's version, so set them yourself from your own deploy pipeline (for example, reading
your own environment variable in application code — this module never reads the environment
itself). Leave them unset and the properties are omitted entirely, never sent as "". See
Reserved event properties.
| API | Parameters | Returns | Behavior |
|---|---|---|---|
AnalyticsClient(endpoint, api_key, flush_at=20, flush_interval_s=5, sender=None, on_delivery_error=None, release=None, app_version=None) |
connection, batching, optional custom sender, optional dropped-batch handler, optional release identifiers | client | Starts an optional daemon flush worker. |
capture(event, properties=None, *, distinct_id=None, session_id=None, timestamp=None) |
event and optional overrides | None |
Queues an event. Without an explicit ID it uses shared identity. |
identify(distinct_id, properties=None, *, anon_distinct_id=None) |
ID; properties; optional alias | None |
Queues identify and switches shared identity after enqueue; normal batching controls delivery. |
group(group_type, group_key, properties=None) |
group and properties | None |
Records shared membership and queues $groupidentify. |
flush() |
— | bool |
Validates complete indexed acknowledgements. Returns True for all attempted events queue-acknowledged (or an empty queue), False for explicit refusals without pending retries, and raises RuntimeError while uncertain events remain. |
stop() |
— | bool |
Stops the worker and flushes, returning what that final flush returned. Raises while retryable events remain queued. Further capture calls raise a closed-client error. |
disable() |
— | None |
Immediately closes analytics collection and discards pending work without a final flush; active delivery settles separately. |
stats() |
— | dict[str,int] |
recorded, delivered, dropped, queued. delivered counts validated queue acknowledgements; dropped counts explicit refusals/local overflow; queued includes in-flight and uncertain events. |
reset() |
— | None |
Attempts to flush, then rotates shared anonymous identity even if delivery raises; retained events keep their original attribution. |
Capture uses the versioned indexed acknowledgement contract. HTTP status alone never proves delivery or refusal. The SDK validates the version, request UUID, original indices, all outcomes and totals before changing counters. Queue acknowledgement does not prove a unique stored row, query visibility or a completed identity mutation.
flush() raises while uncertain events remain, including network errors and malformed responses
at any HTTP status. A flush can report explicit drops and also retain an uncertain remainder;
inspect stats() and on_delivery_error when it raises. Only uncertain original positions and
unsent later chunks retry, preserving message IDs, identity, timestamps and payloads. Retries wait
at least one second and honor Retry-After up to 60 seconds. Accepted and refused siblings are
never automatically retried.
stop() performs a final flush. For collection withdrawal, call disable() instead:
collection closes immediately and pending events are discarded with collection_disabled.
Further capture/identify/group/sync_person calls raise the closed-client RuntimeError. Disable
is nonblocking and safe in a delivery callback; call flush() outside callbacks to wait for
an active request to settle, then inspect stats. A chunk already admitted to delivery may still
reach the server; its validated acceptance/refusal counts remain, but uncertain positions and
later chunks are never retried. A flush that discards work returns False. After settlement,
queued is zero. Repeated disable is safe; new consent requires a new AnalyticsClient. This does
not erase stored events or disable separate telemetry clients. Custom synchronous senders must
supply a finite I/O deadline; the SDK cannot cancel arbitrary Python code. Gate collection before
initialization where your application requires it.
Explicit refusals are reported once per affected chunk through
on_delivery_error(DeliveryError(status, dropped, reason)), stats()["dropped"], and a warning.
Reasons include invalid_event, quota_exceeded, mixed_rejection, bad_request, unauthorized,
forbidden, payload_too_large, queue_overflow and collection_disabled (local discards use status 0). Uncertainty
alone does not fire a drop callback. A handler that raises is swallowed. Response bodies larger
than 64 KiB or inconsistent with HTTP framing remain uncertain, even with a valid JSON prefix.
events = anectico.AnalyticsClient(
endpoint='https://api.anectico.com',
api_key=os.environ['ANECTICO_API_KEY'],
on_delivery_error=lambda err: my_alerting.warn(
f'anectico dropped {err.dropped} events: {err.status} {err.reason}'
),
)
Capture resolves its explicit ID, request-local identity, W3C baggage, then shared identity. Shared
$groups are inherited only for that shared person; explicit event $groups take precedence.
Request-scoped group assertions do not change another person's shared memberships. Identity/group
changes follow successful enqueue even when immediate delivery fails. reset() clears identity
even during a delivery outage, while queued events keep their original attribution.
Custom senders must return anectico.analytics.SendResult(status, body, retry_after_s=None).
body contains the exact response bytes, including typed failures. An integer status or an
assumed accepted count is insufficient evidence and leaves the batch queued. Custom transports
must bound their network operations and preserve complete response framing; the default urllib
sender uses a 10-second socket timeout, a bounded body read, and checks declared content length.
Both use the same acknowledgement validator.
Analytics and feature-flag endpoints must be absolute HTTP(S) base URLs without credentials,
query strings, or fragments.
Feature flags: anectico.feature_flags.FeatureFlags
Bootstrap data and returned payload containers are copied. Exposure deduplication distinguishes identity, flag name, and the response's type and value. Remote decision responses must contain one JSON document of at most 16 MiB, with boolean or string flag values. Invalid responses preserve the last valid cache; overlapping reloads allow only the latest invocation to replace it.
Construct with endpoint, api_key, a capture(event, properties, distinct_id) callback, and
optional bootstrap response. The key needs flags:read; the callback normally sends exposure events
using analytics:write.
| Method | Parameters | Returns | Behavior |
|---|---|---|---|
reload(distinct_id, person_properties=None, groups=None) |
person and targeting context | None |
Calls /api/v1/decide and replaces cached decisions. Network/API failures raise. |
get_feature_flag(key, distinct_id) |
key and ID | decision or None |
Returns a decision and emits one deduplicated exposure. |
is_feature_enabled(key, distinct_id) |
key and ID | bool |
True for True or a non-empty string variant. |
get_feature_flag_payload(key) |
key | any | Returns a deep copy of the cached payload. |
get_all_flags() |
— | dict |
Returns a copy of cached flags. |
had_evaluation_errors() |
— | bool |
Whether the latest evaluation used a fallback. |
reset() |
— | None |
Clears exposure dedup after identity changes. |
refresh_local_evaluation() |
constructor project_id supplies scope |
"updated" | "not_modified" |
Fetches or conditionally revalidates the strict project snapshot; requires flags:read. |
evaluate_local(key, distinct_id, person_properties=None) |
flag key, exact identity, person properties | LocalEvaluationResult |
Uses only a fresh snapshot; successful reads use the constructor capture callback. |
Pass the exact canonical project_id to the same FeatureFlags constructor to enable server-side
local evaluation. refresh_local_evaluation() conditionally validates the versioned snapshot;
evaluate_local(key, distinct_id, person_properties=None) returns LocalEvaluationResult with a
value/payload or an explicit unavailable, stale, unsupported-target, or malformed-rule error. The
last-known-good snapshot is usable only through its advertised max-age. Successful local
matched/default reads use the existing capture callback to emit $feature_flag_called, deduped
per identity/key/value; reset() reopens both remote and local deduplication. That capture
path needs analytics:write when it sends to Anectico.
Framework and provider integrations
| Integration | Constructor/function | Behavior |
|---|---|---|
| FastAPI/Starlette | AnecticoFastAPIMiddleware(app, client=None, skip_paths=None, trust_incoming_identity=False, request_identity_resolver=None) |
Privacy-safe ASGI server spans, status/duration, fail-open errors, explicit cancellation outcomes, and optional sync/async server-authenticated identity. Matched operations/URL targets use the bounded route template; concrete path/query values are excluded. skip_paths=set() disables default exclusions. |
| Flask | AnecticoFlaskMiddleware(app, client, skip_paths=None, trust_incoming_identity=False) |
Registers request hooks without changing responses/error handlers. Matched operations and URL/target attributes use the bounded Werkzeug route; concrete path identifiers, query/fragment values, and unmatched paths are not exported. Unmatched operations use the HTTP method only. Unhandled exceptions are captured before Flask's framework log and the server span ends once during teardown, keeping one linked Issue/log/trace. skip_paths=set() explicitly disables the default health/static exclusions. |
| Django | AnecticoDjangoMiddleware after Django authentication; ANECTICO settings mapping |
Creates route-normalized server spans, request-scoped authenticated identity, privacy-safe ORM child spans, status/duration, and deduplicated real-view exception capture. Full query strings, SQL/parameter values, usernames, and email addresses are not exported on spans. USER_ID_RESOLVER accepts a callable or dotted path and defaults to authenticated user.pk; put recognizable profile fields in sync_person. |
| Django lifecycle | get_django_client() / shutdown_django_client() |
Returns the process-local auto-created client / returns its ShutdownResult and detaches it. A repeated hook returns attempted=False, success=None. Use the shutdown helper from Gunicorn worker_exit. |
FastAPI, Flask, and Django strip URL userinfo, query strings, and fragments.
HTTP attributes are bounded independently and receive a .truncated=true sibling
when shortened, so one oversized request does not invalidate an exporter batch.
Managed child spans also preserve the sampled or unsampled flag of a valid incoming
trace parent; local ratios apply only to new roots.
| Celery | AnecticoCeleryIntegration(app, client) / close() | Strongly registers publish/task lifecycle receivers; restores Anectico log export after Celery's default logger setup; injects and extracts W3C trace plus identity baggage through private broker headers; isolates each consumer attempt in its execution context, including overlapping deliveries with the same task ID, for child/log/error correlation; records type-only retry diagnostics; and never copies task arguments, results, or retry messages. close() disconnects receivers but does not stop the application-owned client. |
| grpc.aio unary client | AnecticoAioUnaryUnaryClientInterceptor(client) | Starts a client span and injects W3C trace/identity metadata only on channels where the interceptor is explicitly installed. Application messages, propagation values, and arbitrary metadata are not recorded. Non-OK transport spans remain visible but do not create generic Issues; capture one typed error at the domain handling boundary when needed. |
| grpc.aio server | AnecticoAioServerInterceptor(client, trust_incoming_identity=False) | Continues an inbound unary-unary trace, records method/duration/status, and rejects caller-supplied Anectico identity by default. Enable identity trust only on a private sanitizing boundary. Non-OK transport spans remain visible but do not create generic Issues. |
| OpenAI | wrap_openai(client, anectico_client, capture_content=False) | Idempotently instruments sync/async Chat Completions, including streams, in place and returns the same client. A stream records once on exhaustion; use stream_options={"include_usage": True} for token/cost fields. |
| Anthropic | wrap_anthropic(client, anectico_client, capture_content=False) | Instruments sync/async messages, including streams, in place and returns the same client. Token and cache counts need no extra request parameter. |
A stream is recorded once, when it is exhausted, fails, or is abandoned. Closing a
stream before exhaustion — or leaving its with block early — is not an error:
the span keeps its normal status and carries
anectico.gen_ai.stream.abandoned = true, so early exits stay out of your error
rate while remaining distinguishable. Its token counts are the provider's last
reported values and are partial by construction. A provider or iteration
exception records an error-status call and is preserved unchanged.
Stream telemetry retains the identity and trace context present when the provider call began, even if a different request or task later consumes the stream.
Neither wrapper changes your request; stream_options={"include_usage": True} is
never added for you, because it inserts an extra empty-choices chunk into your
loop and is rejected outright by some OpenAI-compatible gateways. A count the
provider never reported is recorded as absent, never as zero. Anthropic's
messages.stream() helper is not covered — it issues its own request rather than
going through messages.create — so use messages.create(..., stream=True) for
an instrumented stream. Telemetry errors never replace a provider exception.
Content capture is disabled by default.
Authentication and lower-level utilities
These exports support custom middleware and integrations. Application code should generally use
AnecticoClient and AnalyticsClient.
| API/type | Parameters or fields | Returns/behavior |
|---|---|---|
validate_api_key(key) |
string | None; raises InvalidAPIKeyError for an unsupported key shape. |
anectico.auth.is_api_key_format(value) |
string | Boolean shape check without throwing. |
mask_api_key(key) |
string | Log-safe prefix plus last four characters; never usable as a credential. |
User(...) |
id, email, username, ip_address, segment, data |
Error-user data class; to_otel_attributes() returns enduser.*/user.data.* attributes. |
set_context_user(user) |
User or None |
Sets async request-local error-user context; call with None when the scope ends. |
get_context_user() |
— | Request-local User or None. |
Breadcrumb(timestamp, category, message, level, data=None) |
canonical breadcrumb fields | to_dict() returns the JSON-compatible wire shape, omitting empty data. |
BreadcrumbBuffer() |
fixed capacity 100 | Thread-safe add, snapshot, serialize, drain, and clear; drain serializes and clears atomically. |
ErrorLevel |
DEBUG, INFO, WARNING, ERROR, FATAL |
String severity constants. |
ErrorOptions(...) |
user, tags, extra, level, fingerprint |
Data class for custom error-recording integrations. Normal capture calls accept these fields directly. |
IdentityManager() |
— | Thread-safe holder with get_distinct_id, get_anon_id, is_identified, observability_distinct_id, identify, group, get_groups, and reset. Use the module-level functions for request scope. |
shared_identity() |
— | Process-wide manager shared by signals and diagnostic events. |
BaggageIdentitySpanProcessor(identity=None) |
optional IdentityManager |
Identity-only span processor for application-owned providers. Defaults to shared_identity(); does not export/register/own lifecycle. Add before the export processor. |
BaggageIdentityLogRecordProcessor(identity=None) |
optional IdentityManager |
Identity-only log processor for application-owned providers. Defaults to shared_identity(); does not export/register/own lifecycle. Add before the export processor. |
BAGGAGE_DISTINCT_ID_KEY |
constant | The W3C baggage member name anectico.distinct_id. |
DistinctIDScope |
opaque token | Returned by set_context_distinct_id; pass it to reset_context_distinct_id. |
anectico.__version__ reports the installed package version. Lower-level stack/error serializer and
transport modules are implementation APIs and may change; use the public client methods above.