opentelemetry-instrumentation-openai 0.10.3__tar.gz → 0.11.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of opentelemetry-instrumentation-openai might be problematic. Click here for more details.

Files changed (13) hide show
  1. {opentelemetry_instrumentation_openai-0.10.3 → opentelemetry_instrumentation_openai-0.11.2}/PKG-INFO +2 -2
  2. {opentelemetry_instrumentation_openai-0.10.3 → opentelemetry_instrumentation_openai-0.11.2}/opentelemetry/instrumentation/openai/shared/__init__.py +3 -1
  3. {opentelemetry_instrumentation_openai-0.10.3 → opentelemetry_instrumentation_openai-0.11.2}/opentelemetry/instrumentation/openai/shared/completion_wrappers.py +41 -10
  4. opentelemetry_instrumentation_openai-0.11.2/opentelemetry/instrumentation/openai/version.py +1 -0
  5. {opentelemetry_instrumentation_openai-0.10.3 → opentelemetry_instrumentation_openai-0.11.2}/pyproject.toml +9 -2
  6. opentelemetry_instrumentation_openai-0.10.3/opentelemetry/instrumentation/openai/version.py +0 -1
  7. {opentelemetry_instrumentation_openai-0.10.3 → opentelemetry_instrumentation_openai-0.11.2}/README.md +0 -0
  8. {opentelemetry_instrumentation_openai-0.10.3 → opentelemetry_instrumentation_openai-0.11.2}/opentelemetry/instrumentation/openai/__init__.py +0 -0
  9. {opentelemetry_instrumentation_openai-0.10.3 → opentelemetry_instrumentation_openai-0.11.2}/opentelemetry/instrumentation/openai/shared/chat_wrappers.py +0 -0
  10. {opentelemetry_instrumentation_openai-0.10.3 → opentelemetry_instrumentation_openai-0.11.2}/opentelemetry/instrumentation/openai/shared/embeddings_wrappers.py +0 -0
  11. {opentelemetry_instrumentation_openai-0.10.3 → opentelemetry_instrumentation_openai-0.11.2}/opentelemetry/instrumentation/openai/utils.py +0 -0
  12. {opentelemetry_instrumentation_openai-0.10.3 → opentelemetry_instrumentation_openai-0.11.2}/opentelemetry/instrumentation/openai/v0/__init__.py +0 -0
  13. {opentelemetry_instrumentation_openai-0.10.3 → opentelemetry_instrumentation_openai-0.11.2}/opentelemetry/instrumentation/openai/v1/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: opentelemetry-instrumentation-openai
3
- Version: 0.10.3
3
+ Version: 0.11.2
4
4
  Summary: OpenTelemetry OpenAI instrumentation
5
5
  License: Apache-2.0
6
6
  Author: Gal Kleinman
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3.11
14
14
  Classifier: Programming Language :: Python :: 3.12
15
15
  Requires-Dist: opentelemetry-api (>=1.22.0,<2.0.0)
16
16
  Requires-Dist: opentelemetry-instrumentation (==0.43b0)
17
- Requires-Dist: opentelemetry-semantic-conventions-ai (>=0.0.19,<0.0.20)
17
+ Requires-Dist: opentelemetry-semantic-conventions-ai (>=0.0.20,<0.0.21)
18
18
  Description-Content-Type: text/markdown
19
19
 
20
20
  # OpenTelemetry OpenAI Instrumentation
@@ -131,7 +131,9 @@ def _set_response_attributes(span, response):
131
131
 
132
132
  def is_streaming_response(response):
133
133
  if is_openai_v1():
134
- return isinstance(response, openai.Stream)
134
+ return isinstance(response, openai.Stream) or isinstance(
135
+ response, openai.AsyncStream
136
+ )
135
137
 
