lmnr 0.5.3__tar.gz → 0.6.1__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.
- {lmnr-0.5.3 → lmnr-0.6.1}/PKG-INFO +65 -62
- lmnr-0.6.1/pyproject.toml +137 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/__init__.py +6 -1
- lmnr-0.6.1/src/lmnr/opentelemetry_lib/__init__.py +62 -0
- lmnr-0.5.3/src/lmnr/opentelemetry_lib/decorators/base.py → lmnr-0.6.1/src/lmnr/opentelemetry_lib/decorators/__init__.py +22 -13
- lmnr-0.6.1/src/lmnr/opentelemetry_lib/tracing/__init__.py +158 -0
- lmnr-0.6.1/src/lmnr/opentelemetry_lib/tracing/_instrument_initializers.py +398 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/opentelemetry_lib/tracing/attributes.py +14 -7
- lmnr-0.6.1/src/lmnr/opentelemetry_lib/tracing/context_properties.py +53 -0
- lmnr-0.6.1/src/lmnr/opentelemetry_lib/tracing/exporter.py +60 -0
- lmnr-0.6.1/src/lmnr/opentelemetry_lib/tracing/instruments.py +121 -0
- lmnr-0.6.1/src/lmnr/opentelemetry_lib/tracing/processor.py +96 -0
- lmnr-0.5.3/src/lmnr/opentelemetry_lib/tracing/context_manager.py → lmnr-0.6.1/src/lmnr/opentelemetry_lib/tracing/tracer.py +6 -1
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/opentelemetry_lib/utils/package_check.py +3 -1
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/browser/browser_use_otel.py +1 -1
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/browser/playwright_otel.py +22 -7
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/browser/pw_utils.py +25 -9
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/client/asynchronous/resources/agent.py +3 -1
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/client/synchronous/resources/agent.py +3 -1
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/decorators.py +4 -2
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/evaluations.py +3 -3
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/laminar.py +28 -31
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/utils.py +2 -3
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/version.py +1 -1
- lmnr-0.5.3/pyproject.toml +0 -129
- lmnr-0.5.3/src/lmnr/opentelemetry_lib/__init__.py +0 -75
- lmnr-0.5.3/src/lmnr/opentelemetry_lib/config/__init__.py +0 -12
- lmnr-0.5.3/src/lmnr/opentelemetry_lib/instruments.py +0 -42
- lmnr-0.5.3/src/lmnr/opentelemetry_lib/tracing/__init__.py +0 -1
- lmnr-0.5.3/src/lmnr/opentelemetry_lib/tracing/content_allow_list.py +0 -24
- lmnr-0.5.3/src/lmnr/opentelemetry_lib/tracing/tracing.py +0 -1016
- lmnr-0.5.3/src/lmnr/opentelemetry_lib/utils/in_memory_span_exporter.py +0 -61
- lmnr-0.5.3/src/lmnr/sdk/browser/__init__.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/LICENSE +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/README.md +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/cli.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/opentelemetry_lib/.flake8 +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/__init__.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/config.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/utils.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/opentelemetry_lib/utils/__init__.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/opentelemetry_lib/utils/json_encoder.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/py.typed +0 -0
- {lmnr-0.5.3/src/lmnr/opentelemetry_lib/decorators → lmnr-0.6.1/src/lmnr/sdk}/__init__.py +0 -0
- {lmnr-0.5.3/src/lmnr/sdk → lmnr-0.6.1/src/lmnr/sdk/browser}/__init__.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/browser/patchright_otel.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/browser/rrweb/rrweb.umd.min.cjs +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/browser/utils.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/client/asynchronous/async_client.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/client/asynchronous/resources/__init__.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/client/asynchronous/resources/base.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/client/asynchronous/resources/browser_events.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/client/asynchronous/resources/evals.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/client/synchronous/resources/__init__.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/client/synchronous/resources/base.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/client/synchronous/resources/browser_events.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/client/synchronous/resources/evals.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/client/synchronous/sync_client.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/datasets.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/eval_control.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/log.py +0 -0
- {lmnr-0.5.3 → lmnr-0.6.1}/src/lmnr/sdk/types.py +0 -0
@@ -1,14 +1,13 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: lmnr
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.6.1
|
4
4
|
Summary: Python SDK for Laminar
|
5
5
|
License: Apache-2.0
|
6
6
|
Author: lmnr.ai
|
7
7
|
Author-email: founders@lmnr.ai
|
8
|
-
Requires-Python: >=3.
|
8
|
+
Requires-Python: >=3.10,<4
|
9
9
|
Classifier: License :: OSI Approved :: Apache Software License
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
11
|
-
Classifier: Programming Language :: Python :: 3.9
|
12
11
|
Classifier: Programming Language :: Python :: 3.10
|
13
12
|
Classifier: Programming Language :: Python :: 3.11
|
14
13
|
Classifier: Programming Language :: Python :: 3.12
|
@@ -19,6 +18,7 @@ Provides-Extra: anthropic
|
|
19
18
|
Provides-Extra: bedrock
|
20
19
|
Provides-Extra: chromadb
|
21
20
|
Provides-Extra: cohere
|
21
|
+
Provides-Extra: crewai
|
22
22
|
Provides-Extra: google-generativeai
|
23
23
|
Provides-Extra: groq
|
24
24
|
Provides-Extra: haystack
|
@@ -26,6 +26,7 @@ Provides-Extra: lancedb
|
|
26
26
|
Provides-Extra: langchain
|
27
27
|
Provides-Extra: llamaindex
|
28
28
|
Provides-Extra: marqo
|
29
|
+
Provides-Extra: mcp
|
29
30
|
Provides-Extra: milvus
|
30
31
|
Provides-Extra: mistralai
|
31
32
|
Provides-Extra: ollama
|
@@ -42,65 +43,67 @@ Provides-Extra: weaviate
|
|
42
43
|
Requires-Dist: argparse (>=1.0)
|
43
44
|
Requires-Dist: grpcio (<1.68.0)
|
44
45
|
Requires-Dist: httpx (>=0.25.0)
|
45
|
-
Requires-Dist: opentelemetry-api (>=1.
|
46
|
-
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc (>=1.
|
47
|
-
Requires-Dist: opentelemetry-exporter-otlp-proto-http (>=1.
|
48
|
-
Requires-Dist: opentelemetry-instrumentation-alephalpha (>=0.
|
49
|
-
Requires-Dist: opentelemetry-instrumentation-alephalpha (>=0.
|
50
|
-
Requires-Dist: opentelemetry-instrumentation-anthropic (>=0.
|
51
|
-
Requires-Dist: opentelemetry-instrumentation-anthropic (>=0.
|
52
|
-
Requires-Dist: opentelemetry-instrumentation-bedrock (>=0.
|
53
|
-
Requires-Dist: opentelemetry-instrumentation-bedrock (>=0.
|
54
|
-
Requires-Dist: opentelemetry-instrumentation-chromadb (>=0.
|
55
|
-
Requires-Dist: opentelemetry-instrumentation-chromadb (>=0.
|
56
|
-
Requires-Dist: opentelemetry-instrumentation-cohere (>=0.
|
57
|
-
Requires-Dist: opentelemetry-instrumentation-cohere (>=0.
|
58
|
-
Requires-Dist: opentelemetry-instrumentation-
|
59
|
-
Requires-Dist: opentelemetry-instrumentation-
|
60
|
-
Requires-Dist: opentelemetry-instrumentation-
|
61
|
-
Requires-Dist: opentelemetry-instrumentation-
|
62
|
-
Requires-Dist: opentelemetry-instrumentation-
|
63
|
-
Requires-Dist: opentelemetry-instrumentation-
|
64
|
-
Requires-Dist: opentelemetry-instrumentation-
|
65
|
-
Requires-Dist: opentelemetry-instrumentation-
|
66
|
-
Requires-Dist: opentelemetry-instrumentation-
|
67
|
-
Requires-Dist: opentelemetry-instrumentation-
|
68
|
-
Requires-Dist: opentelemetry-instrumentation-
|
69
|
-
Requires-Dist: opentelemetry-instrumentation-
|
70
|
-
Requires-Dist: opentelemetry-instrumentation-
|
71
|
-
Requires-Dist: opentelemetry-instrumentation-
|
72
|
-
Requires-Dist: opentelemetry-instrumentation-
|
73
|
-
Requires-Dist: opentelemetry-instrumentation-
|
74
|
-
Requires-Dist: opentelemetry-instrumentation-
|
75
|
-
Requires-Dist: opentelemetry-instrumentation-
|
76
|
-
Requires-Dist: opentelemetry-instrumentation-
|
77
|
-
Requires-Dist: opentelemetry-instrumentation-
|
78
|
-
Requires-Dist: opentelemetry-instrumentation-
|
79
|
-
Requires-Dist: opentelemetry-instrumentation-
|
80
|
-
Requires-Dist: opentelemetry-instrumentation-
|
81
|
-
Requires-Dist: opentelemetry-instrumentation-
|
82
|
-
Requires-Dist: opentelemetry-instrumentation-
|
83
|
-
Requires-Dist: opentelemetry-instrumentation-
|
84
|
-
Requires-Dist: opentelemetry-instrumentation-
|
85
|
-
Requires-Dist: opentelemetry-instrumentation-
|
86
|
-
Requires-Dist: opentelemetry-instrumentation-
|
87
|
-
Requires-Dist: opentelemetry-instrumentation-
|
88
|
-
Requires-Dist: opentelemetry-instrumentation-
|
89
|
-
Requires-Dist: opentelemetry-instrumentation-
|
90
|
-
Requires-Dist: opentelemetry-instrumentation-
|
91
|
-
Requires-Dist: opentelemetry-instrumentation-
|
92
|
-
Requires-Dist: opentelemetry-instrumentation-
|
93
|
-
Requires-Dist: opentelemetry-instrumentation-
|
94
|
-
Requires-Dist: opentelemetry-instrumentation-
|
95
|
-
Requires-Dist: opentelemetry-instrumentation-
|
96
|
-
Requires-Dist: opentelemetry-instrumentation-
|
97
|
-
Requires-Dist: opentelemetry-instrumentation-vertexai (>=0.
|
98
|
-
Requires-Dist: opentelemetry-instrumentation-
|
99
|
-
Requires-Dist: opentelemetry-instrumentation-watsonx (>=0.
|
100
|
-
Requires-Dist: opentelemetry-instrumentation-
|
101
|
-
Requires-Dist: opentelemetry-instrumentation-weaviate (>=0.
|
102
|
-
Requires-Dist: opentelemetry-
|
103
|
-
Requires-Dist: opentelemetry-
|
46
|
+
Requires-Dist: opentelemetry-api (>=1.33.0)
|
47
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc (>=1.33.0)
|
48
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http (>=1.33.0)
|
49
|
+
Requires-Dist: opentelemetry-instrumentation-alephalpha (>=0.40.5) ; extra == "alephalpha"
|
50
|
+
Requires-Dist: opentelemetry-instrumentation-alephalpha (>=0.40.5) ; extra == "all"
|
51
|
+
Requires-Dist: opentelemetry-instrumentation-anthropic (>=0.40.5) ; extra == "all"
|
52
|
+
Requires-Dist: opentelemetry-instrumentation-anthropic (>=0.40.5) ; extra == "anthropic"
|
53
|
+
Requires-Dist: opentelemetry-instrumentation-bedrock (>=0.40.5) ; extra == "all"
|
54
|
+
Requires-Dist: opentelemetry-instrumentation-bedrock (>=0.40.5) ; extra == "bedrock"
|
55
|
+
Requires-Dist: opentelemetry-instrumentation-chromadb (>=0.40.5) ; extra == "all"
|
56
|
+
Requires-Dist: opentelemetry-instrumentation-chromadb (>=0.40.5) ; extra == "chromadb"
|
57
|
+
Requires-Dist: opentelemetry-instrumentation-cohere (>=0.40.5) ; extra == "all"
|
58
|
+
Requires-Dist: opentelemetry-instrumentation-cohere (>=0.40.5) ; extra == "cohere"
|
59
|
+
Requires-Dist: opentelemetry-instrumentation-crewai (>=0.40.5) ; extra == "all"
|
60
|
+
Requires-Dist: opentelemetry-instrumentation-crewai (>=0.40.5) ; extra == "crewai"
|
61
|
+
Requires-Dist: opentelemetry-instrumentation-google-generativeai (>=0.40.5) ; extra == "all"
|
62
|
+
Requires-Dist: opentelemetry-instrumentation-google-generativeai (>=0.40.5) ; extra == "google-generativeai"
|
63
|
+
Requires-Dist: opentelemetry-instrumentation-groq (>=0.40.5) ; extra == "all"
|
64
|
+
Requires-Dist: opentelemetry-instrumentation-groq (>=0.40.5) ; extra == "groq"
|
65
|
+
Requires-Dist: opentelemetry-instrumentation-haystack (>=0.40.5) ; extra == "all"
|
66
|
+
Requires-Dist: opentelemetry-instrumentation-haystack (>=0.40.5) ; extra == "haystack"
|
67
|
+
Requires-Dist: opentelemetry-instrumentation-lancedb (>=0.40.5) ; extra == "all"
|
68
|
+
Requires-Dist: opentelemetry-instrumentation-lancedb (>=0.40.5) ; extra == "lancedb"
|
69
|
+
Requires-Dist: opentelemetry-instrumentation-langchain (>=0.40.5) ; extra == "all"
|
70
|
+
Requires-Dist: opentelemetry-instrumentation-langchain (>=0.40.5) ; extra == "langchain"
|
71
|
+
Requires-Dist: opentelemetry-instrumentation-llamaindex (>=0.40.5) ; extra == "all"
|
72
|
+
Requires-Dist: opentelemetry-instrumentation-llamaindex (>=0.40.5) ; extra == "llamaindex"
|
73
|
+
Requires-Dist: opentelemetry-instrumentation-marqo (>=0.40.5) ; extra == "all"
|
74
|
+
Requires-Dist: opentelemetry-instrumentation-marqo (>=0.40.5) ; extra == "marqo"
|
75
|
+
Requires-Dist: opentelemetry-instrumentation-mcp (>=0.40.5) ; extra == "all"
|
76
|
+
Requires-Dist: opentelemetry-instrumentation-mcp (>=0.40.5) ; extra == "mcp"
|
77
|
+
Requires-Dist: opentelemetry-instrumentation-milvus (>=0.40.5) ; extra == "all"
|
78
|
+
Requires-Dist: opentelemetry-instrumentation-milvus (>=0.40.5) ; extra == "milvus"
|
79
|
+
Requires-Dist: opentelemetry-instrumentation-mistralai (>=0.40.5) ; extra == "all"
|
80
|
+
Requires-Dist: opentelemetry-instrumentation-mistralai (>=0.40.5) ; extra == "mistralai"
|
81
|
+
Requires-Dist: opentelemetry-instrumentation-ollama (>=0.40.5) ; extra == "all"
|
82
|
+
Requires-Dist: opentelemetry-instrumentation-ollama (>=0.40.5) ; extra == "ollama"
|
83
|
+
Requires-Dist: opentelemetry-instrumentation-openai (>=0.40.5) ; extra == "all"
|
84
|
+
Requires-Dist: opentelemetry-instrumentation-openai (>=0.40.5) ; extra == "openai"
|
85
|
+
Requires-Dist: opentelemetry-instrumentation-pinecone (>=0.40.5) ; extra == "all"
|
86
|
+
Requires-Dist: opentelemetry-instrumentation-pinecone (>=0.40.5) ; extra == "pinecone"
|
87
|
+
Requires-Dist: opentelemetry-instrumentation-qdrant (>=0.40.5) ; extra == "all"
|
88
|
+
Requires-Dist: opentelemetry-instrumentation-qdrant (>=0.40.5) ; extra == "qdrant"
|
89
|
+
Requires-Dist: opentelemetry-instrumentation-replicate (>=0.40.5) ; extra == "all"
|
90
|
+
Requires-Dist: opentelemetry-instrumentation-replicate (>=0.40.5) ; extra == "replicate"
|
91
|
+
Requires-Dist: opentelemetry-instrumentation-sagemaker (>=0.40.5) ; extra == "all"
|
92
|
+
Requires-Dist: opentelemetry-instrumentation-sagemaker (>=0.40.5) ; extra == "sagemaker"
|
93
|
+
Requires-Dist: opentelemetry-instrumentation-threading (>=0.54b0)
|
94
|
+
Requires-Dist: opentelemetry-instrumentation-together (>=0.40.5) ; extra == "all"
|
95
|
+
Requires-Dist: opentelemetry-instrumentation-together (>=0.40.5) ; extra == "together"
|
96
|
+
Requires-Dist: opentelemetry-instrumentation-transformers (>=0.40.5) ; extra == "all"
|
97
|
+
Requires-Dist: opentelemetry-instrumentation-transformers (>=0.40.5) ; extra == "transformers"
|
98
|
+
Requires-Dist: opentelemetry-instrumentation-vertexai (>=0.40.5) ; extra == "all"
|
99
|
+
Requires-Dist: opentelemetry-instrumentation-vertexai (>=0.40.5) ; extra == "vertexai"
|
100
|
+
Requires-Dist: opentelemetry-instrumentation-watsonx (>=0.40.5) ; extra == "all"
|
101
|
+
Requires-Dist: opentelemetry-instrumentation-watsonx (>=0.40.5) ; extra == "watsonx"
|
102
|
+
Requires-Dist: opentelemetry-instrumentation-weaviate (>=0.40.5) ; extra == "all"
|
103
|
+
Requires-Dist: opentelemetry-instrumentation-weaviate (>=0.40.5) ; extra == "weaviate"
|
104
|
+
Requires-Dist: opentelemetry-sdk (>=1.33.0)
|
105
|
+
Requires-Dist: opentelemetry-semantic-conventions (>=0.54b0)
|
106
|
+
Requires-Dist: opentelemetry-semantic-conventions-ai (>=0.4.8)
|
104
107
|
Requires-Dist: pydantic (>=2.0.3,<3.0.0)
|
105
108
|
Requires-Dist: python-dotenv (>=1.0)
|
106
109
|
Requires-Dist: tenacity (>=8.0)
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# Laminar Python
|
2
|
+
|
3
|
+
# If you are looking for information about possible extras installations,
|
4
|
+
# i.e. what you can pass into `pip install 'lmnr[extra1,extra2]'`, please see the
|
5
|
+
# `[project.optional-dependencies]` section below.
|
6
|
+
|
7
|
+
[project]
|
8
|
+
name = "lmnr"
|
9
|
+
version = "0.6.1"
|
10
|
+
description = "Python SDK for Laminar"
|
11
|
+
authors = [
|
12
|
+
{ name = "lmnr.ai", email = "founders@lmnr.ai" }
|
13
|
+
]
|
14
|
+
readme = "README.md"
|
15
|
+
requires-python = ">=3.10,<4"
|
16
|
+
license = "Apache-2.0"
|
17
|
+
dependencies = [
|
18
|
+
"pydantic (>=2.0.3,<3.0.0)",
|
19
|
+
"python-dotenv (>=1.0)",
|
20
|
+
"opentelemetry-api (>=1.33.0)",
|
21
|
+
"opentelemetry-sdk (>=1.33.0)",
|
22
|
+
"opentelemetry-exporter-otlp-proto-http (>=1.33.0)",
|
23
|
+
"opentelemetry-exporter-otlp-proto-grpc (>=1.33.0)",
|
24
|
+
"opentelemetry-semantic-conventions (>=0.54b0)",
|
25
|
+
"opentelemetry-semantic-conventions-ai (>=0.4.8)",
|
26
|
+
"tqdm (>=4.0)",
|
27
|
+
"argparse (>=1.0)",
|
28
|
+
"tenacity (>=8.0)",
|
29
|
+
# explicitly freeze grpcio. Since 1.68.0, grpcio writes a warning message
|
30
|
+
# that looks scary, but is harmless.
|
31
|
+
# WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
|
32
|
+
# E0000 00:00:1737439981.199902 9456033 init.cc:229] grpc_wait_for_shutdown_with_timeout() timed out.
|
33
|
+
#
|
34
|
+
# Related issue:
|
35
|
+
# https://discuss.ai.google.dev/t/warning-all-log-messages-before-absl-initializelog-is-called-are-written-to-stderr-e0000-001731955515-629532-17124-init-cc-229-grpc-wait-for-shutdown-with-timeout-timed-out/50020
|
36
|
+
# https://github.com/grpc/grpc/issues/38490
|
37
|
+
"grpcio<1.68.0",
|
38
|
+
"httpx>=0.25.0",
|
39
|
+
"opentelemetry-instrumentation-threading>=0.54b0",
|
40
|
+
]
|
41
|
+
|
42
|
+
[project.scripts]
|
43
|
+
lmnr = "lmnr.cli:cli"
|
44
|
+
|
45
|
+
[project.optional-dependencies]
|
46
|
+
# List of all possible extras. You can specify one or more of these extras
|
47
|
+
# when installing the package, using any of the following examples:
|
48
|
+
# `pip install 'lmnr[anthropic,openai]'`
|
49
|
+
# `uv pip install 'lmnr[anthropic,openai]'`
|
50
|
+
# `uv add lmnr --extra anthropic --extra openai`
|
51
|
+
# `poetry add 'lmnr[anthropic,openai]'`
|
52
|
+
|
53
|
+
alephalpha=["opentelemetry-instrumentation-alephalpha>=0.40.5"]
|
54
|
+
anthropic=["opentelemetry-instrumentation-anthropic>=0.40.5"]
|
55
|
+
bedrock=["opentelemetry-instrumentation-bedrock>=0.40.5"]
|
56
|
+
chromadb=["opentelemetry-instrumentation-chromadb>=0.40.5"]
|
57
|
+
cohere=["opentelemetry-instrumentation-cohere>=0.40.5"]
|
58
|
+
crewai=["opentelemetry-instrumentation-crewai>=0.40.5"]
|
59
|
+
google-generativeai=["opentelemetry-instrumentation-google-generativeai>=0.40.5"]
|
60
|
+
groq=["opentelemetry-instrumentation-groq>=0.40.5"]
|
61
|
+
haystack=["opentelemetry-instrumentation-haystack>=0.40.5"]
|
62
|
+
lancedb=["opentelemetry-instrumentation-lancedb>=0.40.5"]
|
63
|
+
langchain=["opentelemetry-instrumentation-langchain>=0.40.5"]
|
64
|
+
llamaindex=["opentelemetry-instrumentation-llamaindex>=0.40.5"]
|
65
|
+
marqo=["opentelemetry-instrumentation-marqo>=0.40.5"]
|
66
|
+
mcp=["opentelemetry-instrumentation-mcp>=0.40.5"]
|
67
|
+
milvus=["opentelemetry-instrumentation-milvus>=0.40.5"]
|
68
|
+
mistralai=["opentelemetry-instrumentation-mistralai>=0.40.5"]
|
69
|
+
ollama=["opentelemetry-instrumentation-ollama>=0.40.5"]
|
70
|
+
openai=["opentelemetry-instrumentation-openai>=0.40.5"]
|
71
|
+
pinecone=["opentelemetry-instrumentation-pinecone>=0.40.5"]
|
72
|
+
qdrant=["opentelemetry-instrumentation-qdrant>=0.40.5"]
|
73
|
+
replicate=["opentelemetry-instrumentation-replicate>=0.40.5"]
|
74
|
+
sagemaker=["opentelemetry-instrumentation-sagemaker>=0.40.5"]
|
75
|
+
together=["opentelemetry-instrumentation-together>=0.40.5"]
|
76
|
+
transformers=["opentelemetry-instrumentation-transformers>=0.40.5"]
|
77
|
+
vertexai=["opentelemetry-instrumentation-vertexai>=0.40.5"]
|
78
|
+
watsonx=["opentelemetry-instrumentation-watsonx>=0.40.5"]
|
79
|
+
weaviate=["opentelemetry-instrumentation-weaviate>=0.40.5"]
|
80
|
+
# `all` is the group added for convenience, if you want to install all
|
81
|
+
# the instrumentations.
|
82
|
+
# we suggest using package-manager-specific commands instead,
|
83
|
+
# like `uv add lmnr --all-extras`
|
84
|
+
all = [
|
85
|
+
"opentelemetry-instrumentation-alephalpha>=0.40.5",
|
86
|
+
"opentelemetry-instrumentation-anthropic>=0.40.5",
|
87
|
+
"opentelemetry-instrumentation-bedrock>=0.40.5",
|
88
|
+
"opentelemetry-instrumentation-chromadb>=0.40.5",
|
89
|
+
"opentelemetry-instrumentation-cohere>=0.40.5",
|
90
|
+
"opentelemetry-instrumentation-crewai>=0.40.5",
|
91
|
+
"opentelemetry-instrumentation-google-generativeai>=0.40.5",
|
92
|
+
"opentelemetry-instrumentation-groq>=0.40.5",
|
93
|
+
"opentelemetry-instrumentation-haystack>=0.40.5",
|
94
|
+
"opentelemetry-instrumentation-lancedb>=0.40.5",
|
95
|
+
"opentelemetry-instrumentation-langchain>=0.40.5",
|
96
|
+
"opentelemetry-instrumentation-llamaindex>=0.40.5",
|
97
|
+
"opentelemetry-instrumentation-marqo>=0.40.5",
|
98
|
+
"opentelemetry-instrumentation-mcp>=0.40.5",
|
99
|
+
"opentelemetry-instrumentation-milvus>=0.40.5",
|
100
|
+
"opentelemetry-instrumentation-mistralai>=0.40.5",
|
101
|
+
"opentelemetry-instrumentation-ollama>=0.40.5",
|
102
|
+
"opentelemetry-instrumentation-openai>=0.40.5",
|
103
|
+
"opentelemetry-instrumentation-pinecone>=0.40.5",
|
104
|
+
"opentelemetry-instrumentation-qdrant>=0.40.5",
|
105
|
+
"opentelemetry-instrumentation-replicate>=0.40.5",
|
106
|
+
"opentelemetry-instrumentation-sagemaker>=0.40.5",
|
107
|
+
"opentelemetry-instrumentation-together>=0.40.5",
|
108
|
+
"opentelemetry-instrumentation-transformers>=0.40.5",
|
109
|
+
"opentelemetry-instrumentation-vertexai>=0.40.5",
|
110
|
+
"opentelemetry-instrumentation-watsonx>=0.40.5",
|
111
|
+
"opentelemetry-instrumentation-weaviate>=0.40.5"
|
112
|
+
]
|
113
|
+
|
114
|
+
[dependency-groups]
|
115
|
+
dev = [
|
116
|
+
"autopep8>=2.3.2",
|
117
|
+
"flake8>=7.2.0",
|
118
|
+
"pytest>=8.3.5",
|
119
|
+
"pytest-sugar>=1.0.0",
|
120
|
+
"pytest-asyncio>=0.26.0",
|
121
|
+
"playwright>=1.52.0",
|
122
|
+
"vcrpy>=7.0.0",
|
123
|
+
"openai>=1.77.0",
|
124
|
+
"pytest-recording>=0.13.4",
|
125
|
+
"patchright>=1.52.3",
|
126
|
+
]
|
127
|
+
|
128
|
+
[build-system]
|
129
|
+
requires = ["poetry-core"]
|
130
|
+
build-backend = "poetry.core.masonry.api"
|
131
|
+
|
132
|
+
[tool.uv.workspace]
|
133
|
+
members = ["examples/fastapi-app"]
|
134
|
+
# we can move to uv_build, once it's more stable
|
135
|
+
# https://github.com/astral-sh/uv/issues/3957
|
136
|
+
# requires = ["uv_build>=0.6.16,<0.7"]
|
137
|
+
# build-backend = "uv_build"
|
@@ -13,8 +13,10 @@ from .sdk.types import (
|
|
13
13
|
)
|
14
14
|
from .sdk.decorators import observe
|
15
15
|
from .sdk.types import LaminarSpanContext
|
16
|
-
from .opentelemetry_lib import Instruments
|
17
16
|
from .opentelemetry_lib.tracing.attributes import Attributes
|
17
|
+
from .opentelemetry_lib.tracing.instruments import Instruments
|
18
|
+
from .opentelemetry_lib.tracing.processor import LaminarSpanProcessor
|
19
|
+
from .opentelemetry_lib.tracing.tracer import get_laminar_tracer_provider, get_tracer
|
18
20
|
from opentelemetry.trace import use_span
|
19
21
|
|
20
22
|
__all__ = [
|
@@ -29,9 +31,12 @@ __all__ = [
|
|
29
31
|
"LaminarClient",
|
30
32
|
"LaminarDataset",
|
31
33
|
"LaminarSpanContext",
|
34
|
+
"LaminarSpanProcessor",
|
32
35
|
"RunAgentResponseChunk",
|
33
36
|
"StepChunkContent",
|
34
37
|
"TracingLevel",
|
38
|
+
"get_laminar_tracer_provider",
|
39
|
+
"get_tracer",
|
35
40
|
"evaluate",
|
36
41
|
"observe",
|
37
42
|
"use_span",
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import logging
|
2
|
+
import sys
|
3
|
+
|
4
|
+
from typing import Optional, Set
|
5
|
+
from opentelemetry.sdk.trace.export import SpanExporter
|
6
|
+
from opentelemetry.sdk.resources import SERVICE_NAME
|
7
|
+
|
8
|
+
from lmnr.opentelemetry_lib.tracing.instruments import Instruments
|
9
|
+
from lmnr.opentelemetry_lib.tracing import TracerWrapper
|
10
|
+
|
11
|
+
MAX_MANUAL_SPAN_PAYLOAD_SIZE = 1024 * 1024 # 1MB
|
12
|
+
|
13
|
+
|
14
|
+
class TracerManager:
|
15
|
+
__tracer_wrapper: TracerWrapper
|
16
|
+
|
17
|
+
@staticmethod
|
18
|
+
def init(
|
19
|
+
app_name: Optional[str] = sys.argv[0],
|
20
|
+
disable_batch=False,
|
21
|
+
exporter: Optional[SpanExporter] = None,
|
22
|
+
resource_attributes: dict = {},
|
23
|
+
instruments: Optional[Set[Instruments]] = None,
|
24
|
+
block_instruments: Optional[Set[Instruments]] = None,
|
25
|
+
base_url: str = "https://api.lmnr.ai",
|
26
|
+
port: int = 8443,
|
27
|
+
http_port: int = 443,
|
28
|
+
project_api_key: Optional[str] = None,
|
29
|
+
max_export_batch_size: Optional[int] = None,
|
30
|
+
force_http: bool = False,
|
31
|
+
timeout_seconds: int = 30,
|
32
|
+
set_global_tracer_provider: bool = True,
|
33
|
+
otel_logger_level: int = logging.ERROR,
|
34
|
+
) -> None:
|
35
|
+
enable_content_tracing = True
|
36
|
+
|
37
|
+
# Tracer init
|
38
|
+
resource_attributes.update({SERVICE_NAME: app_name})
|
39
|
+
TracerWrapper.set_static_params(resource_attributes, enable_content_tracing)
|
40
|
+
TracerManager.__tracer_wrapper = TracerWrapper(
|
41
|
+
disable_batch=disable_batch,
|
42
|
+
exporter=exporter,
|
43
|
+
instruments=instruments,
|
44
|
+
block_instruments=block_instruments,
|
45
|
+
base_url=base_url,
|
46
|
+
port=port,
|
47
|
+
http_port=http_port,
|
48
|
+
project_api_key=project_api_key,
|
49
|
+
max_export_batch_size=max_export_batch_size,
|
50
|
+
force_http=force_http,
|
51
|
+
timeout_seconds=timeout_seconds,
|
52
|
+
set_global_tracer_provider=set_global_tracer_provider,
|
53
|
+
otel_logger_level=otel_logger_level,
|
54
|
+
)
|
55
|
+
|
56
|
+
@staticmethod
|
57
|
+
def flush() -> bool:
|
58
|
+
return TracerManager.__tracer_wrapper.flush()
|
59
|
+
|
60
|
+
@staticmethod
|
61
|
+
def shutdown():
|
62
|
+
TracerManager.__tracer_wrapper.shutdown()
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import json
|
2
1
|
from functools import wraps
|
2
|
+
import json
|
3
3
|
import logging
|
4
4
|
import pydantic
|
5
5
|
import types
|
@@ -10,11 +10,11 @@ from opentelemetry import context as context_api
|
|
10
10
|
from opentelemetry.trace import Span
|
11
11
|
|
12
12
|
from lmnr.sdk.utils import get_input_from_func_args, is_method
|
13
|
-
from lmnr.opentelemetry_lib
|
13
|
+
from lmnr.opentelemetry_lib import MAX_MANUAL_SPAN_PAYLOAD_SIZE
|
14
|
+
from lmnr.opentelemetry_lib.tracing.tracer import get_tracer
|
14
15
|
from lmnr.opentelemetry_lib.tracing.attributes import SPAN_INPUT, SPAN_OUTPUT, SPAN_TYPE
|
15
|
-
from lmnr.opentelemetry_lib.tracing
|
16
|
+
from lmnr.opentelemetry_lib.tracing import TracerWrapper
|
16
17
|
from lmnr.opentelemetry_lib.utils.json_encoder import JSONEncoder
|
17
|
-
from lmnr.opentelemetry_lib.config import MAX_MANUAL_SPAN_PAYLOAD_SIZE
|
18
18
|
|
19
19
|
|
20
20
|
class CustomJSONEncoder(JSONEncoder):
|
@@ -86,7 +86,16 @@ def entity_method(
|
|
86
86
|
|
87
87
|
# span will be ended in the generator
|
88
88
|
if isinstance(res, types.GeneratorType):
|
89
|
-
return _handle_generator(span, res)
|
89
|
+
return _handle_generator(span, ctx_token, res)
|
90
|
+
if isinstance(res, types.AsyncGeneratorType):
|
91
|
+
# async def foo() -> AsyncGenerator[int, None]:
|
92
|
+
# is not considered async in a classical sense in Python,
|
93
|
+
# so we handle this inside the sync wrapper.
|
94
|
+
# In particular, CO_COROUTINE is different from CO_ASYNC_GENERATOR.
|
95
|
+
# Flags are listed from LSB here:
|
96
|
+
# https://docs.python.org/3/library/inspect.html#inspect-module-co-flags
|
97
|
+
# See also: https://groups.google.com/g/python-tulip/c/6rWweGXLutU?pli=1
|
98
|
+
return _ahandle_generator(span, ctx_token, res)
|
90
99
|
|
91
100
|
try:
|
92
101
|
if not ignore_output:
|
@@ -161,6 +170,8 @@ def aentity_method(
|
|
161
170
|
|
162
171
|
# span will be ended in the generator
|
163
172
|
if isinstance(res, types.AsyncGeneratorType):
|
173
|
+
# probably unreachable, read the comment in the similar
|
174
|
+
# part of the sync wrapper.
|
164
175
|
return await _ahandle_generator(span, ctx_token, res)
|
165
176
|
|
166
177
|
try:
|
@@ -185,24 +196,22 @@ def aentity_method(
|
|
185
196
|
return decorate
|
186
197
|
|
187
198
|
|
188
|
-
def _handle_generator(span, res):
|
189
|
-
# for some reason the SPAN_KEY is not being set in the context of the generator, so we re-set it
|
190
|
-
context_api.attach(trace.set_span_in_context(span))
|
199
|
+
def _handle_generator(span, ctx_token, res):
|
191
200
|
yield from res
|
192
201
|
|
193
202
|
span.end()
|
194
|
-
|
195
|
-
|
196
|
-
# https://github.com/open-telemetry/opentelemetry-python/issues/2606
|
197
|
-
# This is not a problem since the context will be detached automatically during garbage collection
|
203
|
+
if ctx_token is not None:
|
204
|
+
context_api.detach(ctx_token)
|
198
205
|
|
199
206
|
|
200
207
|
async def _ahandle_generator(span, ctx_token, res):
|
208
|
+
# async with contextlib.aclosing(res) as closing_gen:
|
201
209
|
async for part in res:
|
202
210
|
yield part
|
203
211
|
|
204
212
|
span.end()
|
205
|
-
|
213
|
+
if ctx_token is not None:
|
214
|
+
context_api.detach(ctx_token)
|
206
215
|
|
207
216
|
|
208
217
|
def _process_exception(span: Span, e: Exception):
|
@@ -0,0 +1,158 @@
|
|
1
|
+
import atexit
|
2
|
+
import logging
|
3
|
+
|
4
|
+
from lmnr.opentelemetry_lib.tracing.processor import LaminarSpanProcessor
|
5
|
+
from lmnr.sdk.client.asynchronous.async_client import AsyncLaminarClient
|
6
|
+
from lmnr.sdk.client.synchronous.sync_client import LaminarClient
|
7
|
+
from lmnr.sdk.log import VerboseColorfulFormatter
|
8
|
+
from lmnr.opentelemetry_lib.tracing.instruments import (
|
9
|
+
Instruments,
|
10
|
+
init_instrumentations,
|
11
|
+
)
|
12
|
+
|
13
|
+
from opentelemetry import trace
|
14
|
+
from opentelemetry.instrumentation.threading import ThreadingInstrumentor
|
15
|
+
from opentelemetry.sdk.resources import Resource
|
16
|
+
from opentelemetry.sdk.trace import TracerProvider, SpanProcessor
|
17
|
+
from opentelemetry.sdk.trace.export import SpanExporter
|
18
|
+
from typing import Optional, Set
|
19
|
+
|
20
|
+
module_logger = logging.getLogger(__name__)
|
21
|
+
console_log_handler = logging.StreamHandler()
|
22
|
+
console_log_handler.setFormatter(VerboseColorfulFormatter())
|
23
|
+
module_logger.addHandler(console_log_handler)
|
24
|
+
|
25
|
+
|
26
|
+
TRACER_NAME = "lmnr.tracer"
|
27
|
+
|
28
|
+
MAX_EVENTS_OR_ATTRIBUTES_PER_SPAN = 5000
|
29
|
+
|
30
|
+
|
31
|
+
class TracerWrapper(object):
|
32
|
+
resource_attributes: dict = {}
|
33
|
+
enable_content_tracing: bool = True
|
34
|
+
__tracer_provider: Optional[TracerProvider] = None
|
35
|
+
__logger: logging.Logger
|
36
|
+
__client: LaminarClient
|
37
|
+
__async_client: AsyncLaminarClient
|
38
|
+
__resource: Resource
|
39
|
+
__span_processor: SpanProcessor
|
40
|
+
|
41
|
+
def __new__(
|
42
|
+
cls,
|
43
|
+
disable_batch=False,
|
44
|
+
exporter: Optional[SpanExporter] = None,
|
45
|
+
instruments: Optional[Set[Instruments]] = None,
|
46
|
+
block_instruments: Optional[Set[Instruments]] = None,
|
47
|
+
base_url: str = "https://api.lmnr.ai",
|
48
|
+
port: int = 8443,
|
49
|
+
http_port: int = 443,
|
50
|
+
project_api_key: Optional[str] = None,
|
51
|
+
max_export_batch_size: Optional[int] = None,
|
52
|
+
force_http: bool = False,
|
53
|
+
timeout_seconds: int = 10,
|
54
|
+
set_global_tracer_provider: bool = True,
|
55
|
+
otel_logger_level: int = logging.ERROR,
|
56
|
+
) -> "TracerWrapper":
|
57
|
+
# Silence some opentelemetry warnings
|
58
|
+
logging.getLogger("opentelemetry.trace").setLevel(otel_logger_level)
|
59
|
+
|
60
|
+
base_http_url = f"{base_url}:{http_port}"
|
61
|
+
cls._initialize_logger(cls)
|
62
|
+
if not hasattr(cls, "instance"):
|
63
|
+
obj = cls.instance = super(TracerWrapper, cls).__new__(cls)
|
64
|
+
|
65
|
+
obj.__client = LaminarClient(
|
66
|
+
base_url=base_http_url,
|
67
|
+
project_api_key=project_api_key,
|
68
|
+
)
|
69
|
+
obj.__async_client = AsyncLaminarClient(
|
70
|
+
base_url=base_http_url,
|
71
|
+
project_api_key=project_api_key,
|
72
|
+
)
|
73
|
+
|
74
|
+
obj.__resource = Resource(attributes=TracerWrapper.resource_attributes)
|
75
|
+
|
76
|
+
obj.__span_processor = LaminarSpanProcessor(
|
77
|
+
base_url=base_url,
|
78
|
+
api_key=project_api_key,
|
79
|
+
port=http_port if force_http else port,
|
80
|
+
exporter=exporter,
|
81
|
+
max_export_batch_size=max_export_batch_size,
|
82
|
+
timeout_seconds=timeout_seconds,
|
83
|
+
force_http=force_http,
|
84
|
+
disable_batch=disable_batch,
|
85
|
+
)
|
86
|
+
|
87
|
+
lmnr_provider = TracerProvider(resource=obj.__resource)
|
88
|
+
global_provider = trace.get_tracer_provider()
|
89
|
+
if set_global_tracer_provider and isinstance(
|
90
|
+
global_provider, trace.ProxyTracerProvider
|
91
|
+
):
|
92
|
+
trace.set_tracer_provider(lmnr_provider)
|
93
|
+
|
94
|
+
obj.__tracer_provider = lmnr_provider
|
95
|
+
|
96
|
+
obj.__tracer_provider.add_span_processor(obj.__span_processor)
|
97
|
+
|
98
|
+
# This is not a real instrumentation and does not generate telemetry
|
99
|
+
# data, but it is required to ensure that OpenTelemetry context
|
100
|
+
# propagation is enabled.
|
101
|
+
# See the README at:
|
102
|
+
# https://pypi.org/project/opentelemetry-instrumentation-threading/
|
103
|
+
ThreadingInstrumentor().instrument()
|
104
|
+
|
105
|
+
init_instrumentations(
|
106
|
+
tracer_provider=obj.__tracer_provider,
|
107
|
+
instruments=instruments,
|
108
|
+
block_instruments=block_instruments,
|
109
|
+
client=obj.__client,
|
110
|
+
async_client=obj.__async_client,
|
111
|
+
)
|
112
|
+
|
113
|
+
# Force flushes for debug environments (e.g. local development)
|
114
|
+
atexit.register(obj.exit_handler)
|
115
|
+
|
116
|
+
return cls.instance
|
117
|
+
|
118
|
+
def exit_handler(self):
|
119
|
+
if isinstance(self.__span_processor, LaminarSpanProcessor):
|
120
|
+
self.__span_processor.clear()
|
121
|
+
self.flush()
|
122
|
+
|
123
|
+
def _initialize_logger(self):
|
124
|
+
self.__logger = logging.getLogger(__name__)
|
125
|
+
console_log_handler = logging.StreamHandler()
|
126
|
+
console_log_handler.setFormatter(VerboseColorfulFormatter())
|
127
|
+
self.__logger.addHandler(console_log_handler)
|
128
|
+
|
129
|
+
@staticmethod
|
130
|
+
def set_static_params(
|
131
|
+
resource_attributes: dict,
|
132
|
+
enable_content_tracing: bool,
|
133
|
+
) -> None:
|
134
|
+
TracerWrapper.resource_attributes = resource_attributes
|
135
|
+
TracerWrapper.enable_content_tracing = enable_content_tracing
|
136
|
+
|
137
|
+
@classmethod
|
138
|
+
def verify_initialized(cls) -> bool:
|
139
|
+
return hasattr(cls, "instance")
|
140
|
+
|
141
|
+
@classmethod
|
142
|
+
def clear(cls):
|
143
|
+
# Any state cleanup. Now used in between tests
|
144
|
+
if isinstance(cls.instance.__span_processor, LaminarSpanProcessor):
|
145
|
+
cls.instance.__span_processor.clear()
|
146
|
+
|
147
|
+
def shutdown(self):
|
148
|
+
if self.__tracer_provider is None:
|
149
|
+
return
|
150
|
+
self.__tracer_provider.shutdown()
|
151
|
+
|
152
|
+
def flush(self):
|
153
|
+
return self.__span_processor.force_flush()
|
154
|
+
|
155
|
+
def get_tracer(self):
|
156
|
+
if self.__tracer_provider is None:
|
157
|
+
return trace.get_tracer_provider().get_tracer(TRACER_NAME)
|
158
|
+
return self.__tracer_provider.get_tracer(TRACER_NAME)
|