lmnr 0.4.21b0__py3-none-any.whl → 0.4.23__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 +1 -0
- lmnr/sdk/laminar.py +36 -2
- lmnr/traceloop_sdk/decorators/base.py +7 -4
- lmnr/traceloop_sdk/tracing/attributes.py +14 -0
- {lmnr-0.4.21b0.dist-info → lmnr-0.4.23.dist-info}/METADATA +26 -25
- {lmnr-0.4.21b0.dist-info → lmnr-0.4.23.dist-info}/RECORD +9 -9
- {lmnr-0.4.21b0.dist-info → lmnr-0.4.23.dist-info}/WHEEL +1 -1
- {lmnr-0.4.21b0.dist-info → lmnr-0.4.23.dist-info}/LICENSE +0 -0
- {lmnr-0.4.21b0.dist-info → lmnr-0.4.23.dist-info}/entry_points.txt +0 -0
lmnr/__init__.py
CHANGED
lmnr/sdk/laminar.py
CHANGED
@@ -9,11 +9,13 @@ from opentelemetry.util.types import AttributeValue
|
|
9
9
|
from opentelemetry.context import set_value, attach, detach
|
10
10
|
from lmnr.traceloop_sdk import Traceloop
|
11
11
|
from lmnr.traceloop_sdk.tracing import get_tracer
|
12
|
+
from lmnr.traceloop_sdk.tracing.attributes import Attributes, SPAN_TYPE
|
13
|
+
from lmnr.traceloop_sdk.decorators.base import json_dumps
|
12
14
|
from contextlib import contextmanager
|
13
15
|
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
|
14
16
|
|
15
17
|
from pydantic.alias_generators import to_snake
|
16
|
-
from typing import Any, Optional, Set, Union
|
18
|
+
from typing import Any, Literal, Optional, Set, Union
|
17
19
|
|
18
20
|
import copy
|
19
21
|
import datetime
|
@@ -279,6 +281,7 @@ class Laminar:
|
|
279
281
|
cls,
|
280
282
|
name: str,
|
281
283
|
input: Any = None,
|
284
|
+
span_type: Union[Literal["DEFAULT"], Literal["LLM"]] = "DEFAULT",
|
282
285
|
):
|
283
286
|
"""Start a new span as the current span. Useful for manual
|
284
287
|
instrumentation.
|
@@ -287,6 +290,7 @@ class Laminar:
|
|
287
290
|
```python
|
288
291
|
with Laminar.start_as_current_span("my_span", input="my_input") as span:
|
289
292
|
await my_async_function()
|
293
|
+
Laminar.set_span_output("my_output")`
|
290
294
|
```
|
291
295
|
|
292
296
|
Args:
|
@@ -308,6 +312,7 @@ class Laminar:
|
|
308
312
|
SPAN_INPUT,
|
309
313
|
json.dumps(input),
|
310
314
|
)
|
315
|
+
span.set_attribute(SPAN_TYPE, span_type)
|
311
316
|
yield span
|
312
317
|
|
313
318
|
# TODO: Figure out if this is necessary
|
@@ -327,7 +332,36 @@ class Laminar:
|
|
327
332
|
"""
|
328
333
|
span = get_current_span()
|
329
334
|
if output is not None and span != INVALID_SPAN:
|
330
|
-
span.set_attribute(SPAN_OUTPUT,
|
335
|
+
span.set_attribute(SPAN_OUTPUT, json_dumps(output))
|
336
|
+
|
337
|
+
@classmethod
|
338
|
+
def set_span_attributes(
|
339
|
+
cls,
|
340
|
+
attributes: dict[Attributes, Any],
|
341
|
+
):
|
342
|
+
"""Set attributes for the current span. Useful for manual
|
343
|
+
instrumentation.
|
344
|
+
|
345
|
+
Args:
|
346
|
+
attributes (dict[ATTRIBUTES, Any]): attributes to set for the span
|
347
|
+
"""
|
348
|
+
span = get_current_span()
|
349
|
+
if span == INVALID_SPAN:
|
350
|
+
return
|
351
|
+
|
352
|
+
for key, value in attributes.items():
|
353
|
+
# Python 3.12+ should do: if key not in Attributes:
|
354
|
+
try:
|
355
|
+
Attributes(key.value)
|
356
|
+
except (TypeError, AttributeError):
|
357
|
+
cls.__logger.warning(
|
358
|
+
f"Attribute {key} is not a valid Laminar attribute."
|
359
|
+
)
|
360
|
+
continue
|
361
|
+
if not isinstance(value, (str, int, float, bool)):
|
362
|
+
span.set_attribute(key.value, json_dumps(value))
|
363
|
+
else:
|
364
|
+
span.set_attribute(key.value, value)
|
331
365
|
|
332
366
|
@classmethod
|
333
367
|
def set_session(
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import json
|
2
2
|
from functools import wraps
|
3
3
|
import os
|
4
|
+
import pydantic
|
4
5
|
import types
|
5
6
|
from typing import Any, Optional
|
6
7
|
import warnings
|
@@ -17,13 +18,15 @@ from lmnr.traceloop_sdk.utils.json_encoder import JSONEncoder
|
|
17
18
|
|
18
19
|
class CustomJSONEncoder(JSONEncoder):
|
19
20
|
def default(self, o: Any) -> Any:
|
21
|
+
if isinstance(o, pydantic.BaseModel):
|
22
|
+
return o.model_dump_json()
|
20
23
|
try:
|
21
24
|
return super().default(o)
|
22
25
|
except TypeError:
|
23
26
|
return str(o) # Fallback to string representation for unsupported types
|
24
27
|
|
25
28
|
|
26
|
-
def
|
29
|
+
def json_dumps(data: dict) -> str:
|
27
30
|
try:
|
28
31
|
with warnings.catch_warnings():
|
29
32
|
warnings.simplefilter("ignore", RuntimeWarning)
|
@@ -59,7 +62,7 @@ def entity_method(
|
|
59
62
|
if _should_send_prompts():
|
60
63
|
span.set_attribute(
|
61
64
|
SPAN_INPUT,
|
62
|
-
|
65
|
+
json_dumps(
|
63
66
|
get_input_from_func_args(
|
64
67
|
fn, is_method(fn), args, kwargs
|
65
68
|
)
|
@@ -78,7 +81,7 @@ def entity_method(
|
|
78
81
|
if _should_send_prompts():
|
79
82
|
span.set_attribute(
|
80
83
|
SPAN_OUTPUT,
|
81
|
-
|
84
|
+
json_dumps(res),
|
82
85
|
)
|
83
86
|
except TypeError:
|
84
87
|
pass
|
@@ -121,7 +124,7 @@ def aentity_method(
|
|
121
124
|
if _should_send_prompts():
|
122
125
|
span.set_attribute(
|
123
126
|
SPAN_INPUT,
|
124
|
-
|
127
|
+
json_dumps(
|
125
128
|
get_input_from_func_args(
|
126
129
|
fn, is_method(fn), args, kwargs
|
127
130
|
)
|
@@ -1,3 +1,6 @@
|
|
1
|
+
from enum import Enum
|
2
|
+
from opentelemetry.semconv_ai import SpanAttributes
|
3
|
+
|
1
4
|
SPAN_INPUT = "lmnr.span.input"
|
2
5
|
SPAN_OUTPUT = "lmnr.span.output"
|
3
6
|
SPAN_TYPE = "lmnr.span.type"
|
@@ -7,3 +10,14 @@ ASSOCIATION_PROPERTIES = "lmnr.association.properties"
|
|
7
10
|
SESSION_ID = "session_id"
|
8
11
|
USER_ID = "user_id"
|
9
12
|
TRACE_TYPE = "trace_type"
|
13
|
+
|
14
|
+
|
15
|
+
# exposed to the user, configurable
|
16
|
+
class Attributes(Enum):
|
17
|
+
# not SpanAttributes.LLM_USAGE_PROMPT_TOKENS,
|
18
|
+
INPUT_TOKEN_COUNT = "gen_ai.usage.input_tokens"
|
19
|
+
# not SpanAttributes.LLM_USAGE_COMPLETION_TOKENS,
|
20
|
+
OUTPUT_TOKEN_COUNT = "gen_ai.usage.output_tokens"
|
21
|
+
PROVIDER = SpanAttributes.LLM_SYSTEM
|
22
|
+
REQUEST_MODEL = SpanAttributes.LLM_REQUEST_MODEL
|
23
|
+
RESPONSE_MODEL = SpanAttributes.LLM_RESPONSE_MODEL
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: lmnr
|
3
|
-
Version: 0.4.
|
3
|
+
Version: 0.4.23
|
4
4
|
Summary: Python SDK for Laminar AI
|
5
5
|
License: Apache-2.0
|
6
6
|
Author: lmnr.ai
|
@@ -11,6 +11,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.10
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
14
15
|
Requires-Dist: argparse (>=1.0,<2.0)
|
15
16
|
Requires-Dist: backoff (>=2.0,<3.0)
|
16
17
|
Requires-Dist: deprecated (>=1.0,<2.0)
|
@@ -18,34 +19,34 @@ Requires-Dist: jinja2 (>=3.0,<4.0)
|
|
18
19
|
Requires-Dist: opentelemetry-api (>=1.27.0,<2.0.0)
|
19
20
|
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc (>=1.27.0,<2.0.0)
|
20
21
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http (>=1.27.0,<2.0.0)
|
21
|
-
Requires-Dist: opentelemetry-instrumentation-alephalpha (>=0.
|
22
|
-
Requires-Dist: opentelemetry-instrumentation-anthropic (>=0.
|
23
|
-
Requires-Dist: opentelemetry-instrumentation-bedrock (>=0.
|
24
|
-
Requires-Dist: opentelemetry-instrumentation-chromadb (>=0.
|
25
|
-
Requires-Dist: opentelemetry-instrumentation-cohere (>=0.
|
26
|
-
Requires-Dist: opentelemetry-instrumentation-google-generativeai (>=0.
|
27
|
-
Requires-Dist: opentelemetry-instrumentation-groq (>=0.
|
28
|
-
Requires-Dist: opentelemetry-instrumentation-haystack (>=0.
|
29
|
-
Requires-Dist: opentelemetry-instrumentation-lancedb (>=0.
|
30
|
-
Requires-Dist: opentelemetry-instrumentation-langchain (>=0.
|
31
|
-
Requires-Dist: opentelemetry-instrumentation-llamaindex (>=0.
|
32
|
-
Requires-Dist: opentelemetry-instrumentation-marqo (>=0.
|
33
|
-
Requires-Dist: opentelemetry-instrumentation-milvus (>=0.
|
34
|
-
Requires-Dist: opentelemetry-instrumentation-mistralai (>=0.
|
35
|
-
Requires-Dist: opentelemetry-instrumentation-ollama (>=0.
|
36
|
-
Requires-Dist: opentelemetry-instrumentation-openai (>=0.
|
37
|
-
Requires-Dist: opentelemetry-instrumentation-pinecone (>=0.
|
38
|
-
Requires-Dist: opentelemetry-instrumentation-qdrant (>=0.
|
39
|
-
Requires-Dist: opentelemetry-instrumentation-replicate (>=0.
|
22
|
+
Requires-Dist: opentelemetry-instrumentation-alephalpha (>=0.33.1)
|
23
|
+
Requires-Dist: opentelemetry-instrumentation-anthropic (>=0.33.1)
|
24
|
+
Requires-Dist: opentelemetry-instrumentation-bedrock (>=0.33.1)
|
25
|
+
Requires-Dist: opentelemetry-instrumentation-chromadb (>=0.33.1)
|
26
|
+
Requires-Dist: opentelemetry-instrumentation-cohere (>=0.33.1)
|
27
|
+
Requires-Dist: opentelemetry-instrumentation-google-generativeai (>=0.33.1)
|
28
|
+
Requires-Dist: opentelemetry-instrumentation-groq (>=0.33.1)
|
29
|
+
Requires-Dist: opentelemetry-instrumentation-haystack (>=0.33.1)
|
30
|
+
Requires-Dist: opentelemetry-instrumentation-lancedb (>=0.33.1)
|
31
|
+
Requires-Dist: opentelemetry-instrumentation-langchain (>=0.33.1)
|
32
|
+
Requires-Dist: opentelemetry-instrumentation-llamaindex (>=0.33.1)
|
33
|
+
Requires-Dist: opentelemetry-instrumentation-marqo (>=0.33.1)
|
34
|
+
Requires-Dist: opentelemetry-instrumentation-milvus (>=0.33.1)
|
35
|
+
Requires-Dist: opentelemetry-instrumentation-mistralai (>=0.33.1)
|
36
|
+
Requires-Dist: opentelemetry-instrumentation-ollama (>=0.33.1)
|
37
|
+
Requires-Dist: opentelemetry-instrumentation-openai (>=0.33.1)
|
38
|
+
Requires-Dist: opentelemetry-instrumentation-pinecone (>=0.33.1)
|
39
|
+
Requires-Dist: opentelemetry-instrumentation-qdrant (>=0.33.1)
|
40
|
+
Requires-Dist: opentelemetry-instrumentation-replicate (>=0.33.1)
|
40
41
|
Requires-Dist: opentelemetry-instrumentation-requests (>=0.48b0,<0.49)
|
41
42
|
Requires-Dist: opentelemetry-instrumentation-sqlalchemy (>=0.48b0,<0.49)
|
42
43
|
Requires-Dist: opentelemetry-instrumentation-threading (>=0.48b0,<0.49)
|
43
|
-
Requires-Dist: opentelemetry-instrumentation-together (>=0.
|
44
|
-
Requires-Dist: opentelemetry-instrumentation-transformers (>=0.
|
44
|
+
Requires-Dist: opentelemetry-instrumentation-together (>=0.33.1)
|
45
|
+
Requires-Dist: opentelemetry-instrumentation-transformers (>=0.33.1)
|
45
46
|
Requires-Dist: opentelemetry-instrumentation-urllib3 (>=0.48b0,<0.49)
|
46
|
-
Requires-Dist: opentelemetry-instrumentation-vertexai (>=0.
|
47
|
-
Requires-Dist: opentelemetry-instrumentation-watsonx (>=0.
|
48
|
-
Requires-Dist: opentelemetry-instrumentation-weaviate (>=0.
|
47
|
+
Requires-Dist: opentelemetry-instrumentation-vertexai (>=0.33.1)
|
48
|
+
Requires-Dist: opentelemetry-instrumentation-watsonx (>=0.33.1)
|
49
|
+
Requires-Dist: opentelemetry-instrumentation-weaviate (>=0.33.1)
|
49
50
|
Requires-Dist: opentelemetry-sdk (>=1.27.0,<2.0.0)
|
50
51
|
Requires-Dist: opentelemetry-semantic-conventions-ai (==0.4.1)
|
51
52
|
Requires-Dist: pydantic (>=2.7,<3.0)
|
@@ -1,9 +1,9 @@
|
|
1
|
-
lmnr/__init__.py,sha256
|
1
|
+
lmnr/__init__.py,sha256=-MdXpUkDNhqJaQ5AVdBohIDQgGmeov_xwwtwErwXnQg,288
|
2
2
|
lmnr/cli.py,sha256=Ptvm5dsNLKUY5lwnN8XkT5GtCYjzpRNi2WvefknB3OQ,1079
|
3
3
|
lmnr/sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
4
|
lmnr/sdk/decorators.py,sha256=ZSDaEZyjo-RUzRCltsNbe6x0t9SKl2xRQ2q4uaKvXtk,2250
|
5
5
|
lmnr/sdk/evaluations.py,sha256=C2lhrevH3PDvnTX-qfop1k-NTqTFX4MWaSkc9oG5kxc,15199
|
6
|
-
lmnr/sdk/laminar.py,sha256=
|
6
|
+
lmnr/sdk/laminar.py,sha256=IoQ_4DJGysKn7tEFZk3ILdRWGxmHvDPzxzXgNZifyws,16293
|
7
7
|
lmnr/sdk/log.py,sha256=EgAMY77Zn1bv1imCqrmflD3imoAJ2yveOkIcrIP3e98,1170
|
8
8
|
lmnr/sdk/types.py,sha256=HvaZEqVRduCZbkF7Cp8rgS5oBbc1qPvOD3PP9tFrRu4,4826
|
9
9
|
lmnr/sdk/utils.py,sha256=s81p6uJehgJSaLWy3sR5fTpEDH7vzn3i_UujUHChl6M,3346
|
@@ -12,7 +12,7 @@ lmnr/traceloop_sdk/.python-version,sha256=9OLQBQVbD4zE4cJsPePhnAfV_snrPSoqEQw-PX
|
|
12
12
|
lmnr/traceloop_sdk/__init__.py,sha256=hp3q1OsFaGgaQCEanJrL38BJN32hWqCNVCSjYpndEsY,2957
|
13
13
|
lmnr/traceloop_sdk/config/__init__.py,sha256=DliMGp2NjYAqRFLKpWQPUKjGMHRO8QsVfazBA1qENQ8,248
|
14
14
|
lmnr/traceloop_sdk/decorators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
|
-
lmnr/traceloop_sdk/decorators/base.py,sha256
|
15
|
+
lmnr/traceloop_sdk/decorators/base.py,sha256=ZkvzVJfO4fOxRHwPobPL2ryW32nZjgO7cX7CXouyUnY,5621
|
16
16
|
lmnr/traceloop_sdk/instruments.py,sha256=oMvIASueW3GeChpjIdH-DD9aFBVB8OtHZ0HawppTrlI,942
|
17
17
|
lmnr/traceloop_sdk/tests/__init__.py,sha256=RYnG0-8zbXL0-2Ste1mEBf5sN4d_rQjGTCgPBuaZC74,20
|
18
18
|
lmnr/traceloop_sdk/tests/cassettes/test_association_properties/test_langchain_and_external_association_properties.yaml,sha256=26g0wRA0juicHg_XrhcE8H4vhs1lawDs0o0aLFn-I7w,3103
|
@@ -35,7 +35,7 @@ lmnr/traceloop_sdk/tests/test_sdk_initialization.py,sha256=fRaf6lrxFzJIN94P1Tav_
|
|
35
35
|
lmnr/traceloop_sdk/tests/test_tasks.py,sha256=xlEx8BKp4yG83SCjK5WkPGfyC33JSrx4h8VyjVwGbgw,906
|
36
36
|
lmnr/traceloop_sdk/tests/test_workflows.py,sha256=RVcfY3WAFIDZC15-aSua21aoQyYeWE7KypDyUsm-2EM,9372
|
37
37
|
lmnr/traceloop_sdk/tracing/__init__.py,sha256=Ckq7zCM26VdJVB5tIZv0GTPyMZKyfso_KWD5yPHaqdo,66
|
38
|
-
lmnr/traceloop_sdk/tracing/attributes.py,sha256=
|
38
|
+
lmnr/traceloop_sdk/tracing/attributes.py,sha256=YBxDZ-9I9QlnehcCIUQcpeHTtv4gPU3vDtct7SqQ06Q,746
|
39
39
|
lmnr/traceloop_sdk/tracing/content_allow_list.py,sha256=3feztm6PBWNelc8pAZUcQyEGyeSpNiVKjOaDk65l2ps,846
|
40
40
|
lmnr/traceloop_sdk/tracing/context_manager.py,sha256=csVlB6kDmbgSPsROHwnddvGGblx55v6lJMRj0wsSMQM,304
|
41
41
|
lmnr/traceloop_sdk/tracing/tracing.py,sha256=_HDLuyy4XgobC1ig4qz5jYbB4tWAZSfD6gbgUqwmYJU,35522
|
@@ -44,8 +44,8 @@ lmnr/traceloop_sdk/utils/in_memory_span_exporter.py,sha256=H_4TRaThMO1H6vUQ0OpQv
|
|
44
44
|
lmnr/traceloop_sdk/utils/json_encoder.py,sha256=dK6b_axr70IYL7Vv-bu4wntvDDuyntoqsHaddqX7P58,463
|
45
45
|
lmnr/traceloop_sdk/utils/package_check.py,sha256=TZSngzJOpFhfUZLXIs38cpMxQiZSmp0D-sCrIyhz7BA,251
|
46
46
|
lmnr/traceloop_sdk/version.py,sha256=OlatFEFA4ttqSSIiV8jdE-sq3KG5zu2hnC4B4mzWF3s,23
|
47
|
-
lmnr-0.4.
|
48
|
-
lmnr-0.4.
|
49
|
-
lmnr-0.4.
|
50
|
-
lmnr-0.4.
|
51
|
-
lmnr-0.4.
|
47
|
+
lmnr-0.4.23.dist-info/LICENSE,sha256=67b_wJHVV1CBaWkrKFWU1wyqTPSdzH77Ls-59631COg,10411
|
48
|
+
lmnr-0.4.23.dist-info/METADATA,sha256=BOAKiIyn49ReowUuPFpmqRYhgiQlK6CUSEEipTreYbo,10493
|
49
|
+
lmnr-0.4.23.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
50
|
+
lmnr-0.4.23.dist-info/entry_points.txt,sha256=K1jE20ww4jzHNZLnsfWBvU3YKDGBgbOiYG5Y7ivQcq4,37
|
51
|
+
lmnr-0.4.23.dist-info/RECORD,,
|
File without changes
|
File without changes
|