openlit 1.34.14__py3-none-any.whl → 1.34.16__py3-none-any.whl

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.
@@ -5,49 +5,65 @@ import importlib.metadata
5
5
  from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
6
6
  from wrapt import wrap_function_wrapper
7
7
  from openlit.instrumentation.azure_ai_inference.azure_ai_inference import (
8
- complete
8
+ complete,
9
+ embed
9
10
  )
10
11
  from openlit.instrumentation.azure_ai_inference.async_azure_ai_inference import (
11
- async_complete
12
+ async_complete,
13
+ async_embed
12
14
  )
13
15
 
14
- _instruments = ('azure-ai-inference >= 1.0.0b4',)
16
+ _instruments = ("azure-ai-inference >= 1.0.0b4",)
15
17
 
16
18
  class AzureAIInferenceInstrumentor(BaseInstrumentor):
17
19
  """
18
- An instrumentor for azure-ai-inference's client library.
20
+ An instrumentor for azure-ai-inference client library.
19
21
  """
20
22
 
21
23
  def instrumentation_dependencies(self) -> Collection[str]:
22
24
  return _instruments
23
25
 
24
26
  def _instrument(self, **kwargs):
25
- application_name = kwargs.get('application_name', 'default')
26
- environment = kwargs.get('environment', 'default')
27
- tracer = kwargs.get('tracer')
28
- event_provider = kwargs.get('event_provider')
29
- metrics = kwargs.get('metrics_dict')
30
- pricing_info = kwargs.get('pricing_info', {})
31
- capture_message_content = kwargs.get('capture_message_content', False)
32
- disable_metrics = kwargs.get('disable_metrics')
33
- version = importlib.metadata.version('azure-ai-inference')
34
-
35
- # sync generate
27
+ application_name = kwargs.get("application_name", "default")
28
+ environment = kwargs.get("environment", "default")
29
+ tracer = kwargs.get("tracer")
30
+ metrics = kwargs.get("metrics_dict")
31
+ pricing_info = kwargs.get("pricing_info", {})
32
+ capture_message_content = kwargs.get("capture_message_content", False)
33
+ disable_metrics = kwargs.get("disable_metrics")
34
+ version = importlib.metadata.version("azure-ai-inference")
35
+
36
+ # sync chat completions
36
37
  wrap_function_wrapper(
37
- 'azure.ai.inference',
38
- 'ChatCompletionsClient.complete',
38
+ "azure.ai.inference",
39
+ "ChatCompletionsClient.complete",
39
40
  complete(version, environment, application_name,
40
- tracer, event_provider, pricing_info, capture_message_content, metrics, disable_metrics),
41
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
41
42
  )
42
43
 
43
- # async generate
44
+ # async chat completions
44
45
  wrap_function_wrapper(
45
- 'azure.ai.inference.aio',
46
- 'ChatCompletionsClient.complete',
46
+ "azure.ai.inference.aio",
47
+ "ChatCompletionsClient.complete",
47
48
  async_complete(version, environment, application_name,
48
- tracer, event_provider, pricing_info, capture_message_content, metrics, disable_metrics),
49
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
50
+ )
51
+
52
+ # sync embeddings
53
+ wrap_function_wrapper(
54
+ "azure.ai.inference",
55
+ "EmbeddingsClient.embed",
56
+ embed(version, environment, application_name,
57
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
58
+ )
59
+
60
+ # async embeddings
61
+ wrap_function_wrapper(
62
+ "azure.ai.inference.aio",
63
+ "EmbeddingsClient.embed",
64
+ async_embed(version, environment, application_name,
65
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics),
49
66
  )
50
67
 
51
68
  def _uninstrument(self, **kwargs):
52
- # Proper uninstrumentation logic to revert patched methods
53
69
  pass
@@ -13,6 +13,7 @@ from openlit.instrumentation.azure_ai_inference.utils import (
13
13
  process_chunk,
14
14
  process_chat_response,
15
15
  process_streaming_chat_response,
16
+ process_embedding_response,
16
17
  )
17
18
  from openlit.semcov import SemanticConvention
18
19
 
@@ -20,7 +21,7 @@ from openlit.semcov import SemanticConvention
20
21
  logger = logging.getLogger(__name__)
21
22
 
22
23
  def async_complete(version, environment, application_name,
23
- tracer, event_provider, pricing_info, capture_message_content, metrics, disable_metrics):
24
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics):
24
25
  """
25
26
  Generates a telemetry wrapper for GenAI function call
26
27
  """
