Installation & Configuration
Installation
Install the base package:
pip install waxell-observe
Optional Extras
For LangChain integration, install with the langchain extra:
pip install waxell-observe[langchain]
This installs langchain-core as an additional dependency.
Quick Setup: init()
The fastest way to get started -- call init() once at application startup:
import waxell_observe
waxell_observe.init(
api_key="wax_sk_...",
api_url="https://waxell.dev",
)
# Import LLM SDKs AFTER init() -- they're now auto-instrumented
from openai import OpenAI
This:
- Configures the API client
- Auto-instruments installed AI/ML libraries (OpenAI, Anthropic, LiteLLM, and many more)
- Auto-instruments installed infrastructure libraries (HTTP clients, databases, caches)
- Enables OpenTelemetry tracing
init() Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
api_key | str | "" | Waxell API key (wax_sk_...). Falls back to WAXELL_API_KEY env var. |
api_url | str | "" | Waxell API URL. Falls back to WAXELL_API_URL env var. |
capture_content | bool | False | Include prompt/response content in traces. |
instrument | list[str] | None | None | Explicit list of AI/ML libraries to auto-instrument (e.g. ["openai", "anthropic"]). None means auto-detect all installed libraries. |
instrument_infra | bool | True | Enable auto-instrumentation of infrastructure libraries (HTTP clients, databases, caches, queues). Falls back to WAXELL_INSTRUMENT_INFRA env var. |
infra_libraries | list[str] | None | None | Only instrument these specific infra libraries (e.g. ["redis", "httpx"]). None means auto-detect all. |
infra_exclude | list[str] | None | None | Instrument all infra libraries except these (e.g. ["celery", "grpc"]). Falls back to WAXELL_INFRA_EXCLUDE env var (comma-delimited). |
resource_attributes | dict | None | None | Custom OTel resource attributes applied to all spans (e.g. {"deployment.environment": "production"}). |
debug | bool | False | Enable debug logging and console span export. |
prompt_guard | bool | False | Enable client-side prompt guard (regex PII/credential/injection detection). Falls back to WAXELL_PROMPT_GUARD env var. |
prompt_guard_server | bool | False | Also check server-side guard service (ML-powered detection). Falls back to WAXELL_PROMPT_GUARD_SERVER env var. |
prompt_guard_action | str | "block" | Action when violations are found: "block" (raise error), "warn" (log and continue), or "redact" (replace and continue). Falls back to WAXELL_PROMPT_GUARD_ACTION env var. |
Supported Libraries
init() auto-instruments a wide range of AI/ML libraries. See Auto-Instrumentation for the full list and details.
Drop-in Imports
Alternative to init() -- import pre-instrumented modules:
from waxell_observe.openai import openai
from waxell_observe.anthropic import anthropic
Kill Switch
Disable all observability without code changes:
export WAXELL_OBSERVE="false" # or "0" or "no"
Configuration
Waxell Observe requires two values to connect to your control plane:
| Setting | Description | Example |
|---|---|---|
api_url | Your Waxell control plane URL | https://acme.waxell.dev |
api_key | Your API key | wax_sk_abc123... |
Configuration Priority
Configuration is resolved in the following order (highest priority first):
- Explicit constructor arguments -- passed directly to
WaxellObserveClient() - Global configure() -- set via
WaxellObserveClient.configure() - CLI config file --
~/.waxell/config - Environment variables --
WAXELL_API_URL/WAXELL_API_KEY
Higher-priority sources override lower-priority ones. You can mix methods -- for example, set the URL in an environment variable and override the API key per-instance.
Method 1: Environment Variables
The simplest approach for most deployments:
export WAXELL_API_URL="https://acme.waxell.dev"
export WAXELL_API_KEY="wax_sk_abc123..."
Both long-form and short-form variable names are supported:
| Long Form | Short Form |
|---|---|
WAXELL_API_URL | WAX_API_URL |
WAXELL_API_KEY | WAX_API_KEY |
The long-form name takes precedence if both are set.
Method 2: CLI Config File
Create a config file at ~/.waxell/config in INI format:
[default]
api_url = https://acme.waxell.dev
api_key = wax_sk_abc123...
You can define multiple profiles by using different section names. The [default] section is used automatically. If no [default] section exists, the first section in the file is used.
Keep your ~/.waxell/config file secure. It contains your API key in plain text. Set file permissions to owner-only: chmod 600 ~/.waxell/config
Method 3: Programmatic configure()
Call WaxellObserveClient.configure() once at application startup:
from waxell_observe import WaxellObserveClient
WaxellObserveClient.configure(
api_url="https://acme.waxell.dev",
api_key="wax_sk_abc123...",
)
All subsequent WaxellObserveClient() instances, @observe decorators, and WaxellContext managers will use this configuration automatically.
This is the recommended approach for application code. Set it once in your application entry point and all observability calls pick it up.
Method 4: Per-Instance
Pass credentials directly when creating a client:
from waxell_observe import WaxellObserveClient
client = WaxellObserveClient(
api_url="https://acme.waxell.dev",
api_key="wax_sk_abc123...",
)
This overrides all other configuration sources for that specific client instance. You can also pass a client parameter to the decorator and context manager:
from waxell_observe import observe, WaxellContext
@observe(agent_name="my-agent", client=client)
async def my_function():
...
async with WaxellContext(agent_name="my-agent", client=client) as ctx:
...
Verifying Configuration
Check whether the client is properly configured:
from waxell_observe import WaxellObserveClient
# After calling configure()
print(WaxellObserveClient.is_configured()) # True or False
# Get the current global config
config = WaxellObserveClient.get_config()
if config:
print(config.api_url)
If the client is not configured when making API calls, it logs a warning and returns empty results instead of raising an error. This means missing configuration degrades gracefully rather than crashing your agent.
Next Steps
- Quickstart -- Get started in 2 minutes
- Auto-Instrumentation -- Zero-code tracing
- OpenAI Integration -- OpenAI-specific patterns
- Anthropic Integration -- Anthropic-specific patterns
- Decorator Pattern -- Add observability with
@observe - REST API Reference -- Direct API integration