Server-Side Integration
The Logic Layer is where Atheon's deep analysis takes place. By integrating on the server, you allow Atheon to generate Intent Fingerprints and power your Knowledge Graph securely — without ever storing raw PII.
1. Install the SDK
pip install atheon-codex
2. Initialise
Call atheon.init() (or atheon.async_init()) once at application startup. All subsequent calls — track(), begin(), decorators — use the global client automatically.
import os
import atheon
atheon.init(os.environ["ATHEON_API_KEY"])
import os
from contextlib import asynccontextmanager
import atheon
from fastapi import FastAPI
@asynccontextmanager
async def lifespan(app: FastAPI):
atheon.async_init(os.environ["ATHEON_API_KEY"])
yield
await atheon.async_shutdown()
app = FastAPI(lifespan=lifespan)
Advanced init options
atheon.init(
api_key=os.environ["ATHEON_API_KEY"],
upload_size=20, # Events per HTTP batch (default 10)
upload_interval=2.0, # Seconds between background flushes (default 1.0)
max_queue_size=50_000, # Max in-memory queue depth (default 10 000)
)
Only one client type per process. Call either
atheon.init()oratheon.async_init(), not both.
3. Track Interactions
Option A — track(): fire-and-forget for complete interactions
Use this when you have the full input and output ready at once.
interaction_id = atheon.track(
provider="openai",
model_name="gpt-4o",
input=user_query,
output=llm_response,
tokens_input=response.usage.prompt_tokens,
tokens_output=response.usage.completion_tokens,
finish_reason=response.choices[0].finish_reason,
properties={"agent": "support-bot"}, # optional
)
# Pass to frontend
return {"reply": llm_response, "interaction_id": str(interaction_id)}
# Call without await — enqueues immediately, non-blocking
interaction_id = atheon.async_track(
provider="openai",
model_name="gpt-4o",
input=req.message,
output=final_text,
tokens_input=response.usage.prompt_tokens,
tokens_output=response.usage.completion_tokens,
finish_reason=response.choices[0].finish_reason,
)
return {"reply": final_text, "interaction_id": str(interaction_id)}
Option B — begin() / finish(): streaming and multi-turn flows
Use this when the interaction spans time — streaming responses, tool calls, or multi-step pipelines. Latency is measured automatically from begin() to finish().
interaction = atheon.begin(
provider="anthropic",
model_name="claude-sonnet-4-5",
input=user_query,
properties={"agent": "rag-pipeline", "environment": "production"},
)
# ... do work, call tools, etc. ...
interaction.set_property("user_tier", "pro") # enrich mid-flight
interaction_id = interaction.finish(
output=final_text,
tokens_input=80,
tokens_output=220,
finish_reason="stop",
)
return {"reply": final_text, "interaction_id": str(interaction_id)}
interaction = atheon.async_begin(
provider="anthropic",
model_name="claude-sonnet-4-5",
input=req.message,
properties={"agent": "rag-pipeline"},
)
chunks = []
async for chunk in llm.stream(req.message):
chunks.append(chunk)
yield chunk
interaction_id = interaction.finish(
output="".join(chunks),
finish_reason="stop",
)
4. Track Tools with @atheon.tool
Decorate any function (sync or async) to record its execution time and errors automatically. The decorator hooks into the nearest active begin() context via Python's ContextVar — no explicit passing required.
import atheon
@atheon.tool("vector-search")
def search(query: str) -> list[str]:
return db.search(query)
@atheon.tool("reranker")
async def rerank(docs: list[str]) -> list[str]:
return await model.rerank(docs)
# Usage — tool records are attached to the active interaction automatically
interaction = atheon.begin(provider="openai", model_name="gpt-4o", input=query)
results = search(query) # ToolRecord added silently
ranked = await rerank(results)
interaction.finish(output=ranked[0], finish_reason="stop")
@atheon.toolis a no-op if called outside an activebegin()context — safe to use unconditionally.
5. Track Sub-Agents with @atheon.agent
Decorate LLM-backed sub-agent functions to nest their tool calls and token usage inside the root interaction's payload. Everything is shipped in a single event on finish().
import atheon
@atheon.tool("vector-search")
def vector_search(query: str) -> list[str]: ...
@atheon.agent(
"rag-pipeline",
provider="anthropic",
model_name="claude-haiku-4-5",
)
def rag_agent(query: str) -> str:
chunks = vector_search(query) # ToolRecord on rag-pipeline, not root
response = llm.messages.create(...)
atheon.set_result( # capture token counts for this sub-agent
tokens_input=response.usage.input_tokens,
tokens_output=response.usage.output_tokens,
finish_reason=response.stop_reason,
)
return response.content[0].text
# Root interaction wires everything together
interaction = atheon.begin(
provider="openai",
model_name="gpt-4o",
input=user_query,
)
result = rag_agent(user_query) # AgentRecord (with nested ToolRecord) on root
interaction.finish(output=result, finish_reason="stop")
Async sub-agents work identically — just make the decorated function async def.
6. Conversation Grouping
Pass a conversation_id to group multiple turns together in the dashboard.
import uuid
conversation_id = str(uuid.uuid4()) # generate once per session
atheon.track(
provider="openai",
model_name="gpt-4o",
input=turn_1_query,
output=turn_1_response,
conversation_id=conversation_id,
)
atheon.track(
provider="openai",
model_name="gpt-4o",
input=turn_2_query,
output=turn_2_response,
conversation_id=conversation_id,
)
7. Shutdown
Call shutdown() (or async_shutdown()) when your process exits to flush any remaining queued events.
atheon.shutdown()
await atheon.async_shutdown()
You can also use the clients as context managers for automatic shutdown:
with atheon.AtheonCodexClient(api_key=...) as client:
client.track(...)
# shutdown() called automatically on exit
Direct Client Instantiation
The module-level helpers (atheon.init, atheon.track, etc.) are the recommended approach. If you need multiple isolated clients in the same process, instantiate the class directly:
from atheon import AtheonCodexClient
client = AtheonCodexClient(api_key=os.environ["ATHEON_API_KEY"])
interaction_id = client.track(provider="openai", model_name="gpt-4o", input="...", output="...")
client.shutdown()
from atheon import AsyncAtheonCodexClient
async_client = AsyncAtheonCodexClient(api_key=os.environ["ATHEON_API_KEY"])
interaction_id = async_client.track(provider="openai", model_name="gpt-4o", input="...", output="...")
await async_client.shutdown()