Skip to content

Commit a217ce3

Browse files
wip: removed unwanted truthiness checks and simplified the test suite.
1 parent 27011f2 commit a217ce3

2 files changed

Lines changed: 26 additions & 65 deletions

File tree

instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/response_extractors.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,9 @@ def _extract_output_parts(
257257

258258
parts: list[Text] = []
259259
for block in content_blocks:
260-
if block.type == "output_text" and block.text:
260+
if block.type == "output_text" and block.text is not None:
261261
parts.append(Text(content=block.text))
262-
elif block.type == "refusal" and block.refusal:
262+
elif block.type == "refusal" and block.refusal is not None:
263263
parts.append(Text(content=block.refusal))
264264
return parts
265265

@@ -292,7 +292,7 @@ def _extract_output_messages_from_model(
292292

293293
messages.append(
294294
OutputMessage(
295-
role=item.role or "assistant",
295+
role=item.role if item.role is not None else "assistant",
296296
parts=_extract_output_parts(item.content),
297297
finish_reason=finish_reason,
298298
)
@@ -360,7 +360,11 @@ def _set_invocation_usage_attributes(
360360
else:
361361
invocation.output_tokens = usage.completion_tokens
362362

363-
details = usage.input_tokens_details or usage.prompt_tokens_details
363+
details = (
364+
usage.input_tokens_details
365+
if usage.input_tokens_details is not None
366+
else usage.prompt_tokens_details
367+
)
364368
if details is None:
365369
return
366370

@@ -391,10 +395,10 @@ def _set_invocation_response_attributes(
391395
if validated_result is None:
392396
return
393397

394-
if validated_result.model:
398+
if validated_result.model is not None:
395399
invocation.response_model_name = validated_result.model
396400

397-
if validated_result.id:
401+
if validated_result.id is not None:
398402
invocation.response_id = validated_result.id
399403

400404
if validated_result.service_tier is not None:

instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_response_extractors.py

Lines changed: 16 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -12,68 +12,25 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import builtins
16-
import functools
17-
import importlib.util
1815
import logging
19-
from pathlib import Path
2016
from types import SimpleNamespace
2117
from unittest import mock
2218

2319
import pytest
2420

21+
from opentelemetry.instrumentation.openai_v2 import response_extractors
2522
from opentelemetry.semconv._incubating.attributes import (
2623
openai_attributes as OpenAIAttributes,
2724
)
2825
from opentelemetry.util.genai.types import LLMInvocation
2926

30-
_MODULE_PATH = (
31-
Path(__file__).resolve().parents[1]
32-
/ "src"
33-
/ "opentelemetry"
34-
/ "instrumentation"
35-
/ "openai_v2"
36-
/ "response_extractors.py"
37-
)
38-
39-
40-
def _load_module(block_genai_types_import=False):
41-
spec = importlib.util.spec_from_file_location(
42-
"test_response_extractors_module", _MODULE_PATH
43-
)
44-
assert spec is not None and spec.loader is not None
45-
module = importlib.util.module_from_spec(spec)
46-
47-
if not block_genai_types_import:
48-
spec.loader.exec_module(module)
49-
return module
50-
51-
original_import = builtins.__import__
52-
53-
def _patched_import(
54-
name, globalns=None, localns=None, fromlist=(), level=0
55-
):
56-
if name == "opentelemetry.util.genai.types":
57-
raise ImportError("simulated missing genai types")
58-
return original_import(name, globalns, localns, fromlist, level)
59-
60-
with mock.patch("builtins.__import__", side_effect=_patched_import):
61-
spec.loader.exec_module(module)
62-
return module
63-
64-
65-
@functools.lru_cache(maxsize=None)
66-
def _module(block_genai_types_import=False):
67-
return _load_module(block_genai_types_import)
68-
69-
7027
def _validate_compat_model(loaded_module, model_type, value):
7128
return loaded_module._validate_model(model_type, value, "test")
7229

7330

7431
@pytest.fixture(scope="module", name="loaded_module")
7532
def _loaded_module_fixture():
76-
return _module()
33+
return response_extractors
7734

7835

7936
@pytest.fixture(
@@ -218,22 +175,22 @@ def test_extract_output_type_handles_text_format_mapping(loaded_module):
218175
assert loaded_module._extract_output_type({"text": "plain"}) is None
219176

220177

221-
def test_extractors_handle_missing_genai_types_import():
222-
module = _module(block_genai_types_import=True)
223-
224-
assert module.Text is None
225-
assert module.InputMessage is None
226-
assert module.OutputMessage is None
227-
assert module._extract_system_instruction({"instructions": "hi"}) == []
228-
assert module._extract_input_messages({"input": "hi"}) == []
229-
assert (
230-
module._extract_output_messages(
231-
SimpleNamespace(
232-
output=[SimpleNamespace(type="message", content=[])]
178+
def test_extractors_handle_missing_genai_types_import(loaded_module):
179+
with mock.patch.object(loaded_module, "Text", None), mock.patch.object(
180+
loaded_module, "InputMessage", None
181+
), mock.patch.object(loaded_module, "OutputMessage", None):
182+
assert loaded_module._extract_system_instruction(
183+
{"instructions": "hi"}
184+
) == []
185+
assert loaded_module._extract_input_messages({"input": "hi"}) == []
186+
assert (
187+
loaded_module._extract_output_messages(
188+
SimpleNamespace(
189+
output=[SimpleNamespace(type="message", content=[])]
190+
)
233191
)
192+
== []
234193
)
235-
== []
236-
)
237194

238195

239196
def test_set_invocation_response_attributes_populates_usage_and_metadata(

0 commit comments

Comments
 (0)