Observed since 20 Oct, 20:25 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Official Python SDK for Aeonic — runtime monitoring and governance for AI agents
Aeonic Python SDK enables runtime monitoring, drift detection, and governance for AI agents running inside Python applications.
It works by observing agent-powered routes at runtime, capturing request/response samples, and securely sending them to the Aeonic platform for analysis.
The SDK is:
Only routes explicitly marked as agent routes are tracked.
All other routes are completely ignored by the SDK.
Install the base SDK (core only — requests is included):
pip install aeonic-agentguard-sdk-python
Install with your framework (recommended):
# FastAPI
pip install aeonic-agentguard-sdk-python[fastapi]
# Django
pip install aeonic-agentguard-sdk-python[django]
Note: The PyPI package name is
aeonic-agentguard-sdk-python, but you import it asaeonic.
Check the installed version:
import aeonic
print(aeonic.__version__)
| Requirement | Details |
|---|---|
| Python | >=3.9 |
| Core dependency | requests>=2.25.0 (installed automatically) |
| FastAPI (optional) | fastapi>=0.68.0 — install via [fastapi] extra |
| Django (optional) | django>=3.2.0 — install via [django] extra |
| Variable | Purpose |
|---|---|
AEONIC_ENDPOINT | Aeonic platform endpoint URL (provided in your Aeonic account or onboarding) |
AEONIC_DEBUG | Set to any value to enable debug logging |
ORIGIN / BASE_URL | Your application's public URL, sent with sample payloads |
PORT / HOST | Used to auto-detect your app origin when ORIGIN is not set |
from fastapi import Depends, FastAPI
from aeonic import init
from aeonic.adapters.fastapi import agent_middleware, with_agent
app = FastAPI()
app.add_middleware(agent_middleware)
init({
"api_key": "your_api_key",
"app": app,
"service_name": "my-service",
})
@app.post(
"/agent/chat",
dependencies=[Depends(with_agent({"name": "ChatAgent", "type": "support", "model": ["gpt-4o"]}))],
)
async def chat_agent(payload: dict):
return {"reply": "Hello!"}
Run with:
uvicorn main:app --reload
Initialize the SDK once at application startup.
init({
"api_key": str, # REQUIRED
"app": Any | None, # Optional: FastAPI/Django app for route introspection
"service_name": str | None, # Optional (recommended)
"introspection_delay_ms": int, # Optional: Delay before route scan (default: 2000ms)
"capture_payloads": {
"max_samples": int # Default: 10
}
})
from aeonic import init
init({
"api_key": "ag_test_123",
"service_name": "payments-api",
"capture_payloads": {
"max_samples": 10
}
})
from aeonic import init
from fastapi import FastAPI
app = FastAPI()
# Pass app instance for automatic route discovery
init({
"api_key": "ag_test_123",
"app": app, # ← Enables automatic agent discovery at startup
"service_name": "payments-api",
"introspection_delay_ms": 2000, # Wait 2s for routes to be defined
"capture_payloads": {
"max_samples": 10
}
})
api_keyapp is provided)📖 Route introspection: Pass your
appinstance toinit()so the SDK can discover agent routes automatically at startup.
Aeonic uses two components in FastAPI:
from fastapi import FastAPI
from aeonic.adapters.fastapi import agent_middleware
app = FastAPI()
# 🔴 MUST be registered once
app.add_middleware(agent_middleware)
This middleware:
Only routes using with_agent() are tracked.
from fastapi import Depends
from aeonic.adapters.fastapi import with_agent
@app.post(
"/agent/finance",
dependencies=[
Depends(
with_agent({
"name": "RefundRiskAgent",
"type": "finance",
"model": ["gpt-4o"]
})
)
]
)
async def finance_agent(payload: dict):
return {
"approved": True,
"amount": payload["amount"]
}
max_samples is reached, data is sent to the Aeonic platform| Feature | Behavior |
|---|---|
| Only marked routes tracked | ✅ |
| Async safe | ✅ |
| Middleware-based | ✅ |
| No contextvars hacks | ✅ |
| Production ready | ✅ |
Django uses:
settings.pyMIDDLEWARE = [
...
"aeonic.adapters.django.agent_middleware",
]
Ensure
init()is called during startup (e.g., insettings.pyorwsgi.py).
from django.http import JsonResponse
from aeonic.adapters.django import with_agent
@with_agent({
"name": "RefundRiskAgent",
"type": "finance",
"model": ["gpt-4o"]
})
def finance_agent(request):
return JsonResponse({
"approved": True,
"amount": 500
})
| Feature | Behavior |
|---|---|
| Declarative agent marking | ✅ |
| Middleware-based capture | ✅ |
| Sync-safe | ✅ |
| No framework coupling | ✅ |
| Production ready | ✅ |
Each agent route is identified by:
name – logical agent nametype – business domain (finance, healthcare, etc.)model – AI models usedAeonic correlates:
HTTP Route + Method + Agent Metadata
This enables:
max_samples are collected per flushThe Aeonic platform classifies agents as:
Status updates are visible in the Aeonic dashboard.
RuntimeError: Aeonic SDK not initializedCall init({...}) once at application startup before any SDK features are used.
with_agent() (FastAPI dependency or Django decorator).agent_middleware).blocked or quarantined (check Aeonic dashboard).AEONIC_DEBUG=1 to see SDK debug output.ModuleNotFoundError: No module named 'fastapi' or 'django'Install the matching framework extra:
pip install aeonic-agentguard-sdk-python[fastapi]
# or
pip install aeonic-agentguard-sdk-python[django]
"app": app to init().init() runs during startup and routes are registered before introspection completes.introspection_delay_ms if routes are registered late (e.g. 3000 or 5000).Set your Aeonic endpoint URL (provided during onboarding):
export AEONIC_ENDPOINT=https://your-aeonic-endpoint
On Windows PowerShell:
$env:AEONIC_ENDPOINT="https://your-aeonic-endpoint"
MIT © Aeonic
This section documents the public SDK functions and middleware for integrating Aeonic into your application.
aeonic.init(config: dict)Purpose
Initializes the Aeonic SDK once at application startup, validates and normalizes configuration, kicks off background route introspection, and (optionally) registers the process as an AgentGuard instance.
Arguments
config (dict) – configuration object with the following keys:
api_key (str, required): Your Aeonic API key. If missing, init raises ValueError.app (FastAPI | Django | None, optional): Application instance used for automatic route introspection and agent discovery at startup. Required for FastAPI introspection; optional for Django (Django can be introspected without app).service_name (str | None, optional): Logical name for the service (e.g. "payments-api"). Propagated to all emitted events and inventories.capture_payloads (dict, optional): Controls how request/response payload samples are collected.
max_samples (int, optional): Number of samples to buffer per agent route before flushing. Defaults to 10 when omitted.introspection_delay_ms (int, optional): Delay (in milliseconds) before route introspection runs. Defaults to 2000 ms, giving the application time to register all routes.agentguard_enabled (bool, optional): When True (default), the SDK registers itself as an AgentGuard instance in a background thread. When False, this registration step is skipped, but sample collection still works.Behavior
api_key, service_name, max_samples, app, introspection_delay_ms, agentguard_enabled."[Aeonic] SDK initialized.") using the aeonic logger.agentguard_enabled is True, registers your service with Aeonic in a background daemon thread:
introspection_delay_ms before running.config["app"] and calls introspect_routes(app).app is None but Django is installed, calls introspect_routes(None), which uses Django’s URL resolver.app and Django not installed), calls a fallback that attempts to emit inventory once agents exist.Typical usage
from aeonic import init
from fastapi import FastAPI
app = FastAPI()
init({
"api_key": "ag_test_123",
"app": app,
"service_name": "payments-api",
"introspection_delay_ms": 2000,
"capture_payloads": {
"max_samples": 10,
},
# Optional – disable AgentGuard registration if needed:
# "agentguard_enabled": False,
})
Accessing effective config (advanced)
For debugging or advanced inspection, you can read the effective configuration:
from aeonic.core import get_config
cfg = get_config() # raises RuntimeError if init() was not called
aeonic.adapters.fastapi.agent_middlewarePurpose
FastAPI-compatible middleware (BaseHTTPMiddleware) that observes responses and captures samples only for requests that have been marked as agent routes via with_agent.
How to register
from fastapi import FastAPI
from aeonic.adapters.fastapi import agent_middleware
app = FastAPI()
app.add_middleware(agent_middleware)
Request/response handling
call_next(request)) first to let your business logic run.request.state.aeonic:
is_agent is falsy, returns the response immediately (non-agent route).x-aeonic-assessment: true is present, no samples are collected.AEONIC_DEBUG environment variable is set, the middleware logs a debug message and includes optional x-aeonic-job-id for traceability.should_collect_samples(agent_key) from aeonic.core.agent_status_cache.agent_key is agent["name"] when available, otherwise "<METHOD>:<PATH>".AEONIC_DEBUG is set and an agent is blocked, a message is printed for easier debugging.Payload capture
request.state.aeonic["req_payload"], which is set by the with_agent dependency (to avoid re-consuming the body).safe_serialize to guarantee JSON-safe structures.response.body directly when available (typical for JSON responses).body_iterator exists (streaming responses), it:
Response with the same status, headers, and media type.Content-Type header:
"json" and the body is non-empty, attempts json.loads() and then safe_serialize the result.Sample creation and buffering
{"req": req_payload, "res": res_payload, "timestamp": int(time()), "status_code": status_code}.get_config():
config["max_samples"], config["api_key"], and config["service_name"].SampleBuffer in an in-memory _BUFFERS map, keyed by agent_key.100 agents; when exceeded, the oldest key is evicted.buffer.add(sample):
max_samples), buffer.flush() is called and the payload is enqueued via enqueue(...) for asynchronous delivery to Aeonic.emit_error_sample(...) with a single-sample payload.Key properties
with_agent has attached metadata.aeonic.adapters.fastapi.with_agent(agent: AgentContext)Purpose
FastAPI dependency factory that marks an endpoint as an agent route and attaches agent metadata and request payloads to the request.state.aeonic object.
Agent context (AgentContext)
AgentContext is a dict-like structure with keys such as:
name (str, recommended): Logical agent name, used as the primary key for statistics and status.type (str | None): Business/domain category (e.g. "finance", "support", "claims").model (str | list[str] | None): Model identifier(s) powering the agent (e.g. "gpt-4o").Declaration-time behavior
with_agent(agent) at import time:
_register_agent_declaration(agent, framework="fastapi"), which in turn:
service_name.name, type, model, framework="fastapi", and service_name.route_path=None and http_method=None initially (filled in later by route introspection)."source": "manual") in an internal map keyed by the dependency function’s ID.__aeonic_metadata__ for robust detection, even when FastAPI wraps or decorates dependencies.Request-time behavior
with_agent(agent) returns an async dependency callable compatible with Depends:from fastapi import Depends
from aeonic.adapters.fastapi import with_agent
@app.post(
"/agent/finance",
dependencies=[Depends(with_agent({"name": "RefundRiskAgent", "type": "finance", "model": ["gpt-4o"]}))],
)
async def finance_agent(payload: dict):
...
await request.json():
body is serialized with safe_serialize.body is set to None.request.state.aeonic:
{"is_agent": True, "agent": {**agent, "source": "manual"}, "req_payload": body}.request.state.aeonic object is later consumed by agent_middleware to decide whether and how to capture samples.Introspection helper: get_agent_metadata(func) (advanced)
aeonic.adapters.fastapi.get_agent_metadata(func):
AgentContext from:
__aeonic_metadata__ attribute on the function or wrapped function..call attribute (for FastAPI dependency objects).aeonic.adapters.django.agent_middlewarePurpose
Global Django middleware class that observes responses and captures samples only for views that have been marked as agent routes via the with_agent decorator.
How to register
# settings.py
MIDDLEWARE = [
...
"aeonic.adapters.django.agent_middleware",
]
Request/response handling
get_response.response = get_response(request) to run your Django view and middleware stack.request.aeonic:
is_agent is falsy, returns the response immediately (non-agent route).request.META["HTTP_X_AEONIC_ASSESSMENT"] to detect the header X-Aeonic-Assessment: true.AEONIC_DEBUG is set, logs a message including optional HTTP_X_AEONIC_JOB_ID.should_collect_samples(agent_key) with agent_key = agent["name"] or "<METHOD>:<PATH>".AEONIC_DEBUG is set and an agent is blocked, logs a message.Payload capture
request.aeonic["req_payload"], which is set by the with_agent decorator.safe_serialize.response["Content-Type"] header."json", attempts:
response.content as UTF‑8.safe_serialize the result.Sample creation and buffering
{"req": req_payload, "res": res_payload, "timestamp": int(time()), "status_code": status_code}.get_config() and uses max_samples, api_key, and service_name.SampleBuffer in _BUFFERS, capped at 100 distinct agent keys with eviction of the oldest entry when full.max_samples), calls buffer.flush() and enqueues the batch via enqueue(...).emit_error_sample(...) immediately with a single sample.aeonic.adapters.django.with_agent(agent: AgentContext)Purpose
Decorator that marks a Django view as an agent route and attaches agent metadata and payloads to request.aeonic.
Declaration-time behavior
_register_agent_declaration(agent, framework="django"):
name, type, model, framework="django", service_name, and route_path/http_method initially set to None.functools.wraps."source": "manual") in an internal map keyed by the wrapped view’s ID.__aeonic_metadata__ for easier introspection later.Request-time behavior
req_payload:
POST, PUT, PATCH:
CONTENT_TYPE from request.META."json" and request.body is non-empty:
safe_serializes the result.GET:
request.GET has query parameters, serializes dict(request.GET).req_payload to an empty dict {}.req_payload falls back to None.request.aeonic = {"is_agent": True, "agent": {**agent, "source": "manual"}, "req_payload": req_payload}.Introspection helper: get_agent_metadata(func) (advanced)
aeonic.adapters.django.get_agent_metadata(func):
__aeonic_metadata__ attribute if present.aeonic.init(config: dict) – one-time SDK setup, background introspection, and optional AgentGuard registration.aeonic.adapters.fastapi.agent_middleware – global middleware for observing and sampling agent routes.aeonic.adapters.fastapi.with_agent(agent: AgentContext) – dependency factory to mark FastAPI endpoints as agent routes and capture request bodies.aeonic.adapters.django.agent_middleware – middleware class for global observation and sampling of agent views.aeonic.adapters.django.with_agent(agent: AgentContext) – decorator to mark Django views as agent routes and capture request data.aeonic.core.get_config() – read the effective runtime SDK configuration.aeonic.adapters.fastapi.get_agent_metadata(func) / aeonic.adapters.django.get_agent_metadata(func) – used by introspection to map framework objects back to agent metadata.You can map each function/middleware above to your integration: use the descriptions as guidance and the code snippets as copy-paste examples.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.1.9 | 21 Jul 2026 | 7 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 20:25 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:c7711a35e80d411aaba2d488ff95c9a22e4203e1b72d0470bfc0024ab1ffe70d