Installation

poetry add autoblocksai
# or
pip install autoblocksai

Basic Example

Here’s a simple example showing how to use tracing with OpenAI:

import logging
from autoblocks.tracer import init_auto_tracer
from autoblocks.tracer import trace_app
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
from openai import AsyncOpenAI

# Configure logging
logging.basicConfig(level=logging.DEBUG)

# Initialize tracing
init_auto_tracer()
OpenAIInstrumentor().instrument()

# Initialize OpenAI client
openai = AsyncOpenAI()

@trace_app("my-app", "production")
async def generate_response(prompt: str):
    response = await openai.chat.completions.create(
        model="gpt-4",
        messages=[{
            "role": "user",
            "content": prompt
        }]
    )
    return response.choices[0].message.content

# Run the application
import asyncio
asyncio.run(generate_response("Hello, how are you?"))

Advanced Usage

Creating Spans

You can create custom spans using OpenTelemetry’s tracer:

from opentelemetry import trace
from opentelemetry.trace import SpanKind

tracer = trace.get_tracer("my-tracer")

async def my_function():
    with tracer.start_as_current_span("my_operation", kind=SpanKind.INTERNAL) as span:
        try:
            # Your code here
            span.set_attribute("result", "success")
        except Exception as e:
            span.record_exception(e)
            span.set_status(trace.Status(trace.StatusCode.ERROR))
            raise

Error Handling

Record exceptions in spans:

try:
    # Your code here
except Exception as e:
    span.record_exception(e)
    span.set_status(trace.Status(trace.StatusCode.ERROR))
    raise

Nested Spans

Create nested spans to represent complex operations:

async def complex_operation():
    with tracer.start_as_current_span("parent_operation") as parent_span:
        parent_span.set_attribute("parent_data", "value")
        
        with tracer.start_as_current_span("child_operation") as child_span:
            child_span.set_attribute("child_data", "value")
            # Child operation code

Best Practices

  1. Span Naming

    • Use descriptive names that reflect the operation
    • Follow a consistent naming convention
    • Include the operation type in the name
  2. Attribute Management

    • Add relevant context to spans
    • Avoid logging sensitive data
    • Use consistent attribute names
  3. Error Handling

    • Always record exceptions
    • Set appropriate error status
    • Include error details in attributes
  4. Performance

    • Keep spans focused
    • Avoid excessive attributes
    • Use sampling for high-volume applications
  5. Async Operations

    • Properly handle async/await with spans
    • Use context managers for span management
    • Use asyncio.gather for parallel operations
  6. Python Integration

    • Use context managers for span management
    • Leverage Python’s async/await patterns
    • Document complex operations

Additional Resources

OpenTelemetry

OpenLLMetry

Next Steps