lmnr 0.5.2__tar.gz → 0.6.0__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.
Files changed (64) hide show
  1. {lmnr-0.5.2 → lmnr-0.6.0}/PKG-INFO +65 -63
  2. {lmnr-0.5.2 → lmnr-0.6.0}/README.md +1 -1
  3. lmnr-0.6.0/pyproject.toml +135 -0
  4. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/__init__.py +7 -2
  5. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/cli.py +10 -8
  6. lmnr-0.6.0/src/lmnr/opentelemetry_lib/__init__.py +55 -0
  7. lmnr-0.5.2/src/lmnr/openllmetry_sdk/decorators/base.py → lmnr-0.6.0/src/lmnr/opentelemetry_lib/decorators/__init__.py +24 -15
  8. {lmnr-0.5.2/src/lmnr/openllmetry_sdk → lmnr-0.6.0/src/lmnr/opentelemetry_lib}/opentelemetry/instrumentation/google_genai/utils.py +1 -1
  9. lmnr-0.6.0/src/lmnr/opentelemetry_lib/tracing/__init__.py +139 -0
  10. lmnr-0.6.0/src/lmnr/opentelemetry_lib/tracing/_instrument_initializers.py +398 -0
  11. {lmnr-0.5.2/src/lmnr/openllmetry_sdk → lmnr-0.6.0/src/lmnr/opentelemetry_lib}/tracing/attributes.py +14 -7
  12. lmnr-0.6.0/src/lmnr/opentelemetry_lib/tracing/context_properties.py +53 -0
  13. lmnr-0.6.0/src/lmnr/opentelemetry_lib/tracing/exporter.py +60 -0
  14. lmnr-0.6.0/src/lmnr/opentelemetry_lib/tracing/instruments.py +121 -0
  15. lmnr-0.6.0/src/lmnr/opentelemetry_lib/tracing/processor.py +96 -0
  16. lmnr-0.5.2/src/lmnr/openllmetry_sdk/tracing/context_manager.py → lmnr-0.6.0/src/lmnr/opentelemetry_lib/tracing/tracer.py +6 -1
  17. {lmnr-0.5.2/src/lmnr/openllmetry_sdk → lmnr-0.6.0/src/lmnr/opentelemetry_lib}/utils/package_check.py +3 -1
  18. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/browser/browser_use_otel.py +20 -3
  19. lmnr-0.6.0/src/lmnr/sdk/browser/patchright_otel.py +177 -0
  20. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/browser/playwright_otel.py +16 -7
  21. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/browser/pw_utils.py +116 -74
  22. lmnr-0.6.0/src/lmnr/sdk/browser/rrweb/rrweb.umd.min.cjs +98 -0
  23. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/client/asynchronous/resources/agent.py +22 -1
  24. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/client/synchronous/resources/agent.py +23 -1
  25. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/decorators.py +5 -3
  26. lmnr-0.6.0/src/lmnr/sdk/eval_control.py +5 -0
  27. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/evaluations.py +10 -16
  28. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/laminar.py +16 -34
  29. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/types.py +2 -0
  30. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/utils.py +2 -3
  31. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/version.py +1 -1
  32. lmnr-0.5.2/pyproject.toml +0 -126
  33. lmnr-0.5.2/src/lmnr/openllmetry_sdk/__init__.py +0 -75
  34. lmnr-0.5.2/src/lmnr/openllmetry_sdk/config/__init__.py +0 -12
  35. lmnr-0.5.2/src/lmnr/openllmetry_sdk/instruments.py +0 -41
  36. lmnr-0.5.2/src/lmnr/openllmetry_sdk/tracing/__init__.py +0 -1
  37. lmnr-0.5.2/src/lmnr/openllmetry_sdk/tracing/content_allow_list.py +0 -24
  38. lmnr-0.5.2/src/lmnr/openllmetry_sdk/tracing/tracing.py +0 -998
  39. lmnr-0.5.2/src/lmnr/openllmetry_sdk/utils/in_memory_span_exporter.py +0 -61
  40. lmnr-0.5.2/src/lmnr/sdk/browser/__init__.py +0 -0
  41. lmnr-0.5.2/src/lmnr/sdk/browser/rrweb/rrweb.min.js +0 -18
  42. lmnr-0.5.2/src/lmnr/sdk/eval_control.py +0 -4
  43. {lmnr-0.5.2 → lmnr-0.6.0}/LICENSE +0 -0
  44. {lmnr-0.5.2/src/lmnr/openllmetry_sdk → lmnr-0.6.0/src/lmnr/opentelemetry_lib}/.flake8 +0 -0
  45. {lmnr-0.5.2/src/lmnr/openllmetry_sdk → lmnr-0.6.0/src/lmnr/opentelemetry_lib}/opentelemetry/instrumentation/google_genai/__init__.py +0 -0
  46. {lmnr-0.5.2/src/lmnr/openllmetry_sdk → lmnr-0.6.0/src/lmnr/opentelemetry_lib}/opentelemetry/instrumentation/google_genai/config.py +0 -0
  47. {lmnr-0.5.2/src/lmnr/openllmetry_sdk → lmnr-0.6.0/src/lmnr/opentelemetry_lib}/utils/__init__.py +0 -0
  48. {lmnr-0.5.2/src/lmnr/openllmetry_sdk → lmnr-0.6.0/src/lmnr/opentelemetry_lib}/utils/json_encoder.py +0 -0
  49. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/py.typed +0 -0
  50. {lmnr-0.5.2/src/lmnr/openllmetry_sdk/decorators → lmnr-0.6.0/src/lmnr/sdk}/__init__.py +0 -0
  51. {lmnr-0.5.2/src/lmnr/sdk → lmnr-0.6.0/src/lmnr/sdk/browser}/__init__.py +0 -0
  52. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/browser/utils.py +0 -0
  53. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/client/asynchronous/async_client.py +0 -0
  54. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/client/asynchronous/resources/__init__.py +0 -0
  55. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/client/asynchronous/resources/base.py +0 -0
  56. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/client/asynchronous/resources/browser_events.py +0 -0
  57. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/client/asynchronous/resources/evals.py +0 -0
  58. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/client/synchronous/resources/__init__.py +0 -0
  59. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/client/synchronous/resources/base.py +0 -0
  60. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/client/synchronous/resources/browser_events.py +0 -0
  61. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/client/synchronous/resources/evals.py +0 -0
  62. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/client/synchronous/sync_client.py +0 -0
  63. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/datasets.py +0 -0
  64. {lmnr-0.5.2 → lmnr-0.6.0}/src/lmnr/sdk/log.py +0 -0
