Overview
TraceCtrl uses Python’s contextvars to maintain a session ID per thread or async context. Session IDs are stored on a ContextVar named tracectrl_session_id, which means they are isolated per thread and per async task automatically.
Automatic Session IDs
The SDK generates a UUID session ID when you call new_session():
from tracectrl.session import new_session, current_session_id
sid = new_session()
print(sid) # e.g., "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
print(current_session_id()) # same value
If the environment variable TRACECTRL_SESSION_ID is set, new_session() uses that value instead of generating a UUID.
Manual Session IDs
Override with your own session ID — useful for tying traces to your application’s session concept:
from tracectrl.session import set_session_id
set_session_id("user-session-abc123")
Environment Variable Override
Set TRACECTRL_SESSION_ID to force a specific session ID for any call to new_session():
export TRACECTRL_SESSION_ID="fixed-session-for-testing"
set_session_id() ignores the env var — it always writes the value passed in.
API Reference
new_session() -> str
Generates a new session ID (or reads from TRACECTRL_SESSION_ID) and stores it in the current context. Returns the session ID.
current_session_id() -> str | None
Returns the current session ID, or None if new_session() or set_session_id() hasn’t been called yet in this context.
set_session_id(sid: str) -> None
Explicitly sets the session ID. Use this for cross-agent session propagation — when Agent B receives a session ID from Agent A, call set_session_id() to continue the session.
Multi-Agent Sessions
In a multi-agent system where agents communicate via HTTP, send the session ID in a custom header alongside the W3C traceparent:
# Agent A — outgoing request
from tracectrl.session import current_session_id
from tracectrl.context import inject_trace_headers
import requests
headers = inject_trace_headers()
headers["X-TraceCtrl-Session"] = current_session_id()
requests.post("http://agent-b/api", headers=headers)
# Agent B — incoming request
from tracectrl.session import set_session_id
from tracectrl.context import extract_trace_headers
extract_trace_headers(request.headers)
set_session_id(request.headers["X-TraceCtrl-Session"])
# All spans now share the same session and trace
The X-TraceCtrl-Session header name is a TraceCtrl convention — pick anything you want as long as both sides agree, but stick with this name and the dashboard will recognise it.
Session IDs are stored in contextvars, so they are isolated between threads and async tasks. Each concurrent request gets its own session context with no extra plumbing.