> ## Documentation Index
> Fetch the complete documentation index at: https://www.sentrial.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Python SDK

> Complete reference for the Sentrial Python SDK. Track sessions, events, and get automatic LangChain integration.

## Installation

```bash theme={null}
pip install sentrial

# With LangChain support
pip install sentrial langchain-core
```

## Quick Start

```python theme={null}
import sentrial

# Configure (or set SENTRIAL_API_KEY env var)
sentrial.configure(api_key="sentrial_live_xxx")

# Track an interaction
interaction = sentrial.begin(
    user_id="user_123",
    event="chat_message",
    input="User's question"
)

# Your agent logic...
response = agent.run(user_input)

# Finish with outcome
interaction.finish(output=response, success=True)
```

## Module Functions

### `sentrial.configure()`

Configure the default Sentrial client.

```python theme={null}
sentrial.configure(
    api_key: str = None,         # API key (or use SENTRIAL_API_KEY env)
    api_url: str = None,         # API URL (default: https://api.sentrial.com)
    fail_silently: bool = True,  # If True, SDK errors are logged but won't crash your app
    pii: bool | PiiConfig = None,  # PII redaction (pass True to auto-fetch from server)
    batching: bool | BatcherConfig = None,  # Event batching for high-throughput agents
)
```

### `sentrial.begin()`

Begin tracking an interaction. Returns an `Interaction` object.

<ParamField body="user_id" type="string" required>
  External user ID.
</ParamField>

<ParamField body="event" type="string" required>
  Event type / agent name.
</ParamField>

<ParamField body="input" type="string">
  Input data.
</ParamField>

<ParamField body="event_id" type="string">
  Custom event ID (auto-generated if omitted).
</ParamField>

<ParamField body="convo_id" type="string">
  Conversation ID for grouping.
</ParamField>

<ParamField body="metadata" type="dict">
  Additional metadata.
</ParamField>

```python theme={null}
interaction = sentrial.begin(
    user_id="user_12345",
    event="support_request",
    input="Help me reset my password",
    convo_id="conv_789",
    metadata={"channel": "web_chat"}
)
```

## Interaction Class

Returned by `sentrial.begin()`. Provides methods to track events and finish the interaction.

### `interaction.finish()`

Finish the interaction and record final metrics.

```python theme={null}
interaction.finish(
    output: str = None,              # Output/response from interaction
    success: bool = True,            # Whether it succeeded
    failure_reason: str = None,      # Reason if success=False
    estimated_cost: float = None,    # Cost in USD
    custom_metrics: dict = None,     # Custom metrics
    duration_ms: int = None,         # Duration in milliseconds (auto-calculated if omitted)
    prompt_tokens: int = None,       # Prompt tokens used
    completion_tokens: int = None,   # Completion tokens used
    total_tokens: int = None         # Total tokens used
)
```

```python theme={null}
# Success example
interaction.finish(
    output="Password reset email sent!",
    success=True,
    estimated_cost=0.023,
    custom_metrics={"satisfaction": 4.5}
)

# Failure example
interaction.finish(
    success=False,
    failure_reason="User not found in database"
)
```

### `interaction.track_tool_call()`

Track a tool call within the interaction.

```python theme={null}
interaction.track_tool_call(
    tool_name="search_knowledge_base",
    tool_input={"query": "password reset"},
    tool_output={"results": ["KB-001", "KB-002"]},
    reasoning="User needs password help",
    estimated_cost=0.001
)
```

### `interaction.track_decision()`

Track an agent decision.

```python theme={null}
interaction.track_decision(
    reasoning="Will search KB before escalating",
    alternatives=["escalate_to_human", "ask_clarifying_question"],
    confidence=0.92
)
```

## SentrialClient Class

For full control over session management.

### Constructor

```python theme={null}
from sentrial import SentrialClient

client = SentrialClient(
    api_key: str = None,   # API key (or SENTRIAL_API_KEY env)
    api_url: str = None    # API URL (or SENTRIAL_API_URL env)
)
```

### `client.create_session()`

Create a new tracking session. Returns the session ID.