@@ -1,14 +1,13 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: lmnr
3
- Version: 0.5.2
3
+ Version: 0.6.0
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.9,<4
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,66 @@ 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.31.1)
46
- Requires-Dist: opentelemetry-exporter-otlp-proto-grpc (>=1.31.1)
47
- Requires-Dist: opentelemetry-exporter-otlp-proto-http (>=1.31.1)
48
- Requires-Dist: opentelemetry-instrumentation-alephalpha (>=0.39.2) ; extra == "alephalpha"
49
- Requires-Dist: opentelemetry-instrumentation-alephalpha (>=0.39.2) ; extra == "all"
50
- Requires-Dist: opentelemetry-instrumentation-anthropic (>=0.39.2) ; extra == "all"
51
- Requires-Dist: opentelemetry-instrumentation-anthropic (>=0.39.2) ; extra == "anthropic"
52
- Requires-Dist: opentelemetry-instrumentation-bedrock (>=0.39.2) ; extra == "all"
53
- Requires-Dist: opentelemetry-instrumentation-bedrock (>=0.39.2) ; extra == "bedrock"
54
- Requires-Dist: opentelemetry-instrumentation-chromadb (>=0.39.2) ; extra == "all"
55
- Requires-Dist: opentelemetry-instrumentation-chromadb (>=0.39.2) ; extra == "chromadb"
56
- Requires-Dist: opentelemetry-instrumentation-cohere (>=0.39.2) ; extra == "all"
57
- Requires-Dist: opentelemetry-instrumentation-cohere (>=0.39.2) ; extra == "cohere"
58
- Requires-Dist: opentelemetry-instrumentation-google-generativeai (>=0.39.2) ; extra == "all"
59
- Requires-Dist: opentelemetry-instrumentation-google-generativeai (>=0.39.2) ; extra == "google-generativeai"
60
- Requires-Dist: opentelemetry-instrumentation-groq (>=0.39.2) ; extra == "all"
61
- Requires-Dist: opentelemetry-instrumentation-groq (>=0.39.2) ; extra == "groq"
62
- Requires-Dist: opentelemetry-instrumentation-haystack (>=0.39.2) ; extra == "all"
63
- Requires-Dist: opentelemetry-instrumentation-haystack (>=0.39.2) ; extra == "haystack"
64
- Requires-Dist: opentelemetry-instrumentation-lancedb (>=0.39.2) ; extra == "all"
65
- Requires-Dist: opentelemetry-instrumentation-lancedb (>=0.39.2) ; extra == "lancedb"
66
- Requires-Dist: opentelemetry-instrumentation-langchain (>=0.39.2) ; extra == "all"
67
- Requires-Dist: opentelemetry-instrumentation-langchain (>=0.39.2) ; extra == "langchain"
68
- Requires-Dist: opentelemetry-instrumentation-llamaindex (>=0.39.2) ; extra == "all"
69
- Requires-Dist: opentelemetry-instrumentation-llamaindex (>=0.39.2) ; extra == "llamaindex"
70
- Requires-Dist: opentelemetry-instrumentation-marqo (>=0.39.2) ; extra == "all"
71
- Requires-Dist: opentelemetry-instrumentation-marqo (>=0.39.2) ; extra == "marqo"
72
- Requires-Dist: opentelemetry-instrumentation-milvus (>=0.39.2) ; extra == "all"
73
- Requires-Dist: opentelemetry-instrumentation-milvus (>=0.39.2) ; extra == "milvus"
74
- Requires-Dist: opentelemetry-instrumentation-mistralai (>=0.39.2) ; extra == "all"
75
- Requires-Dist: opentelemetry-instrumentation-mistralai (>=0.39.2) ; extra == "mistralai"
76
- Requires-Dist: opentelemetry-instrumentation-ollama (>=0.39.2) ; extra == "all"
77
- Requires-Dist: opentelemetry-instrumentation-ollama (>=0.39.2) ; extra == "ollama"
78
- Requires-Dist: opentelemetry-instrumentation-openai (>=0.39.2) ; extra == "all"
79
- Requires-Dist: opentelemetry-instrumentation-openai (>=0.39.2) ; extra == "openai"
80
- Requires-Dist: opentelemetry-instrumentation-pinecone (>=0.39.2) ; extra == "all"
81
- Requires-Dist: opentelemetry-instrumentation-pinecone (>=0.39.2) ; extra == "pinecone"
82
- Requires-Dist: opentelemetry-instrumentation-qdrant (>=0.39.2) ; extra == "all"
83
- Requires-Dist: opentelemetry-instrumentation-qdrant (>=0.39.2) ; extra == "qdrant"
84
- Requires-Dist: opentelemetry-instrumentation-replicate (>=0.39.2) ; extra == "all"
85
- Requires-Dist: opentelemetry-instrumentation-replicate (>=0.39.2) ; extra == "replicate"
86
- Requires-Dist: opentelemetry-instrumentation-requests (>=0.52b0)
87
- Requires-Dist: opentelemetry-instrumentation-sagemaker (>=0.39.2) ; extra == "all"
88
- Requires-Dist: opentelemetry-instrumentation-sagemaker (>=0.39.2) ; extra == "sagemaker"
89
- Requires-Dist: opentelemetry-instrumentation-sqlalchemy (>=0.52b0)
90
- Requires-Dist: opentelemetry-instrumentation-threading (>=0.52b0)
91
- Requires-Dist: opentelemetry-instrumentation-together (>=0.39.2) ; extra == "all"
92
- Requires-Dist: opentelemetry-instrumentation-together (>=0.39.2) ; extra == "together"
93
- Requires-Dist: opentelemetry-instrumentation-transformers (>=0.39.2) ; extra == "all"
94
- Requires-Dist: opentelemetry-instrumentation-transformers (>=0.39.2) ; extra == "transformers"
95
- Requires-Dist: opentelemetry-instrumentation-urllib3 (>=0.52b0)
96
- Requires-Dist: opentelemetry-instrumentation-vertexai (>=0.39.2) ; extra == "all"
97
- Requires-Dist: opentelemetry-instrumentation-vertexai (>=0.39.2) ; extra == "vertexai"
98
- Requires-Dist: opentelemetry-instrumentation-watsonx (>=0.39.2) ; extra == "all"
99
- Requires-Dist: opentelemetry-instrumentation-watsonx (>=0.39.2) ; extra == "watsonx"
100
- Requires-Dist: opentelemetry-instrumentation-weaviate (>=0.39.2) ; extra == "all"
101
- Requires-Dist: opentelemetry-instrumentation-weaviate (>=0.39.2) ; extra == "weaviate"
102
- Requires-Dist: opentelemetry-sdk (>=1.31.1)
103
- Requires-Dist: opentelemetry-semantic-conventions-ai (>=0.4.2)
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-together (>=0.40.5) ; extra == "all"
94
+ Requires-Dist: opentelemetry-instrumentation-together (>=0.40.5) ; extra == "together"
95
+ Requires-Dist: opentelemetry-instrumentation-transformers (>=0.40.5) ; extra == "all"
96
+ Requires-Dist: opentelemetry-instrumentation-transformers (>=0.40.5) ; extra == "transformers"
97
+ Requires-Dist: opentelemetry-instrumentation-vertexai (>=0.40.5) ; extra == "all"
98
+ Requires-Dist: opentelemetry-instrumentation-vertexai (>=0.40.5) ; extra == "vertexai"
99
+ Requires-Dist: opentelemetry-instrumentation-watsonx (>=0.40.5) ; extra == "all"
100
+ Requires-Dist: opentelemetry-instrumentation-watsonx (>=0.40.5) ; extra == "watsonx"
101
+ Requires-Dist: opentelemetry-instrumentation-weaviate (>=0.40.5) ; extra == "all"
102
+ Requires-Dist: opentelemetry-instrumentation-weaviate (>=0.40.5) ; extra == "weaviate"
103
+ Requires-Dist: opentelemetry-sdk (>=1.33.0)
104
+ Requires-Dist: opentelemetry-semantic-conventions (>=0.54b0)
105
+ Requires-Dist: opentelemetry-semantic-conventions-ai (>=0.4.8)
104
106
  Requires-Dist: pydantic (>=2.0.3,<3.0.0)
