Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,20 @@ def clear_exporter(trace_exporter, metrics_reader, logs_exporter):
logs_exporter.clear()


# TODO: should drop autouse and use it explicitly?
@pytest.fixture(autouse=True)
def instrument():
@pytest.fixture
def instrument(monkeypatch, clear_exporter):
monkeypatch.delenv("OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT", raising=False)
instrumentor = OpenAIInstrumentor()
instrumentor.instrument()

yield instrumentor

instrumentor.uninstrument()


@pytest.fixture
def capture_message_content_instrument(monkeypatch, clear_exporter):
monkeypatch.setenv("OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT", "true")
instrumentor = OpenAIInstrumentor()
instrumentor.instrument()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,10 @@
from copy import deepcopy
from dataclasses import dataclass
from typing import List, Optional
Comment thread
xrmx marked this conversation as resolved.
from unittest import mock

import openai
import pytest
from opentelemetry._logs import LogRecord
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
from opentelemetry.semconv._incubating.attributes.gen_ai_attributes import (
GEN_AI_OPENAI_REQUEST_SERVICE_TIER,
GEN_AI_OPENAI_RESPONSE_SERVICE_TIER,
Expand Down Expand Up @@ -71,7 +69,7 @@

@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
@pytest.mark.vcr()
def test_chat(default_openai_env, trace_exporter, metrics_reader, logs_exporter):
def test_chat(default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument):
client = openai.OpenAI()

messages = [
Expand Down Expand Up @@ -136,7 +134,9 @@ def test_chat(default_openai_env, trace_exporter, metrics_reader, logs_exporter)

@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
@pytest.mark.vcr()
def test_chat_with_developer_role_message(default_openai_env, trace_exporter, metrics_reader, logs_exporter):
def test_chat_with_developer_role_message(
default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument
):
client = openai.OpenAI()

messages = [
Expand Down Expand Up @@ -209,7 +209,7 @@ def test_chat_with_developer_role_message(default_openai_env, trace_exporter, me

@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
@pytest.mark.vcr()
def test_chat_all_the_client_options(default_openai_env, trace_exporter, metrics_reader, logs_exporter):
def test_chat_all_the_client_options(default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument):
client = openai.OpenAI()

messages = [
Expand Down Expand Up @@ -299,13 +299,8 @@ def test_chat_all_the_client_options(default_openai_env, trace_exporter, metrics
@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
@pytest.mark.vcr()
def test_chat_multiple_choices_with_capture_message_content(
default_openai_env, trace_exporter, metrics_reader, logs_exporter
default_openai_env, trace_exporter, metrics_reader, logs_exporter, capture_message_content_instrument
):
# Redo the instrumentation dance to be affected by the environment variable
OpenAIInstrumentor().uninstrument()
with mock.patch.dict("os.environ", {"OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT": "true"}):
OpenAIInstrumentor().instrument()

client = openai.OpenAI()

messages = [
Expand Down Expand Up @@ -373,7 +368,9 @@ def test_chat_multiple_choices_with_capture_message_content(

@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
@pytest.mark.vcr()
def test_chat_function_calling_with_tools(default_openai_env, trace_exporter, metrics_reader, logs_exporter):
def test_chat_function_calling_with_tools(
default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument
):
client = openai.OpenAI()

tools = [
Expand Down Expand Up @@ -476,12 +473,9 @@ def test_chat_function_calling_with_tools(default_openai_env, trace_exporter, me

@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
@pytest.mark.vcr()
def test_chat_tools_with_capture_message_content(default_openai_env, trace_exporter, logs_exporter, metrics_reader):
# Redo the instrumentation dance to be affected by the environment variable
OpenAIInstrumentor().uninstrument()
with mock.patch.dict("os.environ", {"OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT": "true"}):
OpenAIInstrumentor().instrument()

def test_chat_tools_with_capture_message_content(
default_openai_env, trace_exporter, logs_exporter, metrics_reader, capture_message_content_instrument
):
client = openai.OpenAI()

tools = [
Expand Down Expand Up @@ -587,15 +581,12 @@ def test_chat_tools_with_capture_message_content(default_openai_env, trace_expor

@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
@pytest.mark.integration
def test_chat_tools_with_capture_message_content_integration(trace_exporter, logs_exporter, metrics_reader):
def test_chat_tools_with_capture_message_content_integration(
trace_exporter, logs_exporter, metrics_reader, capture_message_content_instrument
):
client = get_integration_client()
model = os.getenv("TEST_CHAT_MODEL", TEST_CHAT_MODEL)

# Redo the instrumentation dance to be affected by the environment variable
OpenAIInstrumentor().uninstrument()
with mock.patch.dict("os.environ", {"OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT": "true"}):
OpenAIInstrumentor().instrument()

tools = [
{
"type": "function",
Expand Down Expand Up @@ -697,7 +688,7 @@ def test_chat_tools_with_capture_message_content_integration(trace_exporter, log


@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
def test_chat_connection_error(default_openai_env, trace_exporter, metrics_reader, logs_exporter):
def test_chat_connection_error(default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument):
client = openai.Client(base_url="http://localhost:9999/v5", api_key="not-read", max_retries=1)
messages = [
{
Expand Down Expand Up @@ -749,17 +740,11 @@ def test_chat_connection_error(default_openai_env, trace_exporter, metrics_reade

@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
@pytest.mark.integration
def test_chat_with_capture_message_content_integration(trace_exporter, logs_exporter, metrics_reader):
def test_chat_with_capture_message_content_integration(
trace_exporter, logs_exporter, metrics_reader, capture_message_content_instrument
):
model = os.getenv("TEST_CHAT_MODEL", TEST_CHAT_MODEL)

# Redo the instrumentation dance to be affected by the environment variable
OpenAIInstrumentor().uninstrument()
with mock.patch.dict(
"os.environ",
{"OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT": "true"},
):
OpenAIInstrumentor().instrument()

client = get_integration_client()

messages = [
Expand Down Expand Up @@ -825,14 +810,11 @@ def test_chat_with_capture_message_content_integration(trace_exporter, logs_expo

@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
@pytest.mark.vcr()
def test_chat_with_capture_message_content(default_openai_env, trace_exporter, logs_exporter, metrics_reader):
def test_chat_with_capture_message_content(
default_openai_env, trace_exporter, logs_exporter, metrics_reader, capture_message_content_instrument
):
client = openai.OpenAI()

# Redo the instrumentation dance to be affected by the environment variable
OpenAIInstrumentor().uninstrument()
with mock.patch.dict("os.environ", {"OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT": "true"}):
OpenAIInstrumentor().instrument()

messages = [
{
"role": "user",
Expand Down Expand Up @@ -897,13 +879,8 @@ def test_chat_with_capture_message_content(default_openai_env, trace_exporter, l
@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
@pytest.mark.vcr()
def test_chat_tools_with_followup_and_capture_message_content(
default_openai_env, trace_exporter, metrics_reader, logs_exporter
default_openai_env, trace_exporter, metrics_reader, logs_exporter, capture_message_content_instrument
):
# Redo the instrumentation dance to be affected by the environment variable
OpenAIInstrumentor().uninstrument()
with mock.patch.dict("os.environ", {"OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT": "true"}):
OpenAIInstrumentor().instrument()

client = openai.OpenAI()

tools = [
Expand Down Expand Up @@ -1069,7 +1046,7 @@ def test_chat_tools_with_followup_and_capture_message_content(
@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
@pytest.mark.asyncio
@pytest.mark.vcr()
async def test_chat_async(default_openai_env, trace_exporter, metrics_reader, logs_exporter):
async def test_chat_async(default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument):
client = openai.AsyncOpenAI()

messages = [
Expand Down Expand Up @@ -1136,13 +1113,8 @@ async def test_chat_async(default_openai_env, trace_exporter, metrics_reader, lo
@pytest.mark.asyncio
@pytest.mark.vcr()
async def test_chat_async_with_capture_message_content(
default_openai_env, trace_exporter, metrics_reader, logs_exporter
default_openai_env, trace_exporter, metrics_reader, logs_exporter, capture_message_content_instrument
):
# Redo the instrumentation dance to be affected by the environment variable
OpenAIInstrumentor().uninstrument()
with mock.patch.dict("os.environ", {"OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT": "true"}):
OpenAIInstrumentor().instrument()

client = openai.AsyncOpenAI()

messages = [
Expand Down Expand Up @@ -1209,14 +1181,11 @@ async def test_chat_async_with_capture_message_content(
@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
@pytest.mark.integration
@pytest.mark.asyncio
async def test_chat_async_with_capture_message_content_integration(trace_exporter, logs_exporter, metrics_reader):
async def test_chat_async_with_capture_message_content_integration(
trace_exporter, logs_exporter, metrics_reader, capture_message_content_instrument
):
model = os.getenv("TEST_CHAT_MODEL", TEST_CHAT_MODEL)

# Redo the instrumentation dance to be affected by the environment variable
OpenAIInstrumentor().uninstrument()
with mock.patch.dict("os.environ", {"OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT": "true"}):
OpenAIInstrumentor().instrument()

messages = [
{
"role": "user",
Expand Down Expand Up @@ -1284,13 +1253,8 @@ async def test_chat_async_with_capture_message_content_integration(trace_exporte
@pytest.mark.vcr()
@pytest.mark.asyncio
async def test_chat_async_tools_with_capture_message_content(
default_openai_env, trace_exporter, metrics_reader, logs_exporter
default_openai_env, trace_exporter, metrics_reader, logs_exporter, capture_message_content_instrument
):
# Redo the instrumentation dance to be affected by the environment variable
OpenAIInstrumentor().uninstrument()
with mock.patch.dict("os.environ", {"OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT": "true"}):
OpenAIInstrumentor().instrument()

client = openai.AsyncOpenAI()

tools = [
Expand Down Expand Up @@ -1396,7 +1360,7 @@ async def test_chat_async_tools_with_capture_message_content(

@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
@pytest.mark.vcr()
def test_chat_without_model_parameter(default_openai_env, trace_exporter, metrics_reader):
def test_chat_without_model_parameter(default_openai_env, trace_exporter, metrics_reader, instrument):
client = openai.OpenAI()

messages = [
Expand Down Expand Up @@ -1442,7 +1406,7 @@ def test_chat_without_model_parameter(default_openai_env, trace_exporter, metric

@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
@pytest.mark.vcr()
def test_chat_with_model_not_found(default_openai_env, trace_exporter, metrics_reader):
def test_chat_with_model_not_found(default_openai_env, trace_exporter, metrics_reader, instrument):
client = openai.OpenAI()

messages = [
Expand Down Expand Up @@ -1488,7 +1452,7 @@ def test_chat_with_model_not_found(default_openai_env, trace_exporter, metrics_r

@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
@pytest.mark.vcr()
def test_chat_exported_schema_version(default_openai_env, trace_exporter, metrics_reader):
def test_chat_exported_schema_version(default_openai_env, trace_exporter, metrics_reader, instrument):
client = openai.OpenAI()

messages = [
Expand All @@ -1515,13 +1479,8 @@ def test_chat_exported_schema_version(default_openai_env, trace_exporter, metric
@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
@pytest.mark.vcr()
def test_parse_response_format_json_object_with_capture_message_content(
default_openai_env, trace_exporter, metrics_reader, logs_exporter
default_openai_env, trace_exporter, metrics_reader, logs_exporter, capture_message_content_instrument
):
# Redo the instrumentation dance to be affected by the environment variable
OpenAIInstrumentor().uninstrument()
with mock.patch.dict("os.environ", {"OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT": "true"}):
OpenAIInstrumentor().instrument()

client = openai.OpenAI()

chat_input = """Provide up to 3 words explaining why 2 + 2 equals 4 in JSON format with a 'reason' key."""
Expand Down Expand Up @@ -1592,13 +1551,8 @@ class Reason(BaseModel):
@pytest.mark.skipif(not HAS_BETA_CHAT_COMPLETIONS, reason="beta completions added in 1.40.0, removed in 1.93.0")
@pytest.mark.vcr()
def test_parse_response_format_structured_output_with_capture_message_content(
default_openai_env, trace_exporter, metrics_reader, logs_exporter
default_openai_env, trace_exporter, metrics_reader, logs_exporter, capture_message_content_instrument
):
# Redo the instrumentation dance to be affected by the environment variable
OpenAIInstrumentor().uninstrument()
with mock.patch.dict("os.environ", {"OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT": "true"}):
OpenAIInstrumentor().instrument()

client = openai.OpenAI()

chat_input = """Provide up to 3 words explaining why 2 + 2 equals 4 in JSON format with a 'reason' key."""
Expand Down
Loading
Loading