```python theme={null}
session_id = client.create_session(
    name: str,                        # Descriptive name
    agent_name: str,                  # Agent identifier (for grouping)
    user_id: str,                     # External user ID
    parent_session_id: str = None,    # Parent session ID (for sub-sessions)
    convo_id: str = None,             # Conversation ID (for grouping)
    metadata: dict = None             # Custom metadata
) -> str
```

### `client.track_tool_call()`

```python theme={null}
client.track_tool_call(
    session_id: str,
    tool_name: str,
    tool_input: dict,
    tool_output: dict,
    reasoning: str = None,
    estimated_cost: float = 0.0,
    tool_error: dict = None,         # Error details if the tool call failed
    token_count: int = None,         # Tokens used by the tool call
    trace_id: str = None,            # Trace ID for distributed tracing
    span_id: str = None,             # Span ID for distributed tracing
    metadata: dict = None            # Additional metadata
) -> dict
```

### `client.track_decision()`

```python theme={null}
client.track_decision(
    session_id: str,
    reasoning: str,
    alternatives: list[str] = None,
    confidence: float = None,
    estimated_cost: float = 0.0,
    token_count: int = None
) -> dict
```

### `client.complete_session()`

Complete a session with final metrics.

```python theme={null}
client.complete_session(
    session_id: str,
    success: bool = True,
    failure_reason: str = None,
    estimated_cost: float = None,
    custom_metrics: dict = None,
    duration_ms: int = None,
    prompt_tokens: int = None,
    completion_tokens: int = None,
    total_tokens: int = None,
    user_input: str = None,            # End-user input for this session
    assistant_output: str = None       # Agent/assistant response
) -> dict
```

### `client.track_error()`

```python theme={null}
client.track_error(
    session_id: str,
    error_message: str,
    error_type: str = None,         # e.g. "ValueError", "APIError"
    tool_name: str = None,          # Tool that caused the error
    stack_trace: str = None,        # Stack trace for debugging
    metadata: dict = None
) -> dict
```

## LLM Auto-Wrappers

Automatically track all LLM calls with token counts, cost, and latency.

```python theme={null}
from openai import OpenAI
from sentrial import wrap_openai, configure

configure(api_key="sentrial_live_xxx")

# Wrap your LLM client — all calls are now auto-tracked
client = wrap_openai(OpenAI())

interaction = sentrial.begin(user_id="user_123", event="chat", input=user_query)

# This call is automatically tracked
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": user_query}]
)

interaction.finish(output=response.choices[0].message.content)
```

Also available: `wrap_anthropic(client)`, `wrap_google(model)`, `wrap_llm(client)` (auto-detect).

## Decorators

```python theme={null}
from sentrial import tool, session, configure

configure(api_key="sentrial_live_xxx")

@tool("search_kb")
def search_knowledge_base(query: str) -> dict:
    """Automatically tracked — inputs, outputs, errors, duration."""
    return kb.search(query)

@session("support-agent")
def handle_request(user_id: str, message: str) -> str:
    """Auto-creates session, tracks all @tool calls inside."""
    results = search_knowledge_base(message)
    return format_response(results)

# Works with async too
@session("async-agent")
async def handle_async(user_id: str, message: str) -> str:
    results = await async_search(message)
    return results
```

## Context Manager

```python theme={null}
from sentrial import SentrialClient

client = SentrialClient(api_key="sentrial_live_xxx")

# Auto-finishes on exit, tracks success/failure
with client.begin(user_id="user_123", event="chat", input="Hello") as interaction:
    response = agent.run("Hello")
    interaction.set_output(response)

# Also works with async (use AsyncSentrialClient or module-level begin_async)
async_client = AsyncSentrialClient(api_key="sentrial_live_xxx")
async with async_client.begin(user_id="user_123", event="chat") as interaction:
    response = await agent.run("Hello")
    interaction.set_output(response)
```

## Event Batching

Queue tracking calls and flush periodically to reduce HTTP overhead.

