Skip to content

Commit 4584a47

Browse files
committed
align parse() wrapping with positional args after open-telemetry#4445 rebase
1 parent 1b63914 commit 4584a47

4 files changed

Lines changed: 62 additions & 26 deletions

File tree

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,10 @@ def _instrument(self, **kwargs):
200200
self._parse_supported = _is_parse_supported()
201201
if self._parse_supported:
202202
wrap_function_wrapper(
203-
module="openai.resources.chat.completions",
204-
name="Completions.parse",
205-
wrapper=(
206-
chat_completions_create_v_new(handler, content_mode)
203+
"openai.resources.chat.completions",
204+
"Completions.parse",
205+
(
206+
chat_completions_create_v_new(handler)
207207
if latest_experimental_enabled
208208
else chat_completions_create_v_old(
209209
tracer, logger, instruments, is_content_enabled()
@@ -212,10 +212,10 @@ def _instrument(self, **kwargs):
212212
)
213213

214214
wrap_function_wrapper(
215-
module="openai.resources.chat.completions",
216-
name="AsyncCompletions.parse",
217-
wrapper=(
218-
async_chat_completions_create_v_new(handler, content_mode)
215+
"openai.resources.chat.completions",
216+
"AsyncCompletions.parse",
217+
(
218+
async_chat_completions_create_v_new(handler)
219219
if latest_experimental_enabled
220220
else async_chat_completions_create_v_old(
221221
tracer, logger, instruments, is_content_enabled()

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

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,9 @@ def choice_to_event(choice, capture_content):
155155
if choice.message:
156156
message = {
157157
"role": (
158-
choice.message.role if choice.message and choice.message.role else None
158+
choice.message.role
159+
if choice.message and choice.message.role
160+
else None
159161
)
160162
}
161163
tool_calls = extract_tool_calls(choice.message, capture_content)
@@ -240,10 +242,14 @@ def get_llm_request_attributes(
240242
if operation_name == GenAIAttributes.GenAiOperationNameValues.CHAT.value:
241243
attributes.update(
242244
{
243-
GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE: kwargs.get("temperature"),
245+
GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE: kwargs.get(
246+
"temperature"
247+
),
244248
GenAIAttributes.GEN_AI_REQUEST_TOP_P: kwargs.get("p")
245249
or kwargs.get("top_p"),
246-
GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS: kwargs.get("max_tokens"),
250+
GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS: kwargs.get(
251+
"max_tokens"
252+
),
247253
GenAIAttributes.GEN_AI_REQUEST_PRESENCE_PENALTY: kwargs.get(
248254
"presence_penalty"
249255
),
@@ -257,12 +263,16 @@ def get_llm_request_attributes(
257263
if (choice_count := kwargs.get("n")) is not None:
258264
# Only add non default, meaningful values
259265
if isinstance(choice_count, int) and choice_count != 1:
260-
attributes[GenAIAttributes.GEN_AI_REQUEST_CHOICE_COUNT] = choice_count
266+
attributes[GenAIAttributes.GEN_AI_REQUEST_CHOICE_COUNT] = (
267+
choice_count
268+
)
261269

262270
if (stop_sequences := kwargs.get("stop")) is not None:
263271
if isinstance(stop_sequences, str):
264272
stop_sequences = [stop_sequences]
265-
attributes[GenAIAttributes.GEN_AI_REQUEST_STOP_SEQUENCES] = stop_sequences
273+
attributes[GenAIAttributes.GEN_AI_REQUEST_STOP_SEQUENCES] = (
274+
stop_sequences
275+
)
266276

267277
request_response_format_attr_key = (
268278
GenAIAttributes.GEN_AI_OUTPUT_TYPE
@@ -308,7 +318,10 @@ def get_llm_request_attributes(
308318
)
309319

310320
# Add embeddings-specific attributes
311-
elif operation_name == GenAIAttributes.GenAiOperationNameValues.EMBEDDINGS.value:
321+
elif (
322+
operation_name
323+
== GenAIAttributes.GenAiOperationNameValues.EMBEDDINGS.value
324+
):
312325
# Add embedding dimensions if specified
313326
if (dimensions := kwargs.get("dimensions")) is not None:
314327
# TODO: move to GEN_AI_EMBEDDINGS_DIMENSION_COUNT when 1.39.0 is baseline
@@ -363,7 +376,9 @@ def create_chat_invocation(
363376
GenAIAttributes.GEN_AI_REQUEST_CHOICE_COUNT
364377
] = choice_count
365378

366-
if (response_format := get_value(kwargs.get("response_format"))) is not None:
379+
if (
380+
response_format := get_value(kwargs.get("response_format"))
381+
) is not None:
367382
# response_format may be string, object with a string in the `type` key,
368383
# or a type (e.g. Pydantic model class used with parse())
369384
if isinstance(response_format, type):
@@ -414,13 +429,16 @@ def get_value(v: Any):
414429
def handle_span_exception(span, error: BaseException):
415430
span.set_status(Status(StatusCode.ERROR, str(error)))
416431
if span.is_recording():
417-
span.set_attribute(ErrorAttributes.ERROR_TYPE, type(error).__qualname__)
432+
span.set_attribute(
433+
ErrorAttributes.ERROR_TYPE, type(error).__qualname__
434+
)
418435
span.end()
419436

420437

421438
def _is_text_part(content: Any) -> bool:
422439
return isinstance(content, str) or (
423-
isinstance(content, Iterable) and all(isinstance(part, str) for part in content)
440+
isinstance(content, Iterable)
441+
and all(isinstance(part, str) for part in content)
424442
)
425443

426444

@@ -471,7 +489,9 @@ def extract_tool_calls_new(tool_calls) -> list[ToolCallRequest]:
471489
arguments = arguments_str
472490

473491
# TODO: support custom
474-
parts.append(ToolCallRequest(id=call_id, name=func_name, arguments=arguments))
492+
parts.append(
493+
ToolCallRequest(id=call_id, name=func_name, arguments=arguments)
494+
)
475495
return parts
476496

477497

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,18 @@ async def test_async_structured_output_with_content(
8282
)
8383
assert_messages_attribute(
8484
spans[0].attributes["gen_ai.output.messages"],
85-
format_simple_expected_output_message(response.choices[0].message.content),
85+
format_simple_expected_output_message(
86+
response.choices[0].message.content
87+
),
8688
)
8789
else:
8890
logs = log_exporter.get_finished_logs()
8991
assert len(logs) == 2
9092

9193
user_message = {"content": STRUCTURED_OUTPUT_PROMPT[0]["content"]}
92-
assert_message_in_logs(logs[0], "gen_ai.user.message", user_message, spans[0])
94+
assert_message_in_logs(
95+
logs[0], "gen_ai.user.message", user_message, spans[0]
96+
)
9397

9498
choice_event = {
9599
"index": 0,
@@ -99,7 +103,9 @@ async def test_async_structured_output_with_content(
99103
"content": response.choices[0].message.content,
100104
},
101105
}
102-
assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0])
106+
assert_message_in_logs(
107+
logs[1], "gen_ai.choice", choice_event, spans[0]
108+
)
103109

104110

105111
@pytest.mark.asyncio()
@@ -157,4 +163,6 @@ async def test_async_structured_output_no_content(
157163
"finish_reason": "stop",
158164
"message": {"role": "assistant"},
159165
}
160-
assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0])
166+
assert_message_in_logs(
167+
logs[1], "gen_ai.choice", choice_event, spans[0]
168+
)

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,18 @@ def test_structured_output_with_content(
7575
)
7676
assert_messages_attribute(
7777
spans[0].attributes["gen_ai.output.messages"],
78-
format_simple_expected_output_message(response.choices[0].message.content),
78+
format_simple_expected_output_message(
79+
response.choices[0].message.content
80+
),
7981
)
8082
else:
8183
logs = log_exporter.get_finished_logs()
8284
assert len(logs) == 2
8385

8486
user_message = {"content": STRUCTURED_OUTPUT_PROMPT[0]["content"]}
85-
assert_message_in_logs(logs[0], "gen_ai.user.message", user_message, spans[0])
87+
assert_message_in_logs(
88+
logs[0], "gen_ai.user.message", user_message, spans[0]
89+
)
8690

8791
choice_event = {
8892
"index": 0,
@@ -92,7 +96,9 @@ def test_structured_output_with_content(
9296
"content": response.choices[0].message.content,
9397
},
9498
}
95-
assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0])
99+
assert_message_in_logs(
100+
logs[1], "gen_ai.choice", choice_event, spans[0]
101+
)
96102

97103

98104
def test_structured_output_no_content(
@@ -145,4 +151,6 @@ def test_structured_output_no_content(
145151
"finish_reason": "stop",
146152
"message": {"role": "assistant"},
147153
}
148-
assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0])
154+
assert_message_in_logs(
155+
logs[1], "gen_ai.choice", choice_event, spans[0]
156+
)

0 commit comments

Comments
 (0)