lmnr 0.6.21__py3-none-any.whl → 0.7.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.
- lmnr/__init__.py +0 -4
- lmnr/opentelemetry_lib/decorators/__init__.py +38 -28
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/__init__.py +6 -2
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/__init__.py +4 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/__init__.py +3 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/langgraph/__init__.py +16 -16
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/chat_wrappers.py +3 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/completion_wrappers.py +3 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/assistant_wrappers.py +3 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/responses_wrappers.py +7 -0
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/threading/__init__.py +190 -0
- lmnr/opentelemetry_lib/tracing/__init__.py +89 -1
- lmnr/opentelemetry_lib/tracing/context.py +109 -0
- lmnr/opentelemetry_lib/tracing/processor.py +5 -6
- lmnr/opentelemetry_lib/tracing/tracer.py +29 -0
- lmnr/sdk/browser/browser_use_otel.py +5 -5
- lmnr/sdk/browser/patchright_otel.py +14 -0
- lmnr/sdk/browser/playwright_otel.py +32 -6
- lmnr/sdk/browser/pw_utils.py +78 -6
- lmnr/sdk/client/asynchronous/resources/browser_events.py +1 -0
- lmnr/sdk/laminar.py +109 -164
- lmnr/sdk/types.py +0 -6
- lmnr/version.py +1 -1
- {lmnr-0.6.21.dist-info → lmnr-0.7.0.dist-info}/METADATA +3 -2
- {lmnr-0.6.21.dist-info → lmnr-0.7.0.dist-info}/RECORD +27 -26
- {lmnr-0.6.21.dist-info → lmnr-0.7.0.dist-info}/WHEEL +1 -1
- lmnr/opentelemetry_lib/tracing/context_properties.py +0 -65
- {lmnr-0.6.21.dist-info → lmnr-0.7.0.dist-info}/entry_points.txt +0 -0
lmnr/sdk/laminar.py
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
from contextlib import contextmanager
|
2
2
|
from contextvars import Context
|
3
3
|
import warnings
|
4
|
-
from typing_extensions import deprecated
|
5
4
|
from lmnr.opentelemetry_lib import TracerManager
|
5
|
+
from lmnr.opentelemetry_lib.tracing import TracerWrapper, get_current_context
|
6
6
|
from lmnr.opentelemetry_lib.tracing.instruments import Instruments
|
7
|
-
from lmnr.opentelemetry_lib.tracing.tracer import
|
7
|
+
from lmnr.opentelemetry_lib.tracing.tracer import get_tracer_with_context
|
8
8
|
from lmnr.opentelemetry_lib.tracing.attributes import (
|
9
9
|
ASSOCIATION_PROPERTIES,
|
10
10
|
USER_ID,
|
@@ -13,13 +13,13 @@ from lmnr.opentelemetry_lib.tracing.attributes import (
|
|
13
13
|
)
|
14
14
|
from lmnr.opentelemetry_lib import MAX_MANUAL_SPAN_PAYLOAD_SIZE
|
15
15
|
from lmnr.opentelemetry_lib.decorators import json_dumps
|
16
|
-
from opentelemetry import
|
16
|
+
from opentelemetry import trace
|
17
17
|
from opentelemetry.context import attach, detach
|
18
|
-
from opentelemetry.trace import INVALID_TRACE_ID
|
18
|
+
from opentelemetry.trace import INVALID_TRACE_ID, Span, Status, StatusCode, use_span
|
19
19
|
from opentelemetry.sdk.trace.id_generator import RandomIdGenerator
|
20
20
|
from opentelemetry.util.types import AttributeValue
|
21
21
|
|
22
|
-
from typing import Any, Literal
|
22
|
+
from typing import Any, Iterator, Literal
|
23
23
|
|
24
24
|
import datetime
|
25
25
|
import logging
|
@@ -33,12 +33,6 @@ from lmnr.opentelemetry_lib.tracing.attributes import (
|
|
33
33
|
SPAN_OUTPUT,
|
34
34
|
TRACE_TYPE,
|
35
35
|
)
|
36
|
-
from lmnr.opentelemetry_lib.tracing.context_properties import (
|
37
|
-
get_association_properties,
|
38
|
-
remove_association_properties,
|
39
|
-
set_association_properties,
|
40
|
-
update_association_properties,
|
41
|
-
)
|
42
36
|
from lmnr.sdk.utils import from_env, is_otel_attribute_value_type
|
43
37
|
|
44
38
|
from .log import VerboseColorfulFormatter
|
@@ -46,7 +40,6 @@ from .log import VerboseColorfulFormatter
|
|
46
40
|
from .types import (
|
47
41
|
LaminarSpanContext,
|
48
42
|
TraceType,
|
49
|
-
TracingLevel,
|
50
43
|
)
|
51
44
|
|
52
45
|
|
@@ -147,7 +140,6 @@ class Laminar:
|
|
147
140
|
if match := re.search(r":(\d{1,5})$", url):
|
148
141
|
url = url[: -len(match.group(0))]
|
149
142
|
cls.__logger.info(f"Ignoring port in base URL: {match.group(1)}")
|
150
|
-
|
151
143
|
http_url = base_http_url or url
|
152
144
|
if not http_url.startswith("http:") and not http_url.startswith("https:"):
|
153
145
|
http_url = f"https://{http_url}"
|
@@ -172,9 +164,9 @@ class Laminar:
|
|
172
164
|
http_port=http_port or 443,
|
173
165
|
port=grpc_port or 8443,
|
174
166
|
project_api_key=cls.__project_api_key,
|
175
|
-
instruments=set(instruments) if instruments else None,
|
167
|
+
instruments=set(instruments) if instruments is not None else None,
|
176
168
|
block_instruments=(
|
177
|
-
set(disabled_instruments) if disabled_instruments else None
|
169
|
+
set(disabled_instruments) if disabled_instruments is not None else None
|
178
170
|
),
|
179
171
|
disable_batch=disable_batch,
|
180
172
|
max_export_batch_size=max_export_batch_size,
|
@@ -233,7 +225,7 @@ class Laminar:
|
|
233
225
|
if value is not None:
|
234
226
|
event["lmnr.event.value"] = value
|
235
227
|
|
236
|
-
current_span = trace.get_current_span()
|
228
|
+
current_span = trace.get_current_span(context=get_current_context())
|
237
229
|
if current_span == trace.INVALID_SPAN:
|
238
230
|
cls.__logger.warning(
|
239
231
|
"`Laminar().event()` called outside of span context. "
|
@@ -255,7 +247,7 @@ class Laminar:
|
|
255
247
|
labels: list[str] | None = None,
|
256
248
|
parent_span_context: LaminarSpanContext | None = None,
|
257
249
|
tags: list[str] | None = None,
|
258
|
-
):
|
250
|
+
) -> Iterator[Span]:
|
259
251
|
"""Start a new span as the current span. Useful for manual
|
260
252
|
instrumentation. If `span_type` is set to `"LLM"`, you should report
|
261
253
|
usage and response attributes manually. See `Laminar.set_span_attributes`
|
@@ -303,8 +295,10 @@ class Laminar:
|
|
303
295
|
)
|
304
296
|
return
|
305
297
|
|
306
|
-
|
307
|
-
|
298
|
+
wrapper = TracerWrapper()
|
299
|
+
|
300
|
+
with get_tracer_with_context() as (tracer, isolated_context):
|
301
|
+
ctx = context or isolated_context
|
308
302
|
if parent_span_context is not None:
|
309
303
|
span_context = LaminarSpanContext.try_to_otel_span_context(
|
310
304
|
parent_span_context, cls.__logger
|
@@ -335,6 +329,7 @@ class Laminar:
|
|
335
329
|
f"`start_as_current_span` Could not set tags: {tags}. Tags must be a list of strings. "
|
336
330
|
"Tags will be ignored."
|
337
331
|
)
|
332
|
+
|
338
333
|
with tracer.start_as_current_span(
|
339
334
|
name,
|
340
335
|
context=ctx,
|
@@ -344,6 +339,7 @@ class Laminar:
|
|
344
339
|
**(tag_props),
|
345
340
|
},
|
346
341
|
) as span:
|
342
|
+
wrapper.push_span_context(span)
|
347
343
|
if input is not None:
|
348
344
|
serialized_input = json_dumps(input)
|
349
345
|
if len(serialized_input) > MAX_MANUAL_SPAN_PAYLOAD_SIZE:
|
@@ -358,60 +354,13 @@ class Laminar:
|
|
358
354
|
)
|
359
355
|
yield span
|
360
356
|
|
357
|
+
wrapper.pop_span_context()
|
361
358
|
# TODO: Figure out if this is necessary
|
362
359
|
try:
|
363
360
|
detach(ctx_token)
|
364
361
|
except Exception:
|
365
362
|
pass
|
366
363
|
|
367
|
-
@classmethod
|
368
|
-
@contextmanager
|
369
|
-
@deprecated(
|
370
|
-
"Use `Laminar.set_span_tags` or the `tags` argument of "
|
371
|
-
"`Laminar.start_as_current_span` or `Laminar.start_span` instead"
|
372
|
-
)
|
373
|
-
def with_labels(cls, labels: list[str], context: Context | None = None):
|
374
|
-
"""Set labels for spans within this `with` context. This is useful for
|
375
|
-
adding labels to the spans created in the auto-instrumentations.
|
376
|
-
|
377
|
-
Requirements:
|
378
|
-
- Labels must be created in your project in advance.
|
379
|
-
- Keys must be strings from your label names.
|
380
|
-
- Values must be strings matching the label's allowed values.
|
381
|
-
|
382
|
-
Usage example:
|
383
|
-
```python
|
384
|
-
with Laminar.with_labels({"sentiment": "positive"}):
|
385
|
-
openai_client.chat.completions.create()
|
386
|
-
```
|
387
|
-
"""
|
388
|
-
warnings.warn(
|
389
|
-
"`Laminar.with_labels` is deprecated. Use `Laminar.set_span_tags` or the `tags` argument of "
|
390
|
-
"`Laminar.start_as_current_span` or `Laminar.start_span` instead",
|
391
|
-
DeprecationWarning,
|
392
|
-
)
|
393
|
-
if not cls.is_initialized():
|
394
|
-
yield
|
395
|
-
return
|
396
|
-
|
397
|
-
with get_tracer():
|
398
|
-
label_props = labels.copy()
|
399
|
-
prev_labels = get_association_properties(context).get("labels", [])
|
400
|
-
update_association_properties(
|
401
|
-
{"labels": prev_labels + label_props},
|
402
|
-
set_on_current_span=False,
|
403
|
-
context=context,
|
404
|
-
)
|
405
|
-
yield
|
406
|
-
try:
|
407
|
-
set_association_properties({"labels": prev_labels})
|
408
|
-
except Exception:
|
409
|
-
cls.__logger.warning(
|
410
|
-
f"`with_labels` Could not remove labels: {labels}. They will be "
|
411
|
-
"propagated to the next span."
|
412
|
-
)
|
413
|
-
pass
|
414
|
-
|
415
364
|
@classmethod
|
416
365
|
def start_span(
|
417
366
|
cls,
|
@@ -487,8 +436,8 @@ class Laminar:
|
|
487
436
|
)
|
488
437
|
)
|
489
438
|
|
490
|
-
with
|
491
|
-
ctx = context or
|
439
|
+
with get_tracer_with_context() as (tracer, isolated_context):
|
440
|
+
ctx = context or isolated_context
|
492
441
|
if parent_span_context is not None:
|
493
442
|
span_context = LaminarSpanContext.try_to_otel_span_context(
|
494
443
|
parent_span_context, cls.__logger
|
@@ -520,6 +469,7 @@ class Laminar:
|
|
520
469
|
f"`start_span` Could not set tags: {tags}. Tags must be a list of strings. "
|
521
470
|
+ "Tags will be ignored."
|
522
471
|
)
|
472
|
+
|
523
473
|
span = tracer.start_span(
|
524
474
|
name,
|
525
475
|
context=ctx,
|
@@ -529,6 +479,7 @@ class Laminar:
|
|
529
479
|
**(tag_props),
|
530
480
|
},
|
531
481
|
)
|
482
|
+
|
532
483
|
if input is not None:
|
533
484
|
serialized_input = json_dumps(input)
|
534
485
|
if len(serialized_input) > MAX_MANUAL_SPAN_PAYLOAD_SIZE:
|
@@ -543,6 +494,74 @@ class Laminar:
|
|
543
494
|
)
|
544
495
|
return span
|
545
496
|
|
497
|
+
@classmethod
|
498
|
+
@contextmanager
|
499
|
+
def use_span(
|
500
|
+
cls,
|
501
|
+
span: Span,
|
502
|
+
end_on_exit: bool = False,
|
503
|
+
record_exception: bool = True,
|
504
|
+
set_status_on_exception: bool = True,
|
505
|
+
) -> Iterator[Span]:
|
506
|
+
"""Use a span as the current span. Useful for manual instrumentation.
|
507
|
+
|
508
|
+
Fully copies the implementation of `use_span` from opentelemetry.trace
|
509
|
+
and replaces the context API with Laminar's isolated context.
|
510
|
+
|
511
|
+
Args:
|
512
|
+
span: The span that should be activated in the current context.
|
513
|
+
end_on_exit: Whether to end the span automatically when leaving the
|
514
|
+
context manager scope.
|
515
|
+
record_exception: Whether to record any exceptions raised within the
|
516
|
+
context as error event on the span.
|
517
|
+
set_status_on_exception: Only relevant if the returned span is used
|
518
|
+
in a with/context manager. Defines whether the span status will
|
519
|
+
be automatically set to ERROR when an uncaught exception is
|
520
|
+
raised in the span with block. The span status won't be set by
|
521
|
+
this mechanism if it was previously set manually.
|
522
|
+
"""
|
523
|
+
if not cls.is_initialized():
|
524
|
+
yield from use_span(
|
525
|
+
span, end_on_exit, record_exception, set_status_on_exception
|
526
|
+
)
|
527
|
+
|
528
|
+
wrapper = TracerWrapper()
|
529
|
+
|
530
|
+
try:
|
531
|
+
wrapper.push_span_context(span)
|
532
|
+
try:
|
533
|
+
yield span
|
534
|
+
finally:
|
535
|
+
wrapper.pop_span_context()
|
536
|
+
|
537
|
+
# Record only exceptions that inherit Exception class but not BaseException, because
|
538
|
+
# classes that directly inherit BaseException are not technically errors, e.g. GeneratorExit.
|
539
|
+
# See https://github.com/open-telemetry/opentelemetry-python/issues/4484
|
540
|
+
except Exception as exc: # pylint: disable=broad-exception-caught
|
541
|
+
if isinstance(span, Span) and span.is_recording():
|
542
|
+
# Record the exception as an event
|
543
|
+
if record_exception:
|
544
|
+
span.record_exception(exc)
|
545
|
+
|
546
|
+
# Set status in case exception was raised
|
547
|
+
if set_status_on_exception:
|
548
|
+
span.set_status(
|
549
|
+
Status(
|
550
|
+
status_code=StatusCode.ERROR,
|
551
|
+
description=f"{type(exc).__name__}: {exc}",
|
552
|
+
)
|
553
|
+
)
|
554
|
+
|
555
|
+
# This causes parent spans to set their status to ERROR and to record
|
556
|
+
# an exception as an event if a child span raises an exception even if
|
557
|
+
# such child span was started with both record_exception and
|
558
|
+
# set_status_on_exception attributes set to False.
|
559
|
+
raise
|
560
|
+
|
561
|
+
finally:
|
562
|
+
if end_on_exit:
|
563
|
+
span.end()
|
564
|
+
|
546
565
|
@classmethod
|
547
566
|
def set_span_output(cls, output: Any = None):
|
548
567
|
"""Set the output of the current span. Useful for manual
|
@@ -552,7 +571,7 @@ class Laminar:
|
|
552
571
|
output (Any, optional): output of the span. Will be sent as an\
|
553
572
|
attribute, so must be json serializable. Defaults to None.
|
554
573
|
"""
|
555
|
-
span = trace.get_current_span()
|
574
|
+
span = trace.get_current_span(context=get_current_context())
|
556
575
|
if output is not None and span != trace.INVALID_SPAN:
|
557
576
|
serialized_output = json_dumps(output)
|
558
577
|
if len(serialized_output) > MAX_MANUAL_SPAN_PAYLOAD_SIZE:
|
@@ -563,39 +582,6 @@ class Laminar:
|
|
563
582
|
else:
|
564
583
|
span.set_attribute(SPAN_OUTPUT, serialized_output)
|
565
584
|
|
566
|
-
@classmethod
|
567
|
-
@contextmanager
|
568
|
-
def set_tracing_level(self, level: TracingLevel):
|
569
|
-
"""Set the tracing level for the current span and the context
|
570
|
-
(i.e. any children spans created from the current span in the current
|
571
|
-
thread).
|
572
|
-
|
573
|
-
Tracing level can be one of:
|
574
|
-
- `TracingLevel.ALL`: Enable tracing for the current span and all
|
575
|
-
children spans.
|
576
|
-
- `TracingLevel.META_ONLY`: Enable tracing for the current span and all
|
577
|
-
children spans, but only record metadata, e.g. tokens, costs.
|
578
|
-
- `TracingLevel.OFF`: Disable recording any spans.
|
579
|
-
|
580
|
-
Example:
|
581
|
-
```python
|
582
|
-
from lmnr import Laminar, TracingLevel
|
583
|
-
|
584
|
-
with Laminar.set_tracing_level(TracingLevel.META_ONLY):
|
585
|
-
openai_client.chat.completions.create()
|
586
|
-
```
|
587
|
-
"""
|
588
|
-
if level == TracingLevel.ALL:
|
589
|
-
yield
|
590
|
-
else:
|
591
|
-
level = "meta_only" if level == TracingLevel.META_ONLY else "off"
|
592
|
-
update_association_properties({"tracing_level": level})
|
593
|
-
yield
|
594
|
-
try:
|
595
|
-
remove_association_properties({"tracing_level": level})
|
596
|
-
except Exception:
|
597
|
-
pass
|
598
|
-
|
599
585
|
@classmethod
|
600
586
|
def set_span_attributes(
|
601
587
|
cls,
|
@@ -623,7 +609,7 @@ class Laminar:
|
|
623
609
|
Args:
|
624
610
|
attributes (dict[Attributes | str, Any]): attributes to set for the span
|
625
611
|
"""
|
626
|
-
span = trace.get_current_span()
|
612
|
+
span = trace.get_current_span(context=get_current_context())
|
627
613
|
if span == trace.INVALID_SPAN:
|
628
614
|
return
|
629
615
|
|
@@ -642,7 +628,10 @@ class Laminar:
|
|
642
628
|
"""Get the laminar span context for a given span.
|
643
629
|
If no span is provided, the current active span will be used.
|
644
630
|
"""
|
645
|
-
|
631
|
+
if not cls.is_initialized():
|
632
|
+
return None
|
633
|
+
|
634
|
+
span = span or trace.get_current_span(context=get_current_context())
|
646
635
|
if span == trace.INVALID_SPAN:
|
647
636
|
return None
|
648
637
|
return LaminarSpanContext(
|
@@ -725,7 +714,8 @@ class Laminar:
|
|
725
714
|
"""
|
726
715
|
if not cls.is_initialized():
|
727
716
|
return
|
728
|
-
|
717
|
+
|
718
|
+
span = trace.get_current_span(context=get_current_context())
|
729
719
|
if span == trace.INVALID_SPAN:
|
730
720
|
cls.__logger.warning("No active span to set tags on")
|
731
721
|
return
|
@@ -736,37 +726,6 @@ class Laminar:
|
|
736
726
|
return
|
737
727
|
span.set_attribute(f"{ASSOCIATION_PROPERTIES}.tags", tags)
|
738
728
|
|
739
|
-
@classmethod
|
740
|
-
@deprecated("Use `Laminar.set_trace_session_id` instead")
|
741
|
-
def set_session(
|
742
|
-
cls,
|
743
|
-
session_id: str | None = None,
|
744
|
-
):
|
745
|
-
"""Set the session id for the current span and the context
|
746
|
-
(i.e. any children spans created from the current span in the current
|
747
|
-
thread).
|
748
|
-
|
749
|
-
Args:
|
750
|
-
session_id (str | None, optional): Custom session id.\
|
751
|
-
Useful to debug and group long-running\
|
752
|
-
sessions/conversations.
|
753
|
-
Defaults to None.
|
754
|
-
"""
|
755
|
-
warnings.warn(
|
756
|
-
"`Laminar.set_session` is deprecated. Use `Laminar.set_trace_session_id` instead",
|
757
|
-
DeprecationWarning,
|
758
|
-
)
|
759
|
-
association_properties = {}
|
760
|
-
if session_id is not None:
|
761
|
-
association_properties[SESSION_ID] = session_id
|
762
|
-
# update_association_properties(association_properties)
|
763
|
-
span = trace.get_current_span()
|
764
|
-
if span == trace.INVALID_SPAN:
|
765
|
-
cls.__logger.warning("No active span to set session id on")
|
766
|
-
return
|
767
|
-
if session_id is not None:
|
768
|
-
span.set_attribute(f"{ASSOCIATION_PROPERTIES}.{SESSION_ID}", session_id)
|
769
|
-
|
770
729
|
@classmethod
|
771
730
|
def set_trace_session_id(cls, session_id: str | None = None):
|
772
731
|
"""Set the session id for the current trace.
|
@@ -777,7 +736,8 @@ class Laminar:
|
|
777
736
|
"""
|
778
737
|
if not cls.is_initialized():
|
779
738
|
return
|
780
|
-
|
739
|
+
|
740
|
+
span = trace.get_current_span(context=get_current_context())
|
781
741
|
if span == trace.INVALID_SPAN:
|
782
742
|
cls.__logger.warning("No active span to set session id on")
|
783
743
|
return
|
@@ -794,35 +754,14 @@ class Laminar:
|
|
794
754
|
"""
|
795
755
|
if not cls.is_initialized():
|
796
756
|
return
|
797
|
-
|
757
|
+
|
758
|
+
span = trace.get_current_span(context=get_current_context())
|
798
759
|
if span == trace.INVALID_SPAN:
|
799
760
|
cls.__logger.warning("No active span to set user id on")
|
800
761
|
return
|
801
762
|
if user_id is not None:
|
802
763
|
span.set_attribute(f"{ASSOCIATION_PROPERTIES}.{USER_ID}", user_id)
|
803
764
|
|
804
|
-
@classmethod
|
805
|
-
@deprecated("Use `Laminar.set_trace_metadata` instead")
|
806
|
-
def set_metadata(cls, metadata: dict[str, str]):
|
807
|
-
"""Set the metadata for the current trace.
|
808
|
-
|
809
|
-
Args:
|
810
|
-
metadata (dict[str, str]): Metadata to set for the trace. Will be\
|
811
|
-
sent as attributes, so must be json serializable.
|
812
|
-
"""
|
813
|
-
warnings.warn(
|
814
|
-
"`Laminar.set_metadata` is deprecated. Use `Laminar.set_trace_metadata` instead",
|
815
|
-
DeprecationWarning,
|
816
|
-
)
|
817
|
-
props = {f"metadata.{k}": json_dumps(v) for k, v in metadata.items()}
|
818
|
-
# update_association_properties(props)
|
819
|
-
span = trace.get_current_span()
|
820
|
-
if span == trace.INVALID_SPAN:
|
821
|
-
cls.__logger.warning("No active span to set metadata on")
|
822
|
-
return
|
823
|
-
for key, value in props.items():
|
824
|
-
span.set_attribute(key, value)
|
825
|
-
|
826
765
|
@classmethod
|
827
766
|
def set_trace_metadata(cls, metadata: dict[str, AttributeValue]):
|
828
767
|
"""Set the metadata for the current trace.
|
@@ -832,7 +771,8 @@ class Laminar:
|
|
832
771
|
"""
|
833
772
|
if not cls.is_initialized():
|
834
773
|
return
|
835
|
-
|
774
|
+
|
775
|
+
span = trace.get_current_span(context=get_current_context())
|
836
776
|
if span == trace.INVALID_SPAN:
|
837
777
|
cls.__logger.warning("No active span to set metadata on")
|
838
778
|
return
|
@@ -861,7 +801,11 @@ class Laminar:
|
|
861
801
|
uuid.UUID | None: The trace id for the current span, or None if\
|
862
802
|
there is no active span.
|
863
803
|
"""
|
864
|
-
trace_id =
|
804
|
+
trace_id = (
|
805
|
+
trace.get_current_span(context=get_current_context())
|
806
|
+
.get_span_context()
|
807
|
+
.trace_id
|
808
|
+
)
|
865
809
|
if trace_id == INVALID_TRACE_ID:
|
866
810
|
return None
|
867
811
|
return uuid.UUID(int=trace_id)
|
@@ -885,7 +829,8 @@ class Laminar:
|
|
885
829
|
"""
|
886
830
|
if not cls.is_initialized():
|
887
831
|
return
|
888
|
-
|
832
|
+
|
833
|
+
span = trace.get_current_span(context=get_current_context())
|
889
834
|
if span == trace.INVALID_SPAN:
|
890
835
|
cls.__logger.warning("No active span to set trace type on")
|
891
836
|
return
|
lmnr/sdk/types.py
CHANGED
@@ -141,12 +141,6 @@ class GetDatapointsResponse(pydantic.BaseModel):
|
|
141
141
|
totalCount: int
|
142
142
|
|
143
143
|
|
144
|
-
class TracingLevel(Enum):
|
145
|
-
OFF = 0
|
146
|
-
META_ONLY = 1
|
147
|
-
ALL = 2
|
148
|
-
|
149
|
-
|
150
144
|
class LaminarSpanContext(pydantic.BaseModel):
|
151
145
|
"""
|
152
146
|
A span context that can be used to continue a trace across services. This
|
lmnr/version.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: lmnr
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.7.0
|
4
4
|
Summary: Python SDK for Laminar
|
5
5
|
Author: lmnr.ai
|
6
6
|
Author-email: lmnr.ai <founders@lmnr.ai>
|
@@ -17,14 +17,15 @@ Requires-Dist: opentelemetry-api>=1.33.0
|
|
17
17
|
Requires-Dist: opentelemetry-sdk>=1.33.0
|
18
18
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.33.0
|
19
19
|
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.33.0
|
20
|
+
Requires-Dist: opentelemetry-instrumentation>=0.54b0
|
20
21
|
Requires-Dist: opentelemetry-semantic-conventions>=0.54b0
|
21
22
|
Requires-Dist: opentelemetry-semantic-conventions-ai>=0.4.9
|
22
23
|
Requires-Dist: tqdm>=4.0
|
23
24
|
Requires-Dist: tenacity>=8.0
|
24
25
|
Requires-Dist: grpcio>=1
|
25
26
|
Requires-Dist: httpx>=0.25.0
|
26
|
-
Requires-Dist: opentelemetry-instrumentation-threading>=0.54b0
|
27
27
|
Requires-Dist: orjson>=3.10.18
|
28
|
+
Requires-Dist: packaging>=22.0
|
28
29
|
Requires-Dist: opentelemetry-instrumentation-alephalpha>=0.40.12 ; extra == 'alephalpha'
|
29
30
|
Requires-Dist: opentelemetry-instrumentation-alephalpha>=0.40.12 ; extra == 'all'
|
30
31
|
Requires-Dist: opentelemetry-instrumentation-bedrock>=0.40.12 ; extra == 'all'
|
@@ -1,11 +1,11 @@
|
|
1
|
-
lmnr/__init__.py,sha256=
|
1
|
+
lmnr/__init__.py,sha256=47422a1fd58f5be3e7870ccb3ed7de4f1ac520d942e0c83cbcf903b0600a08f6,1278
|
2
2
|
lmnr/cli.py,sha256=b8780b51f37fe9e20db5495c41d3ad3837f6b48f408b09a58688d017850c0796,6047
|
3
3
|
lmnr/opentelemetry_lib/.flake8,sha256=6c2c6e0e51b1dd8439e501ca3e21899277076a787da868d0254ba37056b79405,150
|
4
4
|
lmnr/opentelemetry_lib/__init__.py,sha256=6962aca915d485586ed814b9e799ced898594ac2bc6d35329405705b26eab861,2160
|
5
|
-
lmnr/opentelemetry_lib/decorators/__init__.py,sha256=
|
5
|
+
lmnr/opentelemetry_lib/decorators/__init__.py,sha256=7bd673692d15591ca1fbf48e16ab63e6e4d6a61d5123b41ad680687145b8efb6,9533
|
6
6
|
lmnr/opentelemetry_lib/litellm/__init__.py,sha256=c23a38e88b7919d866c4f09a880f2468ac9acf756cb910d1614082b2dbcad3e6,14858
|
7
7
|
lmnr/opentelemetry_lib/litellm/utils.py,sha256=da8cf0553f82dc7203109f117a4c7b4185e8baf34caad12d7823875515201a27,539
|
8
|
-
lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/__init__.py,sha256=
|
8
|
+
lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/__init__.py,sha256=984b8f97eb31d4345ea4c52237451f791af189c4a94aaf2625edfd05107d8a6e,20696
|
9
9
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/config.py,sha256=972919b821b9b7e5dc7cd191ba7e78b30b6efa5d63514e8cb301996d6386392c,369
|
10
10
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/event_emitter.py,sha256=812b3ea1c5a04412113d4dd770717561861595f9eec5b94dd8174c6ddfb7572a,6831
|
11
11
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/event_models.py,sha256=3c27c21b1aeb02bc19a91fb8c05717ae1c10ab4b01300c664aba42e0f50cb5a3,876
|
@@ -13,23 +13,23 @@ lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/span_utils.py,sha
|
|
13
13
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/streaming.py,sha256=e999ad093275c5195b5d31dfea456726afd5f474cd779be7af892f54d7b416b8,10129
|
14
14
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/utils.py,sha256=0044f02da8b99322fdbf3f8f6663f04ff5d1295ddae92a635fd16eb685d5fbb6,5386
|
15
15
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/version.py,sha256=5aacde4ca55ef50ed07a239ad8a86889e0621b1cc72be19bd93be7c9e20910a9,23
|
16
|
-
lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/__init__.py,sha256=
|
16
|
+
lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/__init__.py,sha256=7d2cfb6007cbed2c9809f07911d42e07cc2a520ddafb384bd7a750a75b6fd92a,20316
|
17
17
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/config.py,sha256=db9cdebc9ee0dccb493ffe608eede3047efec20ed26c3924b72b2e50edbd92c2,245
|
18
18
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/schema_utils.py,sha256=857a6bc52f8bfd4da72786173615d31faaf3f9378f8f6150ffe8f6f9c4bb78f9,685
|
19
19
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/utils.py,sha256=f1248196246826d899304e510c4c2df74088d8169d28f1d0aed578a7a6c3cbfd,7669
|
20
|
-
lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/__init__.py,sha256=
|
20
|
+
lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/__init__.py,sha256=1e98467711405e4ff8ccd0b53c002e7a676c581616ef015e8b6606bd7057478b,14986
|
21
21
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/config.py,sha256=29d557d9dee56354e89634bdc3f4795f346ee67bbfec56184b4fb394e45a7e03,203
|
22
22
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/event_emitter.py,sha256=1f07d78bf360832951c708fcb3737718e50d39ce05beb8adbf57e818b4873703,4481
|
23
23
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/event_models.py,sha256=3c27c21b1aeb02bc19a91fb8c05717ae1c10ab4b01300c664aba42e0f50cb5a3,876
|
24
24
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/span_utils.py,sha256=7a1cd03539ff2c9e5114a26483dc50066cd5f1b7283e584431dd036949e1f31b,7461
|
25
25
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/utils.py,sha256=139f085a337ae321f68822bbbd2400bfc008c4d6a706ab319e522bef6b91e552,2360
|
26
26
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/version.py,sha256=5aacde4ca55ef50ed07a239ad8a86889e0621b1cc72be19bd93be7c9e20910a9,23
|
27
|
-
lmnr/opentelemetry_lib/opentelemetry/instrumentation/langgraph/__init__.py,sha256=
|
27
|
+
lmnr/opentelemetry_lib/opentelemetry/instrumentation/langgraph/__init__.py,sha256=b77a70771741b95006cb27d7f9fc26e4b79b1f10ca24b93a3160a458c3397a9d,3313
|
28
28
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/langgraph/utils.py,sha256=9dff6c2595e79edb38818668aed1220efc188d8a982594c04f4ceeb6e3ff47a6,1512
|
29
29
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/__init__.py,sha256=8b91dc16af927eee75b969c0980c606680b347a87f8533bc0f4a092e5ec6e5c9,2071
|
30
30
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/__init__.py,sha256=dcc910aa6df02263cad89c1feac2aa21e316fdd6b491ebca2b93fd24a5149625,14911
|
31
|
-
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/chat_wrappers.py,sha256=
|
32
|
-
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/completion_wrappers.py,sha256=
|
31
|
+
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/chat_wrappers.py,sha256=59438bac0abb79bc7e5868a8bf5b975ff4e956fa31bf0569e0839b876188ef4a,33571
|
32
|
+
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/completion_wrappers.py,sha256=1ac4a2f05e9c548b19fa66b71208bb40b5585876d3ce4835ae8998fb94ad472a,9329
|
33
33
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/config.py,sha256=8016e4af0291a77484ce88d7d1ca06146b1229ae0e0a0f46e042faf75b456a8f,507
|
34
34
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/embeddings_wrappers.py,sha256=345c4c795019418b9c7cbf4e571689b566f2b0e350579b48fd2f5f2535351586,9076
|
35
35
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/event_emitter.py,sha256=9c96455b5ca2064dd3a9fb570d78b14ebbdf3d02f8e33255ee9e301c31336c9e,3043
|
@@ -38,37 +38,38 @@ lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/image_gen_wra
|
|
38
38
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/utils.py,sha256=541e94d60c94b8a8035ee74cda00ca3576a3f50a215df03d948de58665dbc25b,4649
|
39
39
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v0/__init__.py,sha256=7f43421e052bd8f64d5d5b03170a3b7187c2ce038362fa15b5d1d0c43bc1a40d,6143
|
40
40
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/__init__.py,sha256=662afd935c52b42512280614bf502554389c8854ab1256efbfde03fe364dac64,12932
|
41
|
-
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/assistant_wrappers.py,sha256=
|
41
|
+
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/assistant_wrappers.py,sha256=0284307113b148b1d59d5b9bd922cbf89679e8a466800f8022e0973b4e92fccf,10260
|
42
42
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/event_handler_wrapper.py,sha256=18d106e77f26ebb233bf3379edf3116540891d643be72be73ea47be3724a89b8,4211
|
43
|
-
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/responses_wrappers.py,sha256=
|
43
|
+
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/responses_wrappers.py,sha256=059b28106e2f473dd361e3cf85ef2db54f2aaaa8092286a03d589d4d337d8bc9,24062
|
44
44
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/version.py,sha256=4f39aaa913f3e49b0c174bc23028687d00bfaffc745bd3fe241e0ae6b442bed1,24
|
45
45
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/opentelemetry/__init__.py,sha256=1f86cdf738e2f68586b0a4569bb1e40edddd85c529f511ef49945ddb7b61fab5,2648
|
46
46
|
lmnr/opentelemetry_lib/opentelemetry/instrumentation/skyvern/__init__.py,sha256=764e4fe979fb08d7821419a3cc5c3ae89a6664b626ef928259f8f175c939eaea,6334
|
47
|
-
lmnr/opentelemetry_lib/
|
47
|
+
lmnr/opentelemetry_lib/opentelemetry/instrumentation/threading/__init__.py,sha256=90aa8558467d7e469fe1a6c75372c113da403557715f03b522b2fab94b287c40,6320
|
48
|
+
lmnr/opentelemetry_lib/tracing/__init__.py,sha256=a39e9a48f8a842ce7f7ec53364d793c1a303dcfd485aee7a72ade07d1b3635a2,9662
|
48
49
|
lmnr/opentelemetry_lib/tracing/_instrument_initializers.py,sha256=a15a46a0515462319195a96f7cdb695e72a1559c3212964f5883ab824031bf70,15125
|
49
50
|
lmnr/opentelemetry_lib/tracing/attributes.py,sha256=32fa30565b977c2a92202dc2bf1ded583a81d02a6bf5ba52958f75a8be08cbbe,1497
|
50
|
-
lmnr/opentelemetry_lib/tracing/
|
51
|
+
lmnr/opentelemetry_lib/tracing/context.py,sha256=33d133a396af8585e51597ed58b28e8efe4ae688b71b85b4dbff920465ec84f6,3428
|
51
52
|
lmnr/opentelemetry_lib/tracing/exporter.py,sha256=6af8e61fd873e8f5db315d9b9f1edbf46b860ba7e50140f0bdcc6864c6d35a03,2082
|
52
53
|
lmnr/opentelemetry_lib/tracing/instruments.py,sha256=e3c12315bda301416d1f3bc8d354ad16d4da211e2ecfa019265f4b565307c118,5655
|
53
|
-
lmnr/opentelemetry_lib/tracing/processor.py,sha256=
|
54
|
-
lmnr/opentelemetry_lib/tracing/tracer.py,sha256=
|
54
|
+
lmnr/opentelemetry_lib/tracing/processor.py,sha256=fd11e4d48eb5932f47898b8f70b8b5880f7ee7e58478f1ef20caff20e1f34252,3381
|
55
|
+
lmnr/opentelemetry_lib/tracing/tracer.py,sha256=33769a9a97385f5697eb0e0a6b1813a57ed956c7a8379d7ac2523e700e7dd528,1362
|
55
56
|
lmnr/opentelemetry_lib/utils/__init__.py,sha256=a4d85fd06def4dde5c728734de2d4c5c36eb89c49a8aa09b8b50cb5a149e90af,604
|
56
57
|
lmnr/opentelemetry_lib/utils/json_encoder.py,sha256=74ae9bfdac6bef42182fb56ff9bbb8c27b6f0c3bb29eda2ab0769d76a5fb3f9f,463
|
57
58
|
lmnr/opentelemetry_lib/utils/package_check.py,sha256=f8274186c96815c996a25fae06bf913f0bb7c835507739949f37c03bbe5d9ca9,527
|
58
59
|
lmnr/py.typed,sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,0
|
59
60
|
lmnr/sdk/__init__.py,sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,0
|
60
61
|
lmnr/sdk/browser/__init__.py,sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,0
|
61
|
-
lmnr/sdk/browser/browser_use_otel.py,sha256=
|
62
|
-
lmnr/sdk/browser/patchright_otel.py,sha256=
|
63
|
-
lmnr/sdk/browser/playwright_otel.py,sha256=
|
64
|
-
lmnr/sdk/browser/pw_utils.py,sha256=
|
62
|
+
lmnr/sdk/browser/browser_use_otel.py,sha256=37d26de1af37f76774af176cb226e0b04988fc3bf419a2fd899ad36e79562fad,5104
|
63
|
+
lmnr/sdk/browser/patchright_otel.py,sha256=9d22ab1f28f1eddbcfd0032a14fe306bfe00bfc7f11128cb99836c4dd15fb7c8,4800
|
64
|
+
lmnr/sdk/browser/playwright_otel.py,sha256=50c0a5a75155a3a7ff5db84790ffb409c9cbd0351eef212d83d923893730223b,9459
|
65
|
+
lmnr/sdk/browser/pw_utils.py,sha256=63364e31b31734a1a941847289ba5f00902c13181ce1ef624c73c25dcbc26b3c,22297
|
65
66
|
lmnr/sdk/browser/rrweb/rrweb.umd.min.cjs,sha256=2f2da38b00bb85312d8225f3069a09352135564ceed2564f652f1bae3bac016d,260896
|
66
67
|
lmnr/sdk/browser/utils.py,sha256=4a668776d2938108d25fbcecd61c8e1710a4da3e56230d5fefca5964dd09e3c1,2371
|
67
68
|
lmnr/sdk/client/asynchronous/async_client.py,sha256=e8feae007506cd2e4b08e72706f5f1bb4ea54492b4aa6b68ef184a129de8f466,4948
|
68
69
|
lmnr/sdk/client/asynchronous/resources/__init__.py,sha256=993423ea462aa8ea37d8d91662341c1ca0711cb2447cd476aacc373858f76135,481
|
69
70
|
lmnr/sdk/client/asynchronous/resources/agent.py,sha256=3a78372b62912cdeda831d7ff9a671306713fce185dff646b452e6f1a3cc6d8c,17788
|
70
71
|
lmnr/sdk/client/asynchronous/resources/base.py,sha256=689e37435ae5b60db7210688e1e79a64a724c554e00d46c226b0a18500941281,986
|
71
|
-
lmnr/sdk/client/asynchronous/resources/browser_events.py,sha256=
|
72
|
+
lmnr/sdk/client/asynchronous/resources/browser_events.py,sha256=76f4d7599ee54c0592198585301adc2e9c338398332eb11e445f763f4ab4c7ca,1164
|
72
73
|
lmnr/sdk/client/asynchronous/resources/evals.py,sha256=8c6f8096916657ef269463b2d0585795d9cedad056a047abcde6365ff0b320bd,5761
|
73
74
|
lmnr/sdk/client/asynchronous/resources/evaluators.py,sha256=964046f5146e89032fbb701b883f4f3a7cb996aeb9ff368f86e8f967df2fef10,2918
|
74
75
|
lmnr/sdk/client/asynchronous/resources/tags.py,sha256=14fc2e38cae2f6fe126dc8dca085d7ad02d8d7c1a09bc4b5b5b8e38a0edf7348,2314
|
@@ -84,12 +85,12 @@ lmnr/sdk/datasets.py,sha256=3fd851c5f97bf88eaa84b1451a053eaff23b4497cbb45eac2f9e
|
|
84
85
|
lmnr/sdk/decorators.py,sha256=0c6b95b92ec8023f28cd15ddc47849888fa91f2534d575f626e3557f5f0a0c02,6451
|
85
86
|
lmnr/sdk/eval_control.py,sha256=291394ac385c653ae9b5167e871bebeb4fe8fc6b7ff2ed38e636f87015dcba86,184
|
86
87
|
lmnr/sdk/evaluations.py,sha256=b41f7737b084dc5b64b2952659b729622e0918fd492bfcddde7177d1a1c690ae,22572
|
87
|
-
lmnr/sdk/laminar.py,sha256=
|
88
|
+
lmnr/sdk/laminar.py,sha256=7e63c547dc5a5fa15967fe374ef60463234f41eac0936a2bfeb3e1bb159cc6fd,33388
|
88
89
|
lmnr/sdk/log.py,sha256=9edfd83263f0d4845b1b2d1beeae2b4ed3f8628de941f371a893d72b79c348d4,2213
|
89
|
-
lmnr/sdk/types.py,sha256=
|
90
|
+
lmnr/sdk/types.py,sha256=116fd2f8cfa2985c4ae5b9ca021b702975ec9aff614e0e9e24d13b89abd61c16,12258
|
90
91
|
lmnr/sdk/utils.py,sha256=4beb884ae6fbbc7d8cf639b036b726ea6a2a658f0a6386faf5735a13d706a2d8,5039
|
91
|
-
lmnr/version.py,sha256=
|
92
|
-
lmnr-0.
|
93
|
-
lmnr-0.
|
94
|
-
lmnr-0.
|
95
|
-
lmnr-0.
|
92
|
+
lmnr/version.py,sha256=54170fa0ec116bd0098e49eb35a28551fd5ec28ab1414e05b2d2dee3979404e5,1321
|
93
|
+
lmnr-0.7.0.dist-info/WHEEL,sha256=ab6157bc637547491fb4567cd7ddf26b04d63382916ca16c29a5c8e94c9c9ef7,79
|
94
|
+
lmnr-0.7.0.dist-info/entry_points.txt,sha256=abdf3411b7dd2d7329a241f2da6669bab4e314a747a586ecdb9f888f3035003c,39
|
95
|
+
lmnr-0.7.0.dist-info/METADATA,sha256=a7e7ad2b1a865c39bfc75358dd0f0da33975534dcfc6cbbea2ca4b0d3406766e,14473
|
96
|
+
lmnr-0.7.0.dist-info/RECORD,,
|