Python SDK
Package: progress-observability
Overview
The Python SDK provides zero-intrusion telemetry for AI agents and LLM applications. It automatically instruments supported LLM providers and agent frameworks — you only need a one-line initialization call.
Use the Python SDK when your agent is written in Python and uses frameworks like LangChain, LlamaIndex, OpenAI, Anthropic, Google GenAI, or any of the other supported providers.
Core capabilities:
- Automatic instrumentation of 20+ LLM providers and frameworks
- Manual instrumentation with
@task,@workflow,@agent, and@tooldecorators - Tag propagation for filtering and grouping in the platform
- Content tracing control — choose whether prompts and completions are sent
- Environment variable overrides for deployment flexibility
Installation
From PyPI:
pip install progress-observability
Initialization
Call Observability.instrument() once at the start of your process, before any LLM or framework imports if possible:
from progress.observability import Observability
# Initialize once at process start
Observability.instrument(
app_name="my-app",
api_key="<your-api-key>"
)
All supported libraries are now instrumented automatically.
Configuration
Full configuration example with all options:
from progress.observability import Observability, ObservabilityInstruments
Observability.instrument(
app_name="my-app",
api_key="<your-api-key>",
endpoint="https://collector.observability.progress.com:443", # default
debug=False,
trace_content=True, # set False to exclude prompts/responses
instruments={ # only enable specific instruments
ObservabilityInstruments.OPENAI,
ObservabilityInstruments.LANGCHAIN
},
additional_tags=["production", "release:2.4.1"]
)
Parameters
| Parameter | Required | Default | Description |
|---|---|---|---|
| app_name | No | sys.argv[0] | Application name shown in the platform |
| api_key | Yes* | None | Your API key (* or set env var) |
| endpoint | No | https://collector.observability.progress.com:443 | Collector endpoint URL |
| debug | No | False | Enable debug logging |
| trace_content | No | True | Include prompts and completions in traces |
| instruments | No | None (all enabled) | Set of instruments to enable |
| block_instruments | No | None | Set of instruments to disable |
| additional_tags | No | None | Global tags applied to all spans |
| disable_batch | No | True | Send traces immediately |
Environment Variables
You can set these instead of (or in addition to) passing parameters to instrument():
# Set these environment variables instead of passing them to instrument()
export OBSERVABILITY_APP_NAME="my-app"
export OBSERVABILITY_API_KEY="<your-api-key>"
export OBSERVABILITY_ENDPOINT="https://collector.observability.progress.com:443"
export OBSERVABILITY_TRACE_CONTENT="true"
| Variable | Overrides |
|---|---|
| OBSERVABILITY_APP_NAME | app_name |
| OBSERVABILITY_API_KEY | api_key |
| OBSERVABILITY_ENDPOINT | endpoint |
| OBSERVABILITY_TRACE_CONTENT | trace_content (true or false) |
Decorators
Decorators add telemetry spans to your own functions. Each decorator creates a span with a specific kind, letting you visualize the structure of your agent in the platform.
| Decorator | Span Kind | Use For |
|---|---|---|
| @task | task | A discrete unit of work such as a data processing step or API call |
| @workflow | workflow | A multi-step orchestration that coordinates tasks |
| @agent | agent | An AI agent entry point |
| @tool | tool | A tool or function the agent can invoke |
Decorator Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| name | str | function name | Override span name |
| version | int | None | Version number for tracking |
| attributes | dict | None | Custom span attributes |
| tags | list[str] | None | Tags for this span (max 200 chars each) |
Examples
@agent
from progress.observability import agent
@agent(name="support-agent")
async def handle_support_request(message: str):
# Agent logic with LLM calls, tool usage, and so on
return response
@workflow
from progress.observability import workflow
@workflow(name="onboarding-flow", version=2)
async def onboard_customer(customer_id: str):
await verify_identity(customer_id)
await create_account(customer_id)
await send_welcome_email(customer_id)
@tool
from progress.observability import tool
@tool(name="web-search")
def search_web(query: str) -> str:
# Tool implementation
return results
@task
from progress.observability import task
@task(
name="custom-span-name", # override the default function name
version=2, # version number for tracking
attributes={"team": "ml"}, # custom span attributes
tags=["experiment-a"] # tags for filtering
)
def my_function():
...
Decorators work with both synchronous and asynchronous functions. On success, the decorator sets the span status to OK. On exception, the decorator sets the status to ERROR, records the exception on the span, and re-raises it.
Tags
Tags are user-defined strings (max 200 characters each) that you attach to spans for filtering and grouping in the platform. There are three ways to add tags:
1. Global Tags
Applied to every span. Set during initialization:
Observability.instrument(
app_name="my-app",
api_key="<your-api-key>",
additional_tags=["production", "release:2.4.1"]
)
2. Scoped Tags
Applied to all spans created within a context block:
from progress.observability import propagate_attributes
with propagate_attributes(tags=["tenant:acme", "experiment-v2"]):
# All spans created inside this block inherit these tags
my_agent_function()
# Nesting is supported — tags accumulate
with propagate_attributes(tags=["outer-tag"]):
with propagate_attributes(tags=["inner-tag"]):
do_work() # span gets both "outer-tag" and "inner-tag"
3. Decorator Tags
Applied to a single decorated function:
from progress.observability import task
@task(tags=["cohort-a"])
def my_task():
...
All three levels merge automatically. If the same tag appears at multiple levels it is deduplicated.
Supported Instruments
LLM Providers
OPENAI, GOOGLE_GENAI (alias GOOGLE_GENERATIVEAI), ANTHROPIC, BEDROCK, OLLAMA, and others.
Agent Frameworks
LANGCHAIN, LLAMA_INDEX, HAYSTACK, and others.
Controlling Instruments
from progress.observability import Observability, ObservabilityInstruments
# Enable everything except OpenAI
Observability.instrument(
app_name="my-app",
api_key="<your-api-key>",
block_instruments={ObservabilityInstruments.OPENAI}
)
To specifically enable or block Google GenAI instrumentation, use the enum value
ObservabilityInstruments.GOOGLE_GENERATIVEAI.
Shutdown
Call shutdown() before your process exits to flush any pending telemetry:
# Call shutdown before your process exits
# Using try/finally ensures telemetry is flushed even on errors
try:
# your application logic
run_agent()
finally:
Observability.shutdown()