Requires Python 3.9 or higher.
Installation
Quick Start
from glass import init, trace, interaction
from openai import OpenAI
# Initialize Glass
init(api_key="your-glass-api-key")
# Your AI calls are now automatically traced
client = OpenAI()
@trace()
def generate_response(prompt: str) -> str:
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.content
# Track user interactions
with interaction(user_id="user_123", session_id="sess_abc") as ctx:
result = generate_response("What is the meaning of life?")
ctx.finish(output={"response": result})
That’s it. All your OpenAI, Anthropic, and Google Generative AI calls are now traced automatically.
API Reference
init()
Initializes the Glass SDK. Call this once at application startup.
from glass import init
# Basic initialization
init(api_key="your-api-key")
# With debug mode (logs traces to console)
init(api_key="your-api-key", debug=True)
Your Glass API key. Falls back to GLASS_API_KEY environment variable if not provided.
Enable console output for local development.
skip_default_instrumentations
@trace()
Decorator that wraps any function with tracing. Automatically records arguments, return values, and exceptions.
from glass import trace
# Basic usage
@trace()
def process_data(data: dict) -> dict:
return {"processed": True, **data}
# Custom span name
@trace(name="custom-operation")
def my_function():
pass
# With attributes
@trace(attributes={"model": "text-embedding-3-small"})
def create_embedding(text: str) -> list[float]:
return [0.1, 0.2, 0.3]
Works with async functions too:
@trace()
async def async_process(data: str) -> str:
await asyncio.sleep(0.1)
return f"processed: {data}"
Custom span name. Defaults to the function name.
Additional attributes to attach to the span.
interaction()
Context manager for tracking user interactions. Propagates user context to all nested traces.
from glass import interaction, trace
@trace()
def call_llm(prompt: str) -> str:
return "LLM response"
with interaction(user_id="user_123", session_id="sess_abc", project="conversational-chat", input="Hello!") as ctx:
result = call_llm("Hello!")
ctx.finish(output={"response": result})
Also works with async:
async with interaction(user_id="user_123") as ctx:
result = await async_call_llm("Hello!")
ctx.finish(output={"response": result})
In which project to classify traces.
Service name for routing.
Methods on the context:
| Method | Description |
|---|
finish(output) | Record the final output of the interaction |
set_attribute(key, value) | Set a custom attribute |
record_exception(exception) | Record an exception |
task_span()
Context manager for creating task spans with explicit input/output recording.
from glass import task_span
with task_span("embedding-task", attributes={"model": "ada-002"}) as task:
task.record_input({"text": "Hello, world!"})
embedding = compute_embedding("Hello, world!")
task.record_output({"embedding": embedding, "dimensions": 1536})
The name of the task span.
Additional attributes for the span.
Methods on the task:
| Method | Description |
|---|
record_input(data) | Record input data |
record_output(data) | Record output data |
set_attribute(key, value) | Set a custom attribute |
record_exception(exception) | Record an exception |
Full Example: RAG Pipeline
Here’s how the primitives compose together:
from glass import init, trace, interaction, task_span
from openai import OpenAI
init(api_key="your-api-key")
client = OpenAI()
@trace()
def retrieve_context(query: str) -> list[str]:
return ["context 1", "context 2"]
@trace()
def generate_response(query: str, context: list[str]) -> str:
response = client.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": f"Context: {context}"},
{"role": "user", "content": query}
]
)
return response.choices[0].message.content
@trace(name="rag-pipeline")
def rag_query(query: str) -> str:
with task_span("retrieval") as task:
task.record_input({"query": query})
context = retrieve_context(query)
task.record_output({"num_docs": len(context)})
return generate_response(query, context)
# Track the full user interaction
with interaction(user_id="user_123", input="What is quantum computing?") as ctx:
result = rag_query("What is quantum computing?")
ctx.finish(output={"answer": result})
This creates a trace hierarchy like:
interaction (user_id=user_123)
└── rag-pipeline
├── retrieval (task_span)
│ └── retrieve_context
└── generate_response
└── OpenAI chat.completions.create (auto)
Environment Variables
| Variable | Description |
|---|
GLASS_API_KEY | Your Glass API key (alternative to passing in code) |
export GLASS_API_KEY="your-api-key"
from glass import init
# API key is read from environment
init()