openlit 1.12.0__py3-none-any.whl → 1.13.0__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.
openlit/__init__.py CHANGED
@@ -1,17 +1,26 @@
1
+ # pylint: disable=broad-exception-caught
1
2
  """
2
3
  The __init__.py module for the openLIT package.
3
4
  This module sets up the openLIT configuration and instrumentation for various
4
5
  large language models (LLMs).
5
6
  """
7
+
6
8
  from typing import Dict
7
9
  import logging
8
10
  from importlib.util import find_spec
11
+ from functools import wraps
12
+ from contextlib import contextmanager
13
+
9
14
 
10
15
  # Import internal modules for setting up tracing and fetching pricing info.
16
+ from opentelemetry import trace as t
17
+ from opentelemetry.trace import SpanKind, Status, StatusCode, Span
18
+ from openlit.semcov import SemanticConvetion
11
19
  from openlit.otel.tracing import setup_tracing
12
20
  from openlit.otel.metrics import setup_meter
13
21
  from openlit.__helpers import fetch_pricing_info
14
22
 
23
+
15
24
  # Instrumentors for various large language models.
16
25
  from openlit.instrumentation.openai import OpenAIInstrumentor
17
26
  from openlit.instrumentation.anthropic import AnthropicInstrumentor
@@ -35,13 +44,14 @@ from openlit.instrumentation.transformers import TransformersInstrumentor
35
44
  # Set up logging for error and information messages.
36
45
  logger = logging.getLogger(__name__)
37
46
 
47
+
38
48
  class OpenlitConfig:
39
49
  """
40
50
  A Singleton Configuration class for openLIT.
41
-
51
+
42
52
  This class maintains a single instance of configuration settings including
43
53
  environment details, application name, and tracing information throughout the openLIT package.
44
-
54
+
45
55
  Attributes:
46
56
  environment (str): Deployment environment of the application.
47
57
  application_name (str): Name of the application using openLIT.
@@ -52,6 +62,7 @@ class OpenlitConfig:
52
62
  disable_batch (bool): Flag to disable batch span processing in tracing.
53
63
  trace_content (bool): Flag to enable or disable tracing of content.
54
64
  """
65
+
55
66
  _instance = None
56
67
 
57
68
  def __new__(cls):
@@ -76,9 +87,19 @@ class OpenlitConfig:
76
87
  cls.disable_metrics = False
77
88
 
78
89
  @classmethod
79
- def update_config(cls, environment, application_name, tracer, otlp_endpoint,
80
- otlp_headers, disable_batch, trace_content, metrics_dict,
81
- disable_metrics, pricing_json):
90
+ def update_config(
91
+ cls,
92
+ environment,
93
+ application_name,
94
+ tracer,
95
+ otlp_endpoint,
96
+ otlp_headers,
97
+ disable_batch,
98
+ trace_content,
99
+ metrics_dict,
100
+ disable_metrics,
101
+ pricing_json,
102
+ ):
82
103
  """
83
104
  Updates the configuration based on provided parameters.
84
105
 
@@ -104,8 +125,14 @@ class OpenlitConfig:
104
125
  cls.trace_content = trace_content
105
126
  cls.disable_metrics = disable_metrics
106
127
 
107
- def instrument_if_available(instrumentor_name, instrumentor_instance, config,
108
- disabled_instrumentors, module_name_map):
128
+
129
+ def instrument_if_available(
130
+ instrumentor_name,
131
+ instrumentor_instance,
132
+ config,
133
+ disabled_instrumentors,
134
+ module_name_map,
135
+ ):
109
136
  """Instruments the specified instrumentor if its library is available."""
110
137
  if instrumentor_name in disabled_instrumentors:
111
138
  return
@@ -121,22 +148,33 @@ def instrument_if_available(instrumentor_name, instrumentor_instance, config,
121
148
  pricing_info=config.pricing_info,
122
149
  trace_content=config.trace_content,
123
150
  metrics_dict=config.metrics_dict,
124
- disable_metrics=config.disable_metrics
151
+ disable_metrics=config.disable_metrics,
125
152
  )
126
153
 
127
154
  # pylint: disable=broad-exception-caught
128
155
  except Exception as e:
129
156
  logger.error("Failed to instrument %s: %s", instrumentor_name, e)
130
157
 
131
- def init(environment="default", application_name="default", tracer=None, otlp_endpoint=None,
132
- otlp_headers=None, disable_batch=False, trace_content=True, disabled_instrumentors=None,
133
- meter=None, disable_metrics=False, pricing_json=None):
158
+
159
+ def init(
160
+ environment="default",
161
+ application_name="default",
162
+ tracer=None,
163
+ otlp_endpoint=None,
164
+ otlp_headers=None,
165
+ disable_batch=False,
166
+ trace_content=True,
167
+ disabled_instrumentors=None,
168
+ meter=None,
169
+ disable_metrics=False,
170
+ pricing_json=None,
171
+ ):
134
172
  """
