The OpenAI wrapper is the simplest way to integrate Galileo logging into your application. By using Galileo’s OpenAI wrapper instead of importing the OpenAI library directly, you can automatically log all prompts, responses, and statistics without any additional code changes in an LLM span for every call.

The Galileo OpenAI wrapper currently only supports the synchronous chat completions API.

The wrapper supports both the OpenAI and Azure OpenAI APIs, so will work out of the box with Azure deployments, as well as any LLM that supports the OpenAI SDK.

Installation

First, make sure you have the Galileo SDK installed. If you are using Python, ensure you install the OpenAI optional dependency.

pip install "galileo[openai]"

Basic usage

If you are using Python, import the galileo.openai module, instead of the OpenAI openai module and use that to create your client. If you are using TypeScript, use the wrapper to wrap your OpenAI client.

import os
from galileo.openai import openai

# Initialize the Galileo wrapped OpenAI client
client = openai.OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))

# Use the Galileo wrapped OpenAI client which logs automatically
# This will create a single span trace with the OpenAI call
chat_completion = client.chat.completions.create(
    messages=[{"role": "user", "content": "Say this is a test"}],
    model="gpt-4o"
)

print(chat_completion.choices[0].message.content)

This example will automatically produce a single-span trace in your Log stream. The wrapper handles all the logging for you, capturing:

  • The input prompt
  • The model used
  • The response
  • Timing information
  • Token usage
  • Other relevant metadata

Sessions and traces

If you use the OpenAI wrapper by itself, it will automatically create a session and start a new trace for you, adding the call as an LLM span. Subsequent calls will be added as an LLM span to a new trace in the same session. The session will have an autogenerated name based off the content.

import os
from galileo.openai import openai

# Initialize the Galileo wrapped OpenAI client
client = openai.OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))

# Use the Galileo wrapped OpenAI client which logs automatically
# This will create a single span trace with the OpenAI call in a new session
first_result = client.chat.completions.create(
    messages=[{"role": "user", "content": "Tell me about the Roman Empire"}],
    model="gpt-4o"
)

# This second call will create a new single span trace inside the same session
second_result = client.chat.completions.create(
    messages=[{
        "role": "user", 
        "content": f"Summarize this: {first_result.choices[0].message.content}"
    }],
    model="gpt-4o"
)

print(second_result.choices[0].message.content)

If you manually start a session before using the OpenAI wrapper, all calls to the wrapper will be added as new traces to that session.

import os
from galileo.openai import openai
from galileo import galileo_context

# Get the logger instance
logger = galileo_context.get_logger_instance()

# Start a session
logger.start_session("Chat about the Roman Empire")

# Initialize the Galileo wrapped OpenAI client
client = openai.OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))

# Use the Galileo wrapped OpenAI client which logs automatically
# This will create a single span trace in the current session
first_result = client.chat.completions.create(
    messages=[{"role": "user", "content": "Tell me about the Roman Empire"}],
    model="gpt-4o"
)

# This second call will create a new single span trace inside the same session
second_result = client.chat.completions.create(
    messages=[{
        "role": "user", 
        "content": f"Summarize this: {first_result.choices[0].message.content}"
    }],
    model="gpt-4o"
)

print(second_result.choices[0].message.content)

If you create a new trace before using the OpenAI wrapper, all calls will be added as LLM spans to that trace.

import os
from galileo.openai import openai
from galileo import galileo_context

# Get the logger instance
logger = galileo_context.get_logger_instance()

# Start a session
logger.start_session("Chat about the Roman Empire")

# Start a new trace
logger.start_trace("Summary of the Roman Empire")

# Initialize the Galileo wrapped OpenAI client
client = openai.OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))

# Use the Galileo wrapped OpenAI client which logs automatically
# This will create a single span trace in the current session
first_result = client.chat.completions.create(
    messages=[{"role": "user", "content": "Tell me about the Roman Empire"}],
    model="gpt-4o"
)

# This second call will create a new single span trace inside the same session
second_result = client.chat.completions.create(
    messages=[{
        "role": "user", 
        "content": f"Summarize this: {first_result.choices[0].message.content}"
    }],
    model="gpt-4o"
)

print(second_result.choices[0].message.content)

Streaming support

The OpenAI wrapper also supports streaming responses. When streaming, the wrapper will log the response as it streams in:

import os
from galileo.openai import openai

client = openai.OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))

stream = client.chat.completions.create(
    messages=[{"role": "user", "content": "Say this is a streaming test"}],
    model="gpt-4o",
    stream=True,
)

# This will create a single span trace with the OpenAI call
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")

Combining with the log decorator

You can combine the OpenAI wrapper with the log decorator to create more complex traces:

import os
from galileo import log
from galileo.openai import openai

client = openai.OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))

def call_openai(prompt):
    # This will be automatically logged as a child span
    chat_completion = client.chat.completions.create(
        messages=[{"role": "user", "content": prompt}],
        model="gpt-4o"
    )
    return chat_completion.choices[0].message.content

@log(span_type="workflow", name="Roman Empire Span")
def make_nested_call():
    # This creates a parent workflow span
    first_result = call_openai("Tell me about the Roman Empire")
    second_result = call_openai(f"Summarize this: {first_result}")
    return second_result

# This will create a trace with a workflow span and two nested LLM spans
response = make_nested_call()
print(response)

Benefits of using the OpenAI integration

  • Zero-config logging: No need to add logging code throughout your application
  • Complete visibility: All prompts and responses are automatically captured
  • Minimal code changes: Change your import statement in Python, or create a wrapper in TypeScript. No other code changes are required.
  • Automatic tracing: Creates spans and traces without manual setup
  • Streaming support: Works with both regular and streaming responses

Asynchronous OpenAI calls with Galileo

Galileo’s Python SDK includes an OpenAI wrapper that currently supports only synchronous calls through the OpenAI client. It currently doesn’t not include built-in support for the AsyncOpenAI class from the official OpenAI Python library. As a result, asynchronous calls made via galileo.openai wrapper won’t automatically generate LLM spans or upload telemetry to Galileo.

You can still track async interactions by manually using the low-level GalileoLogger API. This requires importing and awaiting the OpenAI AsyncOpenAI client, wrapping each call with a call to add an LLM span, and flushing the logger to send your traces.

Next steps