Observed since 20 Oct, 20:57 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Public Python SDK for the Aetia LLM Gateway — governed inference, SSE streaming, async jobs, and tamper-evident run records.
The official Python SDK for the Aetia LLM Gateway — a governed, versioned
inference facade. It wraps authentication, HTTP, and SSE so you never hand-roll
requests: typed models mirror the API contract exactly, and a contract test keeps
the SDK and the gateway in lockstep (GATEWAY_CONTRACT_VERSION).
pip install aetia-gateway-sdk
Requires Python 3.11+. The client is async (built on httpx.AsyncClient).
The gateway has two external front doors; the SDK supports both.
aek_…)A long-lived key, sent directly on every request.
import asyncio
from aetia_gateway_sdk import GatewayClient, ApiKey
async def main():
async with GatewayClient("https://api.aetia.ai", ApiKey("aek_your_key")) as client:
result = await client.infer(model="openai:gpt-4o-mini", input="Hello, world")
print(result.output)
asyncio.run(main())
Pass a client_id / secret; the SDK exchanges them at
POST /api/v1/auth/service-token for a short-lived scoped bearer, caches it,
and auto-refreshes it before expiry and once on a 401. A burst of
concurrent requests coalesces onto a single token exchange.
from aetia_gateway_sdk import GatewayClient, ClientCredentials
creds = ClientCredentials(client_id="svc_...", secret="...")
async with GatewayClient("https://api.aetia.ai", creds) as client:
result = await client.infer(model="openai:gpt-4o-mini", input="Hello")
print(result.output, result.usage)
base_urlis the host root (e.g.https://api.aetia.ai), not the/gatewayprefix — the SDK builds the full/api/v1/...paths itself.
result = await client.infer(
model="openai:gpt-4o-mini",
input="Summarize the meeting notes.",
options={"temperature": 0.2, "max_tokens": 256}, # provider params go here
trace_id="my-trace-123", # echoed as correlation_id
)
result.output # the model output
result.routed_alias # the provider account the engine routed to
result.usage # token accounting
result.finish_reason
result.correlation_id # == trace_id (or a server-stamped id)
Unknown top-level fields are rejected client-side before any HTTP call — put
provider parameters in options, not at the top level.
stream() is an async context manager + iterator. It yields the engine's delta
events and, after iteration, exposes the terminal usage / finish_reason /
correlation_id plus the assembled text.
async with client.stream(model="openai:gpt-4o-mini", input="Write a haiku") as stream:
async for event in stream:
... # each engine delta event (dict)
print(stream.text) # assembled output
print(stream.usage, stream.correlation_id)
Streaming requires a provider-qualified model (alias:model_id). A non-streaming
provider raises StreamingUnsupportedError at open time (never a silent degrade).
submitted = await client.submit_job(model="openai:gpt-4o-mini", input="long batch job")
status = await client.get_job(submitted.job_id)
if status.status == "succeeded":
print(status.result)
receipt = await client.submit_run(
"run-42",
usage={"total_tokens": 1200},
project="deep-research", # arbitrary consumer fields ride along verbatim
)
receipt.ledger_event_id, receipt.record_hash, receipt.previous_hash # inclusion proof
view = await client.get_run("run-42") # tenant-scoped read-back
runs = await client.list_runs()
models = await client.list_models() # list[GatewayModelEntry], tenant-scoped
usage = await client.usage() # own-usage counts + honest rate-limit posture
Every non-2xx response raises a typed error (all subclasses of GatewayError),
carrying status_code, the machine error_code, detail, correlation_id, and
retry_after where present:
| Class | HTTP | Meaning |
|---|---|---|
AuthenticationError | 401 | Missing/invalid/expired/rejected credential |
PermissionDeniedError | 403 | Authenticated but missing scope / cross-tenant |
NotFoundError | 404 | Unknown job/run for this tenant |
RequestValidationError | 422 | Server-side request validation failed |
RateLimitError | 429 | Rate limited (retry_after) |
StreamingUnsupportedError | 400 | Streaming requested on a non-streaming provider |
ServerError | 5xx | Upstream/engine failure |
StreamError | — | An error event mid-stream |
Transient failures (429, and 5xx for idempotent requests) are retried with
backoff that honors Retry-After.
aetia_gateway_sdk.GATEWAY_CONTRACT_VERSION pins the semantic gateway contract
this SDK targets. The v1 contract is additive-compatible; a breaking change moves
the API to /v2 and the SDK to 2.x. The SDK's tests/test_contract.py asserts
the SDK's models match the published external OpenAPI
(GET /api/v1/gateway/openapi.json) in both directions, so drift fails the build.
pip install -e "sdk/python[test]"
# The in-process tests run against a real backend + real auth (only the LLM is
# mocked); the contract test needs only aetia_webapp importable (no DB).
pytest sdk/python/tests
Proprietary — © Aetia.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 1.1.0 | 31 Aug 2026 | 4 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 20:57 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:f1a50e29148eabc313e6f58d37ee426887042c5463bb829ce498ffb5caa3ddbb