135
173
  Initializes the openLIT configuration and setups tracing.
136
-
137
- This function sets up the openLIT environment with provided configurations
174
+
175
+ This function sets up the openLIT environment with provided configurations
138
176
  and initializes instrumentors for tracing.
139
-
177
+
140
178
  Args:
141
179
  environment (str): Deployment environment.
142
180
  application_name (str): Application name.
@@ -155,8 +193,8 @@ def init(environment="default", application_name="default", tracer=None, otlp_en
155
193
 
156
194
  module_name_map = {
157
195
  "openai": "openai",
158
- "anthropic": "anthropic",
159
- "cohere": "cohere",
196
+ "anthropic": "anthropic",
197
+ "cohere": "cohere",
160
198
  "mistral": "mistralai",
161
199
  "bedrock": "boto3",
162
200
  "vertexai": "vertexai",
@@ -171,12 +209,16 @@ def init(environment="default", application_name="default", tracer=None, otlp_en
171
209
  "pinecone": "pinecone",
172
210
  "qdrant": "qdrant_client",
173
211
  "milvus": "pymilvus",
174
- "transformers": "transformers"
212
+ "transformers": "transformers",
175
213
  }
176
214
 
177
- invalid_instrumentors = [name for name in disabled_instrumentors if name not in module_name_map]
215
+ invalid_instrumentors = [
216
+ name for name in disabled_instrumentors if name not in module_name_map
217
+ ]
178
218
  for invalid_name in invalid_instrumentors:
179
- logger.warning("Invalid instrumentor name detected and ignored: '%s'", invalid_name)
219
+ logger.warning(
220
+ "Invalid instrumentor name detected and ignored: '%s'", invalid_name
221
+ )
180
222
 
181
223
  try:
182
224
  # Retrieve or create the single configuration instance.
@@ -185,9 +227,11 @@ def init(environment="default", application_name="default", tracer=None, otlp_en
185
227
  # Setup tracing based on the provided or default configuration.
186
228
  tracer = setup_tracing(
187
229
  application_name=application_name,
188
- environment=environment, tracer=tracer,
189
- otlp_endpoint=otlp_endpoint, otlp_headers=otlp_headers,
190
- disable_batch=disable_batch
230
+ environment=environment,
231
+ tracer=tracer,
232
+ otlp_endpoint=otlp_endpoint,
233
+ otlp_headers=otlp_headers,
234
+ disable_batch=disable_batch,
191
235
  )
192
236
 
193
237
  if not tracer:
@@ -195,18 +239,31 @@ def init(environment="default", application_name="default", tracer=None, otlp_en
195
239
  return
196
240
 
197
241
  # Setup meter and receive metrics_dict instead of meter
198
- metrics_dict = setup_meter(application_name=application_name,
199
- environment=environment, meter=meter,
200
- otlp_endpoint=otlp_endpoint, otlp_headers=otlp_headers)
242
+ metrics_dict = setup_meter(
243
+ application_name=application_name,
244
+ environment=environment,
245
+ meter=meter,
246
+ otlp_endpoint=otlp_endpoint,
247
+ otlp_headers=otlp_headers,
248
+ )
201
249
 
202
250
  if not metrics_dict:
203
251
  logger.error("openLIT metrics setup failed. Metrics will not be available.")
204
252
  return
205
253
 
206
254
  # Update global configuration with the provided settings.
207
- config.update_config(environment, application_name, tracer, otlp_endpoint,
208
- otlp_headers, disable_batch, trace_content,
209
- metrics_dict, disable_metrics, pricing_json)
255
+ config.update_config(
256
+ environment,
257
+ application_name,
258
+ tracer,
259
+ otlp_endpoint,
260
+ otlp_headers,
261
+ disable_batch,
262
+ trace_content,
263
+ metrics_dict,
264
+ disable_metrics,
265
+ pricing_json,
266
+ )
210
267
 
211
268
  # Map instrumentor names to their instances
212
269
  instrumentor_instances = {
@@ -227,14 +284,142 @@ def init(environment="default", application_name="default", tracer=None, otlp_en
227
284
  "pinecone": PineconeInstrumentor(),
228
285
  "qdrant": QdrantInstrumentor(),
229
286
  "milvus": MilvusInstrumentor(),
230
- "transformers": TransformersInstrumentor()
287
+ "transformers": TransformersInstrumentor(),
231
288
  }
232
289
 
233
290
  # Initialize and instrument only the enabled instrumentors
234
291
  for name, instrumentor in instrumentor_instances.items():
235
- instrument_if_available(name, instrumentor, config,
236
- disabled_instrumentors, module_name_map)
292
+ instrument_if_available(
293
+ name, instrumentor, config, disabled_instrumentors, module_name_map
294
+ )
237
295
 
238
- # pylint: disable=broad-exception-caught
239
296
  except Exception as e:
240
297
  logger.error("Error during openLIT initialization: %s", e)
298
+
299
+
300
+ def trace(wrapped):
301
+ """
302
+ Generates a telemetry wrapper for messages to collect metrics.
303
+ """
304
+
305
+ @wraps(wrapped)
306
+ def wrapper(*args, **kwargs):
307
+ __trace = t.get_tracer_provider()
308
+ with __trace.get_tracer(__name__).start_as_current_span(
309
+ name=wrapped.__name__,
310
+ kind=SpanKind.CLIENT,
311
+ ) as span:
312
+ try:
313
+ response = wrapped(*args, **kwargs)
314
+ span.set_attribute(
315
+ SemanticConvetion.GEN_AI_CONTENT_COMPLETION, response
316
+ )
317
+ span.set_status(Status(StatusCode.OK))
318
+
319
+ except Exception as e:
320
+ response = None
321
+ span.record_exception(e)
322
+ span.set_status(status=Status(StatusCode.ERROR), description=e)
323
+ logging.error("Error in %s: %s", wrapped.__name__, e, exc_info=True)
324
+
325
+ # Adding function arguments as metadata
326
+ try:
327
+ span.set_attribute("function.args", str(args))
328
+ span.set_attribute("function.kwargs", str(kwargs))
329
+ span.set_attribute(
330
+ SemanticConvetion.GEN_AI_APPLICATION_NAME,
331
+ OpenlitConfig.application_name,
332
+ )
333
+ span.set_attribute(
334
+ SemanticConvetion.GEN_AI_ENVIRONMENT, OpenlitConfig.environment
335
+ )
336
+
337
+ except Exception as meta_exception:
338
+ logging.error(
339
+ "Failed to set metadata for %s: %s",
340
+ wrapped.__name__,
341
+ meta_exception,
342
+ exc_info=True,
343
+ )
344
+
345
+ return response
346
+
347
+ return wrapper
348
+
349
+
350
+ class TracedSpan:
351
+ """
352
+ A wrapper class for an OpenTelemetry span that provides helper methods
353
+ for setting result and metadata attributes on the span.
354
+
355
+ Attributes:
356
+ _span (Span): The underlying OpenTelemetry span.
357
+ """
358
+
359
+ def __init__(self, span):
360
+ """
361
+ Initializes the TracedSpan with the given span.
362
+
363
+ Params:
364
+ span (Span): The OpenTelemetry span to be wrapped.
365
+ """
366
+
367
+ self._span: Span = span
368
+
369
+ def set_result(self, result):
370
+ """
371
+ Sets the result attribute on the underlying span.
372
+
373
+ Params:
374
+ result: The result to be set as an attribute on the span.
375
+ """
376
+
377
+ self._span.set_attribute(SemanticConvetion.GEN_AI_CONTENT_COMPLETION, result)
378
+
379
+ def set_metadata(self, metadata: Dict):
380
+ """
381
+ Sets multiple attributes on the underlying span.
382
+
383
+ Params:
384
+ metadata (Dict): A dictionary of attributes to be set on the span.
385
+ """
386
+
387
+ self._span.set_attributes(attributes=metadata)
388
+
389
+ def __enter__(self):
390
+ """
391
+ Enters the context of the TracedSpan, returning itself.
392
+
393
+ Returns:
394
+ TracedSpan: The instance of TracedSpan.
395
+ """
396
+
397
+ return self
398
+
399
+ def __exit__(self, _exc_type, _exc_val, _exc_tb):
400
+ """
401
+ Exits the context of the TracedSpan by ending the underlying span.
402
+ """
403
+
404
+ self._span.end()
405
+
406
+
407
+ @contextmanager
408
+ def start_trace(name: str):
409
+ """
410
+ A context manager that starts a new trace and provides a TracedSpan
411
+ for usage within the context.
412
+
413
+ Params:
414
+ name (str): The name of the span.
415
+
416
+ Yields:
417
+ TracedSpan: The wrapped span for trace operations.
418
+ """
419
+
420
+ __trace = t.get_tracer_provider()
421
+ with __trace.get_tracer(__name__).start_as_current_span(
422
+ name,
423
+ kind=SpanKind.CLIENT,
424
+ ) as span:
425
+ yield TracedSpan(span)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openlit
3
- Version: 1.12.0
3
+ Version: 1.13.0
4
4
  Summary: OpenTelemetry-native Auto instrumentation library for monitoring LLM Applications, facilitating the integration of observability into your GenAI-driven projects
5
5
  Home-page: https://github.com/openlit/openlit/tree/main/openlit/python
6
6
  Keywords: OpenTelemetry,otel,otlp,llm,tracing,openai,anthropic,claude,cohere,llm monitoring,observability,monitoring,gpt,Generative AI,chatGPT
@@ -36,7 +36,8 @@ OpenTelemetry Auto-Instrumentation for GenAI & LLM Applications</h1>
36
36
  [![GitHub Contributors](https://img.shields.io/github/contributors/openlit/openlit)](https://github.com/openlit/openlit/graphs/contributors)
37
37
 
38
38
  [![Slack](https://img.shields.io/badge/Slack-4A154B?logo=slack&logoColor=white)](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ)
39
- [![X](https://img.shields.io/badge/follow-%40OpenLIT-1DA1F2?logo=x&style=social)](https://twitter.com/openlit_io)
39
+ [![Discord](https://img.shields.io/badge/Discord-7289DA?logo=discord&logoColor=white)](https://discord.gg/rjvTm6zd)
40
+ [![X](https://img.shields.io/badge/follow-%40openlit__io-1DA1F2?logo=x&style=social)](https://twitter.com/openlit_io)
40
41
 
41
42
  ![OpenLIT Connections Banner](https://github.com/openlit/.github/blob/main/profile/assets/github-readme-connections-banner.png?raw=true)
42
43
 
@@ -191,7 +192,7 @@ Whether it's big or small, we love contributions 💚. Check out our [Contributi
191
192
 
192
193
  Unsure where to start? Here are a few ways to get involved:
193
194
 
194
- - Join our [Slack channel](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) to discuss ideas, share feedback, and connect with both our team and the wider OpenLIT community.
195
+ - Join our [Slack](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) or [Discord](https://discord.gg/rjvTm6zd) community to discuss ideas, share feedback, and connect with both our team and the wider OpenLIT community.
195
196
 
196
197
  Your input helps us grow and improve, and we're here to support you every step of the way.
197
198
 
@@ -200,7 +201,7 @@ Your input helps us grow and improve, and we're here to support you every step o
200
201
  Connect with the OpenLIT community and maintainers for support, discussions, and updates:
201
202
 
202
203
  - 🌟 If you like it, Leave a star on our [GitHub](https://github.com/openlit/openlit/)
203
- - 🌍 Join our [Slack](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) Community for live interactions and questions.
204
+ - 🌍 Join our [Slack](https://join.slack.com/t/openlit/shared_invite/zt-2etnfttwg-TjP_7BZXfYg84oAukY8QRQ) or [Discord](https://discord.gg/rjvTm6zd) community for live interactions and questions.
204
205
  - 🐞 Report bugs on our [GitHub Issues](https://github.com/openlit/openlit/issues) to help us improve OpenLIT.
205
206
  - 𝕏 Follow us on [X](https://x.com/openlit_io) for the latest updates and news.
206
207
 
@@ -1,5 +1,5 @@
1
1
  openlit/__helpers.py,sha256=lrn4PBs9owDudiCY2NBoVbAi7AU_HtUpyOj0oqPBsPY,5545
2
- openlit/__init__.py,sha256=uW32Zg5R6NK3qqy3rfQhUnFi_YfvhnM4TFJSLo6Yr54,10439
2
+ openlit/__init__.py,sha256=ZkXQbO0l2trFv-DqljF5ZLCCBJqjqOMIxmE6Tcafabg,14452
3
3
  openlit/instrumentation/anthropic/__init__.py,sha256=oaU53BOPyfUKbEzYvLr1DPymDluurSnwo4Hernf2XdU,1955
4
4
  openlit/instrumentation/anthropic/anthropic.py,sha256=CYBui5eEfWdSfFF0xtCQjh1xO-gCVJc_V9Hli0szVZE,16026
5
5
  openlit/instrumentation/anthropic/async_anthropic.py,sha256=NW84kTQ3BkUx1zZuMRps_J7zTYkmq5BxOrqSjqWInBs,16068
@@ -47,7 +47,7 @@ openlit/instrumentation/vertexai/vertexai.py,sha256=UvpNKBHPoV9idVMfGigZnmWuEQiy
47
47
  openlit/otel/metrics.py,sha256=O7NoaDz0bY19mqpE4-0PcKwEe-B-iJFRgOCaanAuZAc,4291
48
48
  openlit/otel/tracing.py,sha256=vL1ifMbARPBpqK--yXYsCM6y5dSu5LFIKqkhZXtYmUc,3712
49
49
  openlit/semcov/__init__.py,sha256=fZve0UdvbZCcXBBiYhQhwm6gFe9JPkZznyr8W3wiI68,6681
50
- openlit-1.12.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
51
- openlit-1.12.0.dist-info/METADATA,sha256=4N0gOurCVrWMv_5yMkqFqLxPFwjeACSF6Tutc2WOOxc,13123
52
- openlit-1.12.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
53
- openlit-1.12.0.dist-info/RECORD,,
50
+ openlit-1.13.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
51
+ openlit-1.13.0.dist-info/METADATA,sha256=d_S0Eqcq8Oh0i9yPN21bc6yDFpdxhFuZ97Rv8sQByoc,13329
52
+ openlit-1.13.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
53
+ openlit-1.13.0.dist-info/RECORD,,