136
138
  return isinstance(response, types.GeneratorType) or isinstance(
137
139
  response, types.AsyncGeneratorType
@@ -5,10 +5,7 @@ from opentelemetry import context as context_api
5
5
  from opentelemetry.semconv.ai import SpanAttributes, LLMRequestTypeValues
6
6
 
7
7
  from opentelemetry.instrumentation.utils import _SUPPRESS_INSTRUMENTATION_KEY
8
- from opentelemetry.instrumentation.openai.utils import (
9
- _with_tracer_wrapper,
10
- start_as_current_span_async,
11
- )
8
+ from opentelemetry.instrumentation.openai.utils import _with_tracer_wrapper
12
9
  from opentelemetry.instrumentation.openai.shared import (
13
10
  _set_request_attributes,
14
11
  _set_span_attribute,
@@ -60,17 +57,23 @@ async def acompletion_wrapper(tracer, wrapped, instance, args, kwargs):
60
57
  if context_api.get_value(_SUPPRESS_INSTRUMENTATION_KEY):
61
58
  return wrapped(*args, **kwargs)
62
59
 
63
- async with start_as_current_span_async(
64
- tracer=tracer,
60
+ span = tracer.start_span(
65
61
  name=SPAN_NAME,
66
62
  kind=SpanKind.CLIENT,
67
63
  attributes={SpanAttributes.LLM_REQUEST_TYPE: LLM_REQUEST_TYPE.value},
68
- ) as span:
69
- _handle_request(span, kwargs)
70
- response = await wrapped(*args, **kwargs)
64
+ )
65
+
66
+ _handle_request(span, kwargs)
67
+ response = await wrapped(*args, **kwargs)
68
+
69
+ if is_streaming_response(response):
70
+ # span will be closed after the generator is done
71
+ return _abuild_from_streaming_response(span, response)
72
+ else:
71
73
  _handle_response(response, span)
72
74
 
73
- return response
75
+ span.end()
76
+ return response
74
77
 
75
78
 
76
79
  def _handle_request(span, kwargs):
@@ -148,3 +151,31 @@ def _build_from_streaming_response(span, response):
148
151
 
149
152
  span.set_status(Status(StatusCode.OK))
150
153
  span.end()
154
+
155
+
156
+ async def _abuild_from_streaming_response(span, response):
157
+ complete_response = {"choices": [], "model": ""}
158
+ async for item in response:
159
+ item_to_yield = item
160
+ if is_openai_v1():
161
+ item = model_as_dict(item)
162
+
163
+ for choice in item.get("choices"):
164
+ index = choice.get("index")
165
+ if len(complete_response.get("choices")) <= index:
166
+ complete_response["choices"].append({"index": index, "text": ""})
167
+ complete_choice = complete_response.get("choices")[index]
168
+ if choice.get("finish_reason"):
169
+ complete_choice["finish_reason"] = choice.get("finish_reason")
170
+
171
+ complete_choice["text"] += choice.get("text")
172
+
173
+ yield item_to_yield
174
+
175
+ _set_response_attributes(span, complete_response)
176
+
177
+ if should_send_prompts():
178
+ _set_completions(span, complete_response.get("choices"))
179
+
180
+ span.set_status(Status(StatusCode.OK))
181
+ span.end()
@@ -8,7 +8,7 @@ show_missing = true
8
8
 
9
9
  [tool.poetry]
10
10
  name = "opentelemetry-instrumentation-openai"
11
- version = "0.10.3"
11
+ version = "0.11.2"
12
12
  description = "OpenTelemetry OpenAI instrumentation"
13
13
  authors = [
14
14
  "Gal Kleinman <gal@traceloop.com>",
@@ -25,13 +25,20 @@ include = "opentelemetry/instrumentation/openai"
25
25
  python = ">=3.8.1,<4"
26
26
  opentelemetry-api = "^1.22.0"
27
27
  opentelemetry-instrumentation = "0.43b0"
28
- opentelemetry-semantic-conventions-ai = "^0.0.19"
28
+ opentelemetry-semantic-conventions-ai = "^0.0.20"
29
29
 
30
30
  [tool.poetry.group.dev.dependencies]
31
31
  autopep8 = "2.0.4"
32
32
  flake8 = "7.0.0"
33
+
34
+ [tool.poetry.group.test.dependencies]
33
35
  pytest = "7.4.4"
34
36
  pytest-sugar = "0.9.7"
37
+ vcrpy = "^6.0.1"
38
+ pytest-recording = "^0.13.1"
39
+ openai = "^1.12.0"
40
+ opentelemetry-sdk = "^1.22.0"
41
+ pytest-asyncio = "^0.23.5"
35
42
 
36
43
  [build-system]
37
44
  requires = [ "poetry-core" ]