105
107
  Requires-Dist: python-dotenv (>=1.0)
106
108
  Requires-Dist: tenacity (>=8.0)
@@ -222,7 +224,7 @@ def handle_user_request(topic: str):
222
224
  Laminar allows you to automatically instrument majority of the most popular LLM, Vector DB, database, requests, and other libraries.
223
225
 
224
226
  If you want to automatically instrument a default set of libraries, then simply do NOT pass `instruments` argument to `.initialize()`.
225
- See the full list of available instrumentations in the [enum](https://github.com/lmnr-ai/lmnr-python/blob/main/src/lmnr/openllmetry_sdk/instruments.py).
227
+ See the full list of available instrumentations in the [enum](https://github.com/lmnr-ai/lmnr-python/blob/main/src/lmnr/opentelemetry_lib/instruments.py).
226
228
 
227
229
  If you want to automatically instrument only specific LLM, Vector DB, or other
228
230
  calls with OpenTelemetry-compatible instrumentation, then pass the appropriate instruments to `.initialize()`.
@@ -113,7 +113,7 @@ def handle_user_request(topic: str):
113
113
  Laminar allows you to automatically instrument majority of the most popular LLM, Vector DB, database, requests, and other libraries.
114
114
 
115
115
  If you want to automatically instrument a default set of libraries, then simply do NOT pass `instruments` argument to `.initialize()`.
116
- See the full list of available instrumentations in the [enum](https://github.com/lmnr-ai/lmnr-python/blob/main/src/lmnr/openllmetry_sdk/instruments.py).
116
+ See the full list of available instrumentations in the [enum](https://github.com/lmnr-ai/lmnr-python/blob/main/src/lmnr/opentelemetry_lib/instruments.py).
117
117
 
118
118
  If you want to automatically instrument only specific LLM, Vector DB, or other
119
119
  calls with OpenTelemetry-compatible instrumentation, then pass the appropriate instruments to `.initialize()`.
@@ -0,0 +1,135 @@
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.0"
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
+ ]
40
+
41
+ [project.scripts]
42
+ lmnr = "lmnr.cli:cli"
43
+
44
+ [project.optional-dependencies]
45
+ # List of all possible extras. You can specify one or more of these extras
46
+ # when installing the package, using any of the following examples:
47
+ # `pip install 'lmnr[anthropic,openai]'`
48
+ # `uv pip install 'lmnr[anthropic,openai]'`
49
+ # `uv add lmnr --extra anthropic --extra openai`
50
+ # `poetry add 'lmnr[anthropic,openai]'`
51
+
52
+ alephalpha=["opentelemetry-instrumentation-alephalpha>=0.40.5"]
53
+ anthropic=["opentelemetry-instrumentation-anthropic>=0.40.5"]
54
+ bedrock=["opentelemetry-instrumentation-bedrock>=0.40.5"]
55
+ chromadb=["opentelemetry-instrumentation-chromadb>=0.40.5"]
56
+ cohere=["opentelemetry-instrumentation-cohere>=0.40.5"]
57
+ crewai=["opentelemetry-instrumentation-crewai>=0.40.5"]
58
+ google-generativeai=["opentelemetry-instrumentation-google-generativeai>=0.40.5"]
59
+ groq=["opentelemetry-instrumentation-groq>=0.40.5"]
60
+ haystack=["opentelemetry-instrumentation-haystack>=0.40.5"]
61
+ lancedb=["opentelemetry-instrumentation-lancedb>=0.40.5"]
62
+ langchain=["opentelemetry-instrumentation-langchain>=0.40.5"]
63
+ llamaindex=["opentelemetry-instrumentation-llamaindex>=0.40.5"]
64
+ marqo=["opentelemetry-instrumentation-marqo>=0.40.5"]
65
+ mcp=["opentelemetry-instrumentation-mcp>=0.40.5"]
66
+ milvus=["opentelemetry-instrumentation-milvus>=0.40.5"]
67
+ mistralai=["opentelemetry-instrumentation-mistralai>=0.40.5"]
68
+ ollama=["opentelemetry-instrumentation-ollama>=0.40.5"]
69
+ openai=["opentelemetry-instrumentation-openai>=0.40.5"]
70
+ pinecone=["opentelemetry-instrumentation-pinecone>=0.40.5"]
71
+ qdrant=["opentelemetry-instrumentation-qdrant>=0.40.5"]
72
+ replicate=["opentelemetry-instrumentation-replicate>=0.40.5"]
73
+ sagemaker=["opentelemetry-instrumentation-sagemaker>=0.40.5"]
74
+ together=["opentelemetry-instrumentation-together>=0.40.5"]
75
+ transformers=["opentelemetry-instrumentation-transformers>=0.40.5"]
76
+ vertexai=["opentelemetry-instrumentation-vertexai>=0.40.5"]
77
+ watsonx=["opentelemetry-instrumentation-watsonx>=0.40.5"]
78
+ weaviate=["opentelemetry-instrumentation-weaviate>=0.40.5"]
79
+ # `all` is the group added for convenience, if you want to install all
80
+ # the instrumentations.
81
+ # we suggest using package-manager-specific commands instead,
82
+ # like `uv add lmnr --all-extras`
83
+ all = [
84
+ "opentelemetry-instrumentation-alephalpha>=0.40.5",
85
+ "opentelemetry-instrumentation-anthropic>=0.40.5",
86
+ "opentelemetry-instrumentation-bedrock>=0.40.5",
87
+ "opentelemetry-instrumentation-chromadb>=0.40.5",
88
+ "opentelemetry-instrumentation-cohere>=0.40.5",
89
+ "opentelemetry-instrumentation-crewai>=0.40.5",
90
+ "opentelemetry-instrumentation-google-generativeai>=0.40.5",
91
+ "opentelemetry-instrumentation-groq>=0.40.5",
92
+ "opentelemetry-instrumentation-haystack>=0.40.5",
93
+ "opentelemetry-instrumentation-lancedb>=0.40.5",
94
+ "opentelemetry-instrumentation-langchain>=0.40.5",
95
+ "opentelemetry-instrumentation-llamaindex>=0.40.5",
96
+ "opentelemetry-instrumentation-marqo>=0.40.5",
97
+ "opentelemetry-instrumentation-mcp>=0.40.5",
98
+ "opentelemetry-instrumentation-milvus>=0.40.5",
99
+ "opentelemetry-instrumentation-mistralai>=0.40.5",
100
+ "opentelemetry-instrumentation-ollama>=0.40.5",
101
+ "opentelemetry-instrumentation-openai>=0.40.5",
102
+ "opentelemetry-instrumentation-pinecone>=0.40.5",
103
+ "opentelemetry-instrumentation-qdrant>=0.40.5",
104
+ "opentelemetry-instrumentation-replicate>=0.40.5",
105
+ "opentelemetry-instrumentation-sagemaker>=0.40.5",
106
+ "opentelemetry-instrumentation-together>=0.40.5",
107
+ "opentelemetry-instrumentation-transformers>=0.40.5",
108
+ "opentelemetry-instrumentation-vertexai>=0.40.5",
109
+ "opentelemetry-instrumentation-watsonx>=0.40.5",
110
+ "opentelemetry-instrumentation-weaviate>=0.40.5"
111
+ ]
112
+
113
+ [dependency-groups]
114
+ dev = [
115
+ "autopep8>=2.3.2",
116
+ "flake8>=7.2.0",
117
+ "pytest>=8.3.5",
118
+ "pytest-sugar>=1.0.0",
119
+ "pytest-asyncio>=0.26.0",
120
+ "playwright>=1.51.0",
121
+ "vcrpy>=7.0.0",
122
+ "openai>=1.77.0",
123
+ "pytest-recording>=0.13.4",
124
+ ]
125
+
126
+ [build-system]
127
+ requires = ["poetry-core"]
128
+ build-backend = "poetry.core.masonry.api"
129
+
130
+ [tool.uv.workspace]
131
+ members = ["examples/fastapi-app"]
132
+ # we can move to uv_build, once it's more stable
133
+ # https://github.com/astral-sh/uv/issues/3957
134
+ # requires = ["uv_build>=0.6.16,<0.7"]
135
+ # 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 .openllmetry_sdk import Instruments
17
- from .openllmetry_sdk.tracing.attributes import Attributes
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",
@@ -1,18 +1,17 @@
1
1
  from argparse import ArgumentParser
2
2
  import asyncio
3
3
  import importlib.util
4
- import logging
5
4
  import os
6
5
  import re
7
6
  import sys
7
+ from typing import Optional
8
+
9
+ from lmnr.sdk.evaluations import Evaluation
8
10
 
9
11
  from .sdk.eval_control import PREPARE_ONLY, EVALUATION_INSTANCE
10
- from .sdk.log import ColorfulFormatter
12
+ from .sdk.log import get_default_logger
11
13
 
12
- LOG = logging.getLogger(__name__)
13
- console_log_handler = logging.StreamHandler()
14
- console_log_handler.setFormatter(ColorfulFormatter())
15
- LOG.addHandler(console_log_handler)
14
+ LOG = get_default_logger(__name__)
16
15
 
17
16
 
18
17
  EVAL_DIR = "evals"
@@ -28,7 +27,10 @@ async def run_evaluation(args):
28
27
  if re.match(r".*_eval\.py$", f) or re.match(r"eval_.*\.py$", f)
29
28
  ]
30
29
  if len(files) == 0:
31
- LOG.error("No evaluation files found in evals directory")
30
+ LOG.error("No evaluation files found in `evals` directory")
31
+ LOG.info(
32
+ "Eval files must be located in the `evals` directory and must be named *_eval.py or eval_*.py"
33
+ )
32
34
  return
33
35
  files.sort()
34
36
  LOG.info(f"Located {len(files)} evaluation files in {EVAL_DIR}")
@@ -53,7 +55,7 @@ async def run_evaluation(args):
53
55
  sys.modules[name] = mod
54
56
 
55
57
  spec.loader.exec_module(mod)
56
- evaluation = EVALUATION_INSTANCE.get()
58
+ evaluation: Optional[Evaluation] = EVALUATION_INSTANCE.get()
57
59
  if evaluation is None:
58
60
  LOG.warning("Evaluation instance not found")
59
61
  if args.fail_on_error:
@@ -0,0 +1,55 @@
1
+ import sys
2
+
3
+ from typing import Optional, Set
4
+ from opentelemetry.sdk.trace.export import SpanExporter
5
+ from opentelemetry.sdk.resources import SERVICE_NAME
6
+
7
+ from lmnr.opentelemetry_lib.tracing.instruments import Instruments
8
+ from lmnr.opentelemetry_lib.tracing import TracerWrapper
9
+
10
+ MAX_MANUAL_SPAN_PAYLOAD_SIZE = 1024 * 1024 # 1MB
11
+
12
+
13
+ class TracerManager:
14
+ __tracer_wrapper: TracerWrapper
15
+
16
+ @staticmethod
17
+ def init(
18
+ app_name: Optional[str] = sys.argv[0],
19
+ disable_batch=False,
20
+ exporter: Optional[SpanExporter] = None,
21
+ resource_attributes: dict = {},
22
+ instruments: Optional[Set[Instruments]] = None,
23
+ base_url: str = "https://api.lmnr.ai",
24
+ port: int = 8443,
25
+ http_port: int = 443,
26
+ project_api_key: Optional[str] = None,
27
+ max_export_batch_size: Optional[int] = None,
28
+ force_http: bool = False,
29
+ timeout_seconds: int = 30,
30
+ ) -> None:
31
+ enable_content_tracing = True
32
+
33
+ # Tracer init
34
+ resource_attributes.update({SERVICE_NAME: app_name})
35
+ TracerWrapper.set_static_params(resource_attributes, enable_content_tracing)
36
+ TracerManager.__tracer_wrapper = TracerWrapper(
37
+ disable_batch=disable_batch,
38
+ exporter=exporter,
39
+ instruments=instruments,
40
+ base_url=base_url,
41
+ port=port,
42
+ http_port=http_port,
43
+ project_api_key=project_api_key,
44
+ max_export_batch_size=max_export_batch_size,
45
+ force_http=force_http,
46
+ timeout_seconds=timeout_seconds,
47
+ )
48
+
49
+ @staticmethod
50
+ def flush() -> bool:
51
+ return TracerManager.__tracer_wrapper.flush()
52
+
53
+ @staticmethod
54
+ def shutdown():
55
+ 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.openllmetry_sdk.tracing import get_tracer
14
- from lmnr.openllmetry_sdk.tracing.attributes import SPAN_INPUT, SPAN_OUTPUT, SPAN_TYPE
15
- from lmnr.openllmetry_sdk.tracing.tracing import TracerWrapper
16
- from lmnr.openllmetry_sdk.utils.json_encoder import JSONEncoder
17
- from lmnr.openllmetry_sdk.config import MAX_MANUAL_SPAN_PAYLOAD_SIZE
13
+ from lmnr.opentelemetry_lib import MAX_MANUAL_SPAN_PAYLOAD_SIZE
14
+ from lmnr.opentelemetry_lib.tracing.tracer import get_tracer
15
+ from lmnr.opentelemetry_lib.tracing.attributes import SPAN_INPUT, SPAN_OUTPUT, SPAN_TYPE
16
+ from lmnr.opentelemetry_lib.tracing import TracerWrapper
17
+ from lmnr.opentelemetry_lib.utils.json_encoder import JSONEncoder
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
- # Note: we don't detach the context here as this fails in some situations
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
- context_api.detach(ctx_token)
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):
@@ -34,7 +34,7 @@ def dont_throw(func):
34
34
  return func(*args, **kwargs)
35
35
  except Exception as e:
36
36
  logger.debug(
37
- "OpenLLMetry failed to trace in %s, error: %s",
37
+ "Laminar failed to trace in %s, error: %s",
38
38
  func.__name__,
39
39
  traceback.format_exc(),
40
40
  )