```python theme={null}
from sentrial import configure, BatcherConfig

# Simple: just enable batching
configure(api_key="sentrial_live_xxx", batching=True)

# Advanced: customize flush behavior
configure(
    api_key="sentrial_live_xxx",
    batching=BatcherConfig(
        enabled=True,
        flush_interval=2.0,    # Flush every 2s (default: 1.0)
        flush_threshold=20,    # Flush after 20 events (default: 10)
        max_queue_size=500,    # Drop events if queue exceeds this (default: 1000)
    )
)

# Flush manually before shutdown
client.flush()
client.shutdown()
```

## PII Redaction

Automatically redact sensitive data before it leaves your infrastructure.

```python theme={null}
# Auto-fetch your org's PII config from the server
configure(api_key="sentrial_live_xxx", pii=True)

# Or configure locally
from sentrial.redact import PiiConfig, PiiBuiltinPatterns, PiiCustomPattern
from sentrial import SentrialClient

client = SentrialClient(
    api_key="sentrial_live_xxx",
    pii=PiiConfig(
        enabled=True,
        mode="label",            # "label" | "hash" | "remove"
        fields=["user_input", "assistant_output", "metadata", "reasoning"],
        builtin_patterns=PiiBuiltinPatterns(
            emails=True,
            phones=True,
            ssns=True,
            credit_cards=True,
        ),
        custom_patterns=[
            PiiCustomPattern(label="api_key", pattern=r"sk-[a-zA-Z0-9]{32,}"),
        ],
    ),
)
```

## Cost Calculation Helpers

Static methods to calculate LLM API costs.

### `calculate_openai_cost()`

```python theme={null}
cost = SentrialClient.calculate_openai_cost(
    model="gpt-4o",
    input_tokens=1000,
    output_tokens=500
)
# Returns: 0.0075 (USD)
```

### `calculate_anthropic_cost()`

```python theme={null}
cost = SentrialClient.calculate_anthropic_cost(
    model="claude-sonnet-4",
    input_tokens=1000,
    output_tokens=500
)
# Returns: 0.0105 (USD)
```

### `calculate_google_cost()`

```python theme={null}
cost = SentrialClient.calculate_google_cost(
    model="gemini-2.0-flash",
    input_tokens=1000,
    output_tokens=500
)
```

## Async Support

All SDK classes have async equivalents for use with `asyncio`.

```python theme={null}
import sentrial

# Async module-level API
sentrial.configure(api_key="sentrial_live_xxx")

interaction = await sentrial.begin_async(
    user_id="user_123",
    event="chat_message",
    input="User's question"
)

response = await agent.run(user_input)
await interaction.finish(output=response)
```

```python theme={null}
# Async client
from sentrial import AsyncSentrialClient

client = AsyncSentrialClient(api_key="sentrial_live_xxx")

session_id = await client.create_session(
    name="Async session",
    agent_name="my-agent",
    user_id="user_123"
)

await client.track_tool_call(
    session_id=session_id,
    tool_name="search",
    tool_input={"query": "test"},
    tool_output={"results": []}
)

await client.complete_session(session_id=session_id, success=True)
```

### `client.flush()`

Flush any queued events immediately. No-op if batching is not enabled.

```python theme={null}
client.flush()
```

### `client.shutdown()`

Shut down the event batcher, flushing remaining events. Call this before your process exits to ensure all events are sent.

```python theme={null}
client.shutdown()
```

## LangChain Integration

<Note>
  Use `SentrialCallbackHandler` to automatically track all LLM calls, tool usage, and agent decisions in LangChain.
  [Full LangChain Integration Guide →](/integrations/langchain)
</Note>

## Next Steps

<CardGroup cols={2}>
  <Card title="LangChain Integration" icon="link" href="/integrations/langchain">
    Automatic tracking for LangChain agents.
  </Card>

  <Card title="Claude Code Integration" icon="terminal" href="/integrations/claude-code-python">
    Auto-track Claude Agent SDK sessions and tool calls.
  </Card>

  <Card title="Mastra Integration" icon="robot" href="/integrations/mastra">
    One-line setup for Mastra AI agents.
  </Card>

  <Card title="Sessions API" icon="server" href="/api/sessions">
    REST API reference.
  </Card>
</CardGroup>
