---
title: "Context Managers"
description: "Use AgentOps traces as Python context managers for automatic lifecycle management"
---
# Context Managers
AgentOps provides native context manager support for traces, allowing you to use Python's `with` statement for automatic trace lifecycle management. This approach ensures traces are properly started and ended, even when exceptions occur.
## Basic Usage
The simplest way to use context managers is with the `start_trace()` function:
```python
import agentops
# Initialize AgentOps
agentops.init(api_key="your-api-key")
# Use context manager for automatic trace management
with agentops.start_trace("my_workflow") as trace:
# Your code here
print("Processing data...")
# Trace automatically ends when exiting the with block
```
The trace will automatically:
- Start when entering the `with` block
- End with "Success" status when exiting normally
- End with "Error" status if an exception occurs
- Clean up resources properly in all cases
## Advanced Usage
### Traces with Tags
You can add tags to traces for better organization and filtering:
```python
import agentops
agentops.init(api_key="your-api-key")
# Using list tags
with agentops.start_trace("data_processing", tags=["batch", "production"]):
process_batch_data()
# Using dictionary tags for more structured metadata
with agentops.start_trace("user_request", tags={
"user_id": "12345",
"request_type": "query",
"priority": "high"
}):
handle_user_request()
```
### Parallel Traces
Context managers create independent parallel traces, not parent-child relationships:
```python
import agentops
agentops.init(api_key="your-api-key")
# Sequential parallel traces
with agentops.start_trace("task_1"):
print("Task 1 executing")
with agentops.start_trace("task_2"):
print("Task 2 executing")
# Nested context managers create parallel traces
with agentops.start_trace("outer_workflow"):
print("Outer workflow started")
with agentops.start_trace("inner_task"):
print("Inner task executing (parallel to outer)")
print("Outer workflow continuing")
```
### Exception Handling
Context managers automatically handle exceptions and set appropriate trace states:
```python
import agentops
agentops.init(api_key="your-api-key")
# Automatic error handling
try:
with agentops.start_trace("risky_operation"):
# This will automatically set trace status to "Error"
raise ValueError("Something went wrong")
except ValueError as e:
print(f"Caught error: {e}")
# Trace has already been ended with Error status
# Graceful degradation pattern
try:
with agentops.start_trace("primary_service"):
result = call_primary_service()
except ServiceUnavailableError:
with agentops.start_trace("fallback_service"):
result = call_fallback_service()
```
### Concurrent Execution
Context managers work seamlessly with threading and asyncio:
```python Threading
import agentops
import threading
agentops.init(api_key="your-api-key")
# With threading
def worker_function(worker_id):
with agentops.start_trace(f"worker_{worker_id}"):
# Each thread gets its own independent trace
process_work(worker_id)
threads = []
for i in range(3):
thread = threading.Thread(target=worker_function, args=(i,))
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
```
```python Asyncio
import agentops
import asyncio
agentops.init(api_key="your-api-key")
# With asyncio
async def async_task(task_id):
with agentops.start_trace(f"async_task_{task_id}"):
await asyncio.sleep(0.1) # Simulate async work
return f"result_{task_id}"
async def main():
tasks = [async_task(i) for i in range(3)]
results = await asyncio.gather(*tasks)
return results
# Run async tasks
results = asyncio.run(main())
```
## Production Patterns
### API Endpoint Monitoring
```python
import agentops
from flask import Flask, request
app = Flask(__name__)
agentops.init(api_key="your-api-key")
@app.route('/api/process', methods=['POST'])
def process_request():
# Create trace for each API request
with agentops.start_trace("api_request", tags={
"endpoint": "/api/process",
"method": "POST",
"user_id": request.headers.get("user-id")
}):
try:
data = request.get_json()
result = process_data(data)
return {"status": "success", "result": result}
except Exception as e:
# Exception automatically sets trace to Error status
return {"status": "error", "message": str(e)}, 500
```
### Batch Processing
```python
import agentops
agentops.init(api_key="your-api-key")
def process_batch(items):
with agentops.start_trace("batch_processing", tags={
"batch_size": len(items),
"batch_type": "data_processing"
}):
successful = 0
failed = 0
for item in items:
try:
with agentops.start_trace("item_processing", tags={
"item_id": item.get("id"),
"item_type": item.get("type")
}):
process_item(item)
successful += 1
except Exception as e:
failed += 1
print(f"Failed to process item {item.get('id')}: {e}")
print(f"Batch completed: {successful} successful, {failed} failed")
```
### Retry Logic
```python
import agentops
import time
agentops.init(api_key="your-api-key")
def retry_operation(operation_name, max_retries=3):
for attempt in range(max_retries):
try:
with agentops.start_trace(f"{operation_name}_attempt_{attempt + 1}", tags={
"operation": operation_name,
"attempt": attempt + 1,
"max_retries": max_retries
}):
# Your operation here
result = perform_operation()
return result # Success - exit retry loop
except Exception as e:
if attempt < max_retries - 1:
wait_time = 2 ** attempt # Exponential backoff
print(f"Attempt {attempt + 1} failed: {e}. Retrying in {wait_time}s...")
time.sleep(wait_time)
else:
print(f"All {max_retries} attempts failed")
raise
```
## Backward Compatibility
Context managers are fully backward compatible with existing AgentOps code patterns:
```python Manual Management
import agentops
agentops.init(api_key="your-api-key")
# Manual trace management (legacy)
trace = agentops.start_trace("manual_trace")
# ... your code ...
agentops.end_trace(trace, "Success")
```
```python Context Manager
import agentops
agentops.init(api_key="your-api-key")
# Context manager (new, recommended)
with agentops.start_trace("context_managed_trace") as trace:
# ... your code ...
pass # Automatically ended
```
```python Property Access
import agentops
agentops.init(api_key="your-api-key")
# Accessing trace properties
with agentops.start_trace("property_access") as trace:
span = trace.span # Access underlying span
trace_id = trace.span.get_span_context().trace_id
```
```python Mixed Usage
import agentops
agentops.init(api_key="your-api-key")
# Mixed usage
trace = agentops.start_trace("mixed_usage")
try:
with trace: # Use existing trace as context manager
# ... your code ...
pass
except Exception:
agentops.end_trace(trace, "Error")
```
## Examples
For complete working examples, see the following files in the AgentOps repository:
Simple context manager patterns and error handling
Sequential, nested, and concurrent trace patterns
Exception handling, retry patterns, and graceful degradation
API endpoints, batch processing, microservices, and monitoring
These examples demonstrate real-world usage patterns and best practices for using AgentOps context managers in production applications.
## API Reference
For detailed API information, see the [SDK Reference](/v2/usage/sdk-reference#trace-management) documentation.