@@ -43,12 +44,15 @@ def async_complete(version, environment, application_name,
43
44
  self.__wrapped__ = wrapped
44
45
  self._span = span
45
46
  self._span_name = span_name
46
- self._llmresponse = ''
47
- self._response_id = ''
48
- self._response_model = ''
49
- self._finish_reason = ''
47
+ self._llmresponse = ""
48
+ self._response_id = ""
49
+ self._response_model = ""
50
+ self._finish_reason = ""
51
+ self._response_service_tier = ""
52
+ self._tools = None
50
53
  self._input_tokens = 0
51
54
  self._output_tokens = 0
55
+ self._reasoning_tokens = 0
52
56
 
53
57
  self._args = args
54
58
  self._kwargs = kwargs
@@ -64,53 +68,35 @@ def async_complete(version, environment, application_name,
64
68
  await self.__wrapped__.__aenter__()
65
69
  return self
66
70
 
67
- async def __aexit__(self, exc_type, exc_value, traceback):
68
- await self.__wrapped__.__aexit__(exc_type, exc_value, traceback)
71
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
72
+ await self.__wrapped__.__aexit__(exc_type, exc_val, exc_tb)
73
+ process_streaming_chat_response(
74
+ self, pricing_info, environment, application_name, metrics,
75
+ capture_message_content, disable_metrics, version
76
+ )
69
77
 
70
78
  def __aiter__(self):
71
79
  return self
72
80
 
73
- async def __getattr__(self, name):
74
- """Delegate attribute access to the wrapped object."""
75
- return getattr(await self.__wrapped__, name)
76
-
77
81
  async def __anext__(self):
78
- try:
79
- chunk = await self.__wrapped__.__anext__()
80
- process_chunk(self, chunk)
81
- return chunk
82
- except StopAsyncIteration:
83
- try:
84
- with tracer.start_as_current_span(self._span_name, kind= SpanKind.CLIENT) as self._span:
85
- process_streaming_chat_response(
86
- self,
87
- pricing_info=pricing_info,
88
- environment=environment,
89
- application_name=application_name,
90
- metrics=metrics,
91
- event_provider=event_provider,
92
- capture_message_content=capture_message_content,
93
- disable_metrics=disable_metrics,
94
- version=version
95
- )
96
-
97
- except Exception as e:
98
- handle_exception(self._span, e)
99
- logger.error('Error in trace creation: %s', e)
100
- raise
82
+ chunk = await self.__wrapped__.__anext__()
83
+ process_chunk(self, chunk)
84
+ return chunk
85
+
86
+ def __getattr__(self, name):
87
+ return getattr(self.__wrapped__, name)
101
88
 
102
89
  async def wrapper(wrapped, instance, args, kwargs):
103
90
  """
104
91
  Wraps the GenAI function call.
105
92
  """
106
93
 
107
- streaming = kwargs.get('stream', False)
108
- server_address, server_port = set_server_address_and_port(instance, 'models.github.ai', 443)
109
- request_model = kwargs.get('model', 'gpt-4o')
94
+ streaming = kwargs.get("stream", False)
95
+ server_address, server_port = set_server_address_and_port(instance, "models.github.ai", 443)
96
+ request_model = kwargs.get("model", "gpt-4o")
110
97
 
111
- span_name = f'{SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT} {request_model}'
98
+ span_name = f"{SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT} {request_model}"
112
99
 
113
- # pylint: disable=no-else-return
114
100
  if streaming:
115
101
  awaited_wrapped = await wrapped(*args, **kwargs)
116
102
  span = tracer.start_span(span_name, kind=SpanKind.CLIENT)
@@ -130,7 +116,6 @@ def async_complete(version, environment, application_name,
130
116
  environment=environment,
131
117
  application_name=application_name,
132
118
  metrics=metrics,
133
- event_provider=event_provider,
134
119
  start_time=start_time,
135
120
  span=span,
136
121
  capture_message_content=capture_message_content,
@@ -142,3 +127,48 @@ def async_complete(version, environment, application_name,
142
127
  return response
143
128
 
144
129
  return wrapper
130
+
131
+ def async_embed(version, environment, application_name,
132
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics):
133
+ """
134
+ Generates a telemetry wrapper for GenAI embedding function call
135
+ """
136
+
137
+ async def wrapper(wrapped, instance, args, kwargs):
138
+ """
139
+ Wraps the GenAI embedding function call.
140
+ """
141
+
142
+ server_address, server_port = set_server_address_and_port(instance, "models.github.ai", 443)
143
+ request_model = kwargs.get("model", "text-embedding-3-small")
144
+
145
+ span_name = f"{SemanticConvention.GEN_AI_OPERATION_TYPE_EMBEDDING} {request_model}"
146
+
147
+ with tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT) as span:
148
+ start_time = time.time()
149
+ response = await wrapped(*args, **kwargs)
150
+
151
+ try:
152
+ response = process_embedding_response(
153
+ response=response,
154
+ request_model=request_model,
155
+ pricing_info=pricing_info,
156
+ server_port=server_port,
157
+ server_address=server_address,
158
+ environment=environment,
159
+ application_name=application_name,
160
+ metrics=metrics,
161
+ start_time=start_time,
162
+ span=span,
163
+ capture_message_content=capture_message_content,
164
+ disable_metrics=disable_metrics,
165
+ version=version,
166
+ **kwargs
167
+ )
168
+
169
+ except Exception as e:
170
+ handle_exception(span, e)
171
+
172
+ return response
173
+
174
+ return wrapper
@@ -13,6 +13,7 @@ from openlit.instrumentation.azure_ai_inference.utils import (
13
13
  process_chunk,
14
14
  process_chat_response,
15
15
  process_streaming_chat_response,
16
+ process_embedding_response,
16
17
  )
17
18
  from openlit.semcov import SemanticConvention
18
19
 
@@ -20,7 +21,7 @@ from openlit.semcov import SemanticConvention
20
21
  logger = logging.getLogger(__name__)
21
22
 
22
23
  def complete(version, environment, application_name,
23
- tracer, event_provider, pricing_info, capture_message_content, metrics, disable_metrics):
24
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics):
24
25
  """
25
26
  Generates a telemetry wrapper for GenAI function call
26
27
  """
@@ -43,12 +44,15 @@ def complete(version, environment, application_name,
43
44
  self.__wrapped__ = wrapped
44
45
  self._span = span
45
46
  self._span_name = span_name
46
- self._llmresponse = ''
47
- self._response_id = ''
48
- self._response_model = ''
49
- self._finish_reason = ''
47
+ self._llmresponse = ""
48
+ self._response_id = ""
49
+ self._response_model = ""
50
+ self._finish_reason = ""
51
+ self._response_service_tier = ""
52
+ self._tools = None
50
53
  self._input_tokens = 0
51
54
  self._output_tokens = 0
55
+ self._reasoning_tokens = 0
52
56
 
53
57
  self._args = args
54
58
  self._kwargs = kwargs
@@ -64,53 +68,35 @@ def complete(version, environment, application_name,
64
68
  self.__wrapped__.__enter__()
65
69
  return self
66
70
 
67
- def __exit__(self, exc_type, exc_value, traceback):
68
- self.__wrapped__.__exit__(exc_type, exc_value, traceback)
71
+ def __exit__(self, exc_type, exc_val, exc_tb):
72
+ self.__wrapped__.__exit__(exc_type, exc_val, exc_tb)
73
+ process_streaming_chat_response(
74
+ self, pricing_info, environment, application_name, metrics,
75
+ capture_message_content, disable_metrics, version
76
+ )
69
77
 
70
78
  def __iter__(self):
71
79
  return self
72
80
 
81
+ def __next__(self):
82
+ chunk = next(self.__wrapped__)
83
+ process_chunk(self, chunk)
84
+ return chunk
85
+
73
86
  def __getattr__(self, name):
74
- """Delegate attribute access to the wrapped object."""
75
87
  return getattr(self.__wrapped__, name)
76
88
 
77
- def __next__(self):
78
- try:
79
- chunk = self.__wrapped__.__next__()
80
- process_chunk(self, chunk)
81
- return chunk
82
- except StopIteration:
83
- try:
84
- with tracer.start_as_current_span(self._span_name, kind= SpanKind.CLIENT) as self._span:
85
- process_streaming_chat_response(
86
- self,
87
- pricing_info=pricing_info,
88
- environment=environment,
89
- application_name=application_name,
90
- metrics=metrics,
91
- event_provider=event_provider,
92
- capture_message_content=capture_message_content,
93
- disable_metrics=disable_metrics,
94
- version=version
95
- )
96
-
97
- except Exception as e:
98
- handle_exception(self._span, e)
99
- logger.error('Error in trace creation: %s', e)
100
- raise
101
-
102
89
  def wrapper(wrapped, instance, args, kwargs):
103
90
  """
104
91
  Wraps the GenAI function call.
105
92
  """
106
93
 
107
- streaming = kwargs.get('stream', False)
108
- server_address, server_port = set_server_address_and_port(instance, 'models.github.ai', 443)
109
- request_model = kwargs.get('model', 'gpt-4o')
94
+ streaming = kwargs.get("stream", False)
95
+ server_address, server_port = set_server_address_and_port(instance, "models.github.ai", 443)
96
+ request_model = kwargs.get("model", "gpt-4o")
110
97
 
111
- span_name = f'{SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT} {request_model}'
98
+ span_name = f"{SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT} {request_model}"
112
99
 
113
- # pylint: disable=no-else-return
114
100
  if streaming:
115
101
  awaited_wrapped = wrapped(*args, **kwargs)
116
102
  span = tracer.start_span(span_name, kind=SpanKind.CLIENT)
@@ -130,7 +116,6 @@ def complete(version, environment, application_name,
130
116
  environment=environment,
131
117
  application_name=application_name,
132
118
  metrics=metrics,
133
- event_provider=event_provider,
134
119
  start_time=start_time,
135
120
  span=span,
136
121
  capture_message_content=capture_message_content,
@@ -142,3 +127,48 @@ def complete(version, environment, application_name,
142
127
  return response
143
128
 
144
129
  return wrapper
130
+
131
+ def embed(version, environment, application_name,
132
+ tracer, pricing_info, capture_message_content, metrics, disable_metrics):
133
+ """
134
+ Generates a telemetry wrapper for GenAI embedding function call
135
+ """
136
+
137
+ def wrapper(wrapped, instance, args, kwargs):
138
+ """
139
+ Wraps the GenAI embedding function call.
140
+ """
141
+
142
+ server_address, server_port = set_server_address_and_port(instance, "models.github.ai", 443)
143
+ request_model = kwargs.get("model", "text-embedding-3-small")
144
+
145
+ span_name = f"{SemanticConvention.GEN_AI_OPERATION_TYPE_EMBEDDING} {request_model}"
146
+
147
+ with tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT) as span:
148
+ start_time = time.time()
149
+ response = wrapped(*args, **kwargs)
150
+
151
+ try:
152
+ response = process_embedding_response(
153
+ response=response,
154
+ request_model=request_model,
155
+ pricing_info=pricing_info,
156
+ server_port=server_port,
157
+ server_address=server_address,
158
+ environment=environment,
159
+ application_name=application_name,
160
+ metrics=metrics,
161
+ start_time=start_time,
162
+ span=span,
163
+ capture_message_content=capture_message_content,
164
+ disable_metrics=disable_metrics,
165
+ version=version,
166
+ **kwargs
167
+ )
168
+
169
+ except Exception as e:
170
+ handle_exception(span, e)
171
+
172
+ return response
173
+
174
+ return wrapper