diff --git a/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/conftest.py b/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/conftest.py index bffdc8c..772ad50 100644 --- a/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/conftest.py +++ b/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/conftest.py @@ -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() diff --git a/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_beta_chat_completions.py b/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_beta_chat_completions.py index f9991ba..4d20e6c 100644 --- a/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_beta_chat_completions.py +++ b/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_beta_chat_completions.py @@ -20,12 +20,10 @@ from copy import deepcopy from dataclasses import dataclass from typing import List, Optional -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, @@ -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 = [ @@ -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 = [ @@ -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 = [ @@ -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 = [ @@ -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 = [ @@ -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 = [ @@ -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", @@ -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 = [ { @@ -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 = [ @@ -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", @@ -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 = [ @@ -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 = [ @@ -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 = [ @@ -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", @@ -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 = [ @@ -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 = [ @@ -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 = [ @@ -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 = [ @@ -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.""" @@ -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.""" diff --git a/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_chat_completions.py b/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_chat_completions.py index c1a3e8a..6c5ed55 100644 --- a/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_chat_completions.py +++ b/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_chat_completions.py @@ -19,13 +19,11 @@ import re from dataclasses import dataclass from typing import List, Optional -from unittest import mock import openai import pytest from opentelemetry._events import Event 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, @@ -68,7 +66,7 @@ @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 = [ @@ -132,7 +130,7 @@ def test_chat(default_openai_env, trace_exporter, metrics_reader, logs_exporter) @pytest.mark.vcr() -def test_chat_n_1(default_openai_env, trace_exporter, metrics_reader, logs_exporter): +def test_chat_n_1(default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument): client = openai.OpenAI() messages = [ @@ -155,7 +153,7 @@ def test_chat_n_1(default_openai_env, trace_exporter, metrics_reader, logs_expor @pytest.mark.skipif(OPENAI_VERSION < (1, 8, 0), reason="LegacyAPIResponse available") @pytest.mark.vcr() -def test_chat_with_raw_response(default_openai_env, trace_exporter, metrics_reader, logs_exporter): +def test_chat_with_raw_response(default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument): client = openai.OpenAI() messages = [ @@ -220,7 +218,9 @@ def test_chat_with_raw_response(default_openai_env, trace_exporter, metrics_read @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 = [ @@ -293,7 +293,7 @@ def test_chat_with_developer_role_message(default_openai_env, trace_exporter, me @pytest.mark.skipif(OPENAI_VERSION < (1, 35, 0), reason="service tier added in 1.35.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 = [ @@ -382,7 +382,9 @@ def test_chat_all_the_client_options(default_openai_env, trace_exporter, metrics @pytest.mark.skipif(OPENAI_VERSION < (1, 35, 0), reason="service tier added in 1.35.0") @pytest.mark.vcr() -def test_chat_all_the_client_options_not_given(default_openai_env, trace_exporter, metrics_reader, logs_exporter): +def test_chat_all_the_client_options_not_given( + default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument +): client = openai.OpenAI() messages = [ @@ -462,13 +464,8 @@ def test_chat_all_the_client_options_not_given(default_openai_env, trace_exporte @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 = [ @@ -535,7 +532,9 @@ def test_chat_multiple_choices_with_capture_message_content( @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 = [ @@ -636,12 +635,9 @@ def test_chat_function_calling_with_tools(default_openai_env, trace_exporter, me @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 = [ @@ -745,15 +741,12 @@ def test_chat_tools_with_capture_message_content(default_openai_env, trace_expor @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", @@ -853,7 +846,7 @@ def test_chat_tools_with_capture_message_content_integration(trace_exporter, log ) -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 = [ { @@ -904,17 +897,11 @@ def test_chat_connection_error(default_openai_env, trace_exporter, metrics_reade @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 = [ @@ -979,14 +966,11 @@ def test_chat_with_capture_message_content_integration(trace_exporter, logs_expo @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", @@ -1049,7 +1033,7 @@ def test_chat_with_capture_message_content(default_openai_env, trace_exporter, l @pytest.mark.vcr() -def test_chat_stream(default_openai_env, trace_exporter, metrics_reader, logs_exporter): +def test_chat_stream(default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument): client = openai.OpenAI() messages = [ @@ -1104,7 +1088,9 @@ def test_chat_stream(default_openai_env, trace_exporter, metrics_reader, logs_ex @pytest.mark.vcr() -def test_chat_stream_with_context_manager(default_openai_env, trace_exporter, metrics_reader, logs_exporter): +def test_chat_stream_with_context_manager( + default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument +): client = openai.OpenAI() messages = [ @@ -1161,7 +1147,7 @@ def test_chat_stream_with_context_manager(default_openai_env, trace_exporter, me @pytest.mark.skipif(OPENAI_VERSION < (1, 8, 0), reason="LegacyAPIResponse available") @pytest.mark.vcr() -def test_chat_stream_with_raw_response(default_openai_env, trace_exporter, metrics_reader, logs_exporter): +def test_chat_stream_with_raw_response(default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument): client = openai.OpenAI() messages = [ @@ -1223,7 +1209,9 @@ def test_chat_stream_with_raw_response(default_openai_env, trace_exporter, metri @pytest.mark.skipif(OPENAI_VERSION < (1, 35, 0), reason="service tier added in 1.35.0") @pytest.mark.vcr() -def test_chat_stream_all_the_client_options(default_openai_env, trace_exporter, metrics_reader, logs_exporter): +def test_chat_stream_all_the_client_options( + default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument +): client = openai.OpenAI() messages = [ @@ -1304,7 +1292,9 @@ def test_chat_stream_all_the_client_options(default_openai_env, trace_exporter, @pytest.mark.skipif(OPENAI_VERSION < (1, 26, 0), reason="stream_options added in 1.26.0") @pytest.mark.vcr() -def test_chat_stream_with_include_usage_option(default_openai_env, trace_exporter, metrics_reader, logs_exporter): +def test_chat_stream_with_include_usage_option( + default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument +): client = openai.OpenAI() messages = [ @@ -1373,18 +1363,10 @@ def test_chat_stream_with_include_usage_option(default_openai_env, trace_exporte @pytest.mark.skipif(OPENAI_VERSION < (1, 26, 0), reason="stream_options added in 1.26.0") @pytest.mark.integration def test_chat_stream_with_include_usage_option_and_capture_message_content_integration( - default_openai_env, trace_exporter, logs_exporter, metrics_reader + default_openai_env, 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 = [ @@ -1456,13 +1438,8 @@ def test_chat_stream_with_include_usage_option_and_capture_message_content_integ @pytest.mark.vcr() def test_chat_stream_with_tools_and_capture_message_content( - default_openai_env, trace_exporter, logs_exporter, metrics_reader + default_openai_env, trace_exporter, logs_exporter, metrics_reader, 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 = [ @@ -1563,13 +1540,8 @@ def test_chat_stream_with_tools_and_capture_message_content( @pytest.mark.vcr() def test_chat_stream_with_parallel_tools_and_capture_message_content( - default_openai_env, trace_exporter, logs_exporter, metrics_reader + default_openai_env, trace_exporter, logs_exporter, metrics_reader, 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 = [ @@ -1657,13 +1629,8 @@ def test_chat_stream_with_parallel_tools_and_capture_message_content( @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 = [ @@ -1823,7 +1790,7 @@ def test_chat_tools_with_followup_and_capture_message_content( @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 = [ @@ -1889,7 +1856,9 @@ async def test_chat_async(default_openai_env, trace_exporter, metrics_reader, lo @pytest.mark.skipif(OPENAI_VERSION < (1, 8, 0), reason="LegacyAPIResponse available") @pytest.mark.asyncio @pytest.mark.vcr() -async def test_chat_async_with_raw_response(default_openai_env, trace_exporter, metrics_reader, logs_exporter): +async def test_chat_async_with_raw_response( + default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument +): client = openai.AsyncOpenAI() messages = [ @@ -1956,13 +1925,8 @@ async def test_chat_async_with_raw_response(default_openai_env, trace_exporter, @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 = [ @@ -2028,14 +1992,11 @@ async def test_chat_async_with_capture_message_content( @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", @@ -2101,7 +2062,7 @@ async def test_chat_async_with_capture_message_content_integration(trace_exporte @pytest.mark.vcr() @pytest.mark.asyncio -async def test_chat_async_stream(default_openai_env, trace_exporter, metrics_reader, logs_exporter): +async def test_chat_async_stream(default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument): client = openai.AsyncOpenAI() messages = [ @@ -2158,7 +2119,7 @@ async def test_chat_async_stream(default_openai_env, trace_exporter, metrics_rea @pytest.mark.vcr() @pytest.mark.asyncio async def test_chat_async_stream_with_context_manager( - default_openai_env, trace_exporter, metrics_reader, logs_exporter + default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument ): client = openai.AsyncOpenAI() @@ -2219,7 +2180,9 @@ async def test_chat_async_stream_with_context_manager( @pytest.mark.skipif(OPENAI_VERSION < (1, 8, 0), reason="LegacyAPIResponse available") @pytest.mark.vcr() @pytest.mark.asyncio -async def test_chat_async_stream_with_raw_response(default_openai_env, trace_exporter, metrics_reader, logs_exporter): +async def test_chat_async_stream_with_raw_response( + default_openai_env, trace_exporter, metrics_reader, logs_exporter, instrument +): client = openai.AsyncOpenAI() messages = [ @@ -2282,13 +2245,8 @@ async def test_chat_async_stream_with_raw_response(default_openai_env, trace_exp @pytest.mark.vcr() @pytest.mark.asyncio async def test_chat_async_stream_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 = [ @@ -2351,13 +2309,8 @@ async def test_chat_async_stream_with_capture_message_content( @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 = [ @@ -2461,7 +2414,7 @@ async def test_chat_async_tools_with_capture_message_content( @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 = [ @@ -2508,7 +2461,7 @@ def test_chat_without_model_parameter(default_openai_env, trace_exporter, metric @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 = [ @@ -2553,7 +2506,7 @@ def test_chat_with_model_not_found(default_openai_env, trace_exporter, metrics_r @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 = [ diff --git a/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_embeddings.py b/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_embeddings.py index 3c1b395..db2a769 100644 --- a/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_embeddings.py +++ b/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_embeddings.py @@ -46,7 +46,7 @@ @pytest.mark.vcr() -def test_embeddings(default_openai_env, trace_exporter, metrics_reader): +def test_embeddings(default_openai_env, trace_exporter, metrics_reader, instrument): client = openai.OpenAI() response = client.embeddings.create(model=TEST_EMBEDDINGS_MODEL, input=[TEST_EMBEDDINGS_INPUT]) @@ -85,7 +85,7 @@ def test_embeddings(default_openai_env, trace_exporter, metrics_reader): @pytest.mark.vcr() -def test_embeddings_all_the_client_options(default_openai_env, trace_exporter, metrics_reader): +def test_embeddings_all_the_client_options(default_openai_env, trace_exporter, metrics_reader, instrument): client = openai.OpenAI() response = client.embeddings.create( @@ -134,7 +134,7 @@ def test_embeddings_all_the_client_options(default_openai_env, trace_exporter, m @pytest.mark.skipif(OPENAI_VERSION < (1, 13, 4), reason="openai.NOT_GIVEN not available") @pytest.mark.vcr() -def test_embeddings_all_the_client_options_not_given(default_openai_env, trace_exporter, metrics_reader): +def test_embeddings_all_the_client_options_not_given(default_openai_env, trace_exporter, metrics_reader, instrument): client = openai.OpenAI() response = client.embeddings.create( @@ -181,7 +181,7 @@ def test_embeddings_all_the_client_options_not_given(default_openai_env, trace_e @pytest.mark.integration -def test_embeddings_all_the_client_options_integration(trace_exporter, metrics_reader): +def test_embeddings_all_the_client_options_integration(trace_exporter, metrics_reader, instrument): client = get_integration_client() model = os.getenv("TEST_EMBEDDINGS_MODEL", TEST_EMBEDDINGS_MODEL) @@ -223,7 +223,7 @@ def test_embeddings_all_the_client_options_integration(trace_exporter, metrics_r ) -def test_embeddings_connection_error(trace_exporter, metrics_reader): +def test_embeddings_connection_error(trace_exporter, metrics_reader, instrument): client = openai.Client(base_url="http://localhost:9999/v5", api_key="text-embedding-3-large", max_retries=1) with pytest.raises(Exception): @@ -263,7 +263,7 @@ def test_embeddings_connection_error(trace_exporter, metrics_reader): @pytest.mark.vcr(cassette_name="test_embeddings.yaml") @pytest.mark.asyncio -async def test_embeddings_async(default_openai_env, trace_exporter, metrics_reader): +async def test_embeddings_async(default_openai_env, trace_exporter, metrics_reader, instrument): client = openai.AsyncOpenAI() response = await client.embeddings.create(model=TEST_EMBEDDINGS_MODEL, input=[TEST_EMBEDDINGS_INPUT]) @@ -309,7 +309,7 @@ async def test_embeddings_async(default_openai_env, trace_exporter, metrics_read @pytest.mark.vcr(cassette_name="test_embeddings_all_the_client_options.yaml") @pytest.mark.asyncio -async def test_embeddings_async_all_the_client_options(default_openai_env, trace_exporter, metrics_reader): +async def test_embeddings_async_all_the_client_options(default_openai_env, trace_exporter, metrics_reader, instrument): client = openai.AsyncOpenAI() response = await client.embeddings.create( @@ -358,7 +358,7 @@ async def test_embeddings_async_all_the_client_options(default_openai_env, trace @pytest.mark.integration @pytest.mark.asyncio -async def test_embeddings_async_all_the_client_options_integration(trace_exporter, metrics_reader): +async def test_embeddings_async_all_the_client_options_integration(trace_exporter, metrics_reader, instrument): client = get_integration_async_client() model = os.getenv("TEST_EMBEDDINGS_MODEL", TEST_EMBEDDINGS_MODEL) @@ -409,7 +409,7 @@ async def test_embeddings_async_all_the_client_options_integration(trace_exporte @pytest.mark.asyncio -async def test_embeddings_async_connection_error(default_openai_env, trace_exporter, metrics_reader): +async def test_embeddings_async_connection_error(default_openai_env, trace_exporter, metrics_reader, instrument): client = openai.AsyncOpenAI(base_url="http://localhost:9999/v5", api_key="unused", max_retries=1) with pytest.raises(Exception): @@ -449,7 +449,7 @@ async def test_embeddings_async_connection_error(default_openai_env, trace_expor @pytest.mark.vcr() -def test_embeddings_without_model_parameter(default_openai_env, trace_exporter, metrics_reader): +def test_embeddings_without_model_parameter(default_openai_env, trace_exporter, metrics_reader, instrument): client = openai.OpenAI() with pytest.raises(TypeError, match=re.escape("create() missing 1 required keyword-only argument: 'model'")): @@ -485,7 +485,7 @@ def test_embeddings_without_model_parameter(default_openai_env, trace_exporter, @pytest.mark.vcr() -def test_embeddings_model_not_found(default_openai_env, trace_exporter, metrics_reader): +def test_embeddings_model_not_found(default_openai_env, trace_exporter, metrics_reader, instrument): # force a timeout to don't slow down tests client = openai.OpenAI(timeout=1) diff --git a/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_instrumentor.py b/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_instrumentor.py index 72d7064..c28c58e 100644 --- a/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_instrumentor.py +++ b/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_instrumentor.py @@ -18,13 +18,14 @@ def test_capture_message_content_false_by_default(instrument): - instrument.uninstrument() assert not instrument.capture_message_content -def test_can_override_capture_message_content_programmatically(instrument): - instrument.uninstrument() +def test_can_override_capture_message_content_programmatically(monkeypatch): + monkeypatch.delenv("OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT", raising=False) instrumentor = OpenAIInstrumentor() - instrumentor.instrument(capture_message_content=True) - assert instrumentor.capture_message_content - instrumentor.uninstrument() + try: + instrumentor.instrument(capture_message_content=True) + assert instrumentor.capture_message_content + finally: + instrumentor.uninstrument()