lmnr 0.5.1a0__tar.gz → 0.5.3__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 (65) hide show
  1. {lmnr-0.5.1a0 → lmnr-0.5.3}/PKG-INFO +58 -58
  2. {lmnr-0.5.1a0 → lmnr-0.5.3}/README.md +5 -5
  3. lmnr-0.5.3/pyproject.toml +129 -0
  4. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/__init__.py +2 -10
  5. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/cli.py +10 -8
  6. {lmnr-0.5.1a0/src/lmnr/openllmetry_sdk → lmnr-0.5.3/src/lmnr/opentelemetry_lib}/__init__.py +8 -36
  7. {lmnr-0.5.1a0/src/lmnr/openllmetry_sdk → lmnr-0.5.3/src/lmnr/opentelemetry_lib}/decorators/base.py +27 -20
  8. {lmnr-0.5.1a0/src/lmnr/openllmetry_sdk → lmnr-0.5.3/src/lmnr/opentelemetry_lib}/instruments.py +2 -0
  9. lmnr-0.5.3/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/__init__.py +454 -0
  10. lmnr-0.5.3/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/config.py +9 -0
  11. lmnr-0.5.3/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/utils.py +216 -0
  12. lmnr-0.5.3/src/lmnr/opentelemetry_lib/tracing/__init__.py +1 -0
  13. lmnr-0.5.3/src/lmnr/opentelemetry_lib/tracing/context_manager.py +13 -0
  14. {lmnr-0.5.1a0/src/lmnr/openllmetry_sdk → lmnr-0.5.3/src/lmnr/opentelemetry_lib}/tracing/tracing.py +253 -257
  15. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/browser/browser_use_otel.py +20 -3
  16. lmnr-0.5.3/src/lmnr/sdk/browser/patchright_otel.py +177 -0
  17. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/browser/playwright_otel.py +55 -62
  18. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/browser/pw_utils.py +122 -116
  19. lmnr-0.5.3/src/lmnr/sdk/browser/rrweb/rrweb.umd.min.cjs +98 -0
  20. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/client/asynchronous/async_client.py +0 -34
  21. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/client/asynchronous/resources/__init__.py +0 -4
  22. lmnr-0.5.3/src/lmnr/sdk/client/asynchronous/resources/agent.py +329 -0
  23. lmnr-0.5.3/src/lmnr/sdk/client/synchronous/resources/__init__.py +5 -0
  24. lmnr-0.5.3/src/lmnr/sdk/client/synchronous/resources/agent.py +321 -0
  25. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/client/synchronous/sync_client.py +0 -36
  26. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/decorators.py +19 -5
  27. lmnr-0.5.3/src/lmnr/sdk/eval_control.py +5 -0
  28. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/evaluations.py +8 -14
  29. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/laminar.py +10 -10
  30. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/types.py +86 -170
  31. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/utils.py +8 -1
  32. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/version.py +1 -1
  33. lmnr-0.5.1a0/pyproject.toml +0 -122
  34. lmnr-0.5.1a0/src/lmnr/sdk/browser/__init__.py +0 -0
  35. lmnr-0.5.1a0/src/lmnr/sdk/browser/rrweb/rrweb.min.js +0 -18
  36. lmnr-0.5.1a0/src/lmnr/sdk/client/asynchronous/resources/agent.py +0 -220
  37. lmnr-0.5.1a0/src/lmnr/sdk/client/asynchronous/resources/pipeline.py +0 -89
  38. lmnr-0.5.1a0/src/lmnr/sdk/client/asynchronous/resources/semantic_search.py +0 -60
  39. lmnr-0.5.1a0/src/lmnr/sdk/client/synchronous/resources/__init__.py +0 -7
  40. lmnr-0.5.1a0/src/lmnr/sdk/client/synchronous/resources/agent.py +0 -215
  41. lmnr-0.5.1a0/src/lmnr/sdk/client/synchronous/resources/pipeline.py +0 -89
  42. lmnr-0.5.1a0/src/lmnr/sdk/client/synchronous/resources/semantic_search.py +0 -60
  43. lmnr-0.5.1a0/src/lmnr/sdk/eval_control.py +0 -4
  44. {lmnr-0.5.1a0 → lmnr-0.5.3}/LICENSE +0 -0
  45. {lmnr-0.5.1a0/src/lmnr/openllmetry_sdk → lmnr-0.5.3/src/lmnr/opentelemetry_lib}/.flake8 +0 -0
  46. {lmnr-0.5.1a0/src/lmnr/openllmetry_sdk → lmnr-0.5.3/src/lmnr/opentelemetry_lib}/config/__init__.py +0 -0
  47. {lmnr-0.5.1a0/src/lmnr/openllmetry_sdk → lmnr-0.5.3/src/lmnr/opentelemetry_lib}/decorators/__init__.py +0 -0
  48. {lmnr-0.5.1a0/src/lmnr/openllmetry_sdk → lmnr-0.5.3/src/lmnr/opentelemetry_lib}/tracing/attributes.py +0 -0
  49. {lmnr-0.5.1a0/src/lmnr/openllmetry_sdk → lmnr-0.5.3/src/lmnr/opentelemetry_lib}/tracing/content_allow_list.py +0 -0
  50. {lmnr-0.5.1a0/src/lmnr/openllmetry_sdk → lmnr-0.5.3/src/lmnr/opentelemetry_lib}/utils/__init__.py +0 -0
  51. {lmnr-0.5.1a0/src/lmnr/openllmetry_sdk → lmnr-0.5.3/src/lmnr/opentelemetry_lib}/utils/in_memory_span_exporter.py +0 -0
  52. {lmnr-0.5.1a0/src/lmnr/openllmetry_sdk → lmnr-0.5.3/src/lmnr/opentelemetry_lib}/utils/json_encoder.py +0 -0
  53. {lmnr-0.5.1a0/src/lmnr/openllmetry_sdk → lmnr-0.5.3/src/lmnr/opentelemetry_lib}/utils/package_check.py +0 -0
  54. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/py.typed +0 -0
  55. {lmnr-0.5.1a0/src/lmnr/openllmetry_sdk/tracing → lmnr-0.5.3/src/lmnr/sdk}/__init__.py +0 -0
  56. {lmnr-0.5.1a0/src/lmnr/sdk → lmnr-0.5.3/src/lmnr/sdk/browser}/__init__.py +0 -0
  57. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/browser/utils.py +0 -0
  58. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/client/asynchronous/resources/base.py +0 -0
  59. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/client/asynchronous/resources/browser_events.py +0 -0
  60. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/client/asynchronous/resources/evals.py +0 -0
  61. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/client/synchronous/resources/base.py +0 -0
  62. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/client/synchronous/resources/browser_events.py +0 -0
  63. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/client/synchronous/resources/evals.py +0 -0
  64. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/datasets.py +0 -0
  65. {lmnr-0.5.1a0 → lmnr-0.5.3}/src/lmnr/sdk/log.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: lmnr
3
- Version: 0.5.1a0
3
+ Version: 0.5.3
4
4
  Summary: Python SDK for Laminar
5
5
  License: Apache-2.0
6
6
  Author: lmnr.ai
@@ -41,67 +41,67 @@ Provides-Extra: watsonx
41
41
  Provides-Extra: weaviate
42
42
  Requires-Dist: argparse (>=1.0)
43
43
  Requires-Dist: grpcio (<1.68.0)
44
- Requires-Dist: httpx (>=0.28.1)
44
+ Requires-Dist: httpx (>=0.25.0)
45
45
  Requires-Dist: opentelemetry-api (>=1.31.1)
46
46
  Requires-Dist: opentelemetry-exporter-otlp-proto-grpc (>=1.31.1)
47
47
  Requires-Dist: opentelemetry-exporter-otlp-proto-http (>=1.31.1)
48
- Requires-Dist: opentelemetry-instrumentation-alephalpha (>=0.38.12) ; extra == "alephalpha"
49
- Requires-Dist: opentelemetry-instrumentation-alephalpha (>=0.38.12) ; extra == "all"
50
- Requires-Dist: opentelemetry-instrumentation-anthropic (>=0.38.12) ; extra == "all"
51
- Requires-Dist: opentelemetry-instrumentation-anthropic (>=0.38.12) ; extra == "anthropic"
52
- Requires-Dist: opentelemetry-instrumentation-bedrock (>=0.38.12) ; extra == "all"
53
- Requires-Dist: opentelemetry-instrumentation-bedrock (>=0.38.12) ; extra == "bedrock"
54
- Requires-Dist: opentelemetry-instrumentation-chromadb (>=0.38.12) ; extra == "all"
55
- Requires-Dist: opentelemetry-instrumentation-chromadb (>=0.38.12) ; extra == "chromadb"
56
- Requires-Dist: opentelemetry-instrumentation-cohere (>=0.38.12) ; extra == "all"
57
- Requires-Dist: opentelemetry-instrumentation-cohere (>=0.38.12) ; extra == "cohere"
58
- Requires-Dist: opentelemetry-instrumentation-google-generativeai (>=0.38.12) ; extra == "all"
59
- Requires-Dist: opentelemetry-instrumentation-google-generativeai (>=0.38.12) ; extra == "google-generativeai"
60
- Requires-Dist: opentelemetry-instrumentation-groq (>=0.38.12) ; extra == "all"
61
- Requires-Dist: opentelemetry-instrumentation-groq (>=0.38.12) ; extra == "groq"
62
- Requires-Dist: opentelemetry-instrumentation-haystack (>=0.38.12) ; extra == "all"
63
- Requires-Dist: opentelemetry-instrumentation-haystack (>=0.38.12) ; extra == "haystack"
64
- Requires-Dist: opentelemetry-instrumentation-lancedb (>=0.38.12) ; extra == "all"
65
- Requires-Dist: opentelemetry-instrumentation-lancedb (>=0.38.12) ; extra == "lancedb"
66
- Requires-Dist: opentelemetry-instrumentation-langchain (>=0.38.12) ; extra == "all"
67
- Requires-Dist: opentelemetry-instrumentation-langchain (>=0.38.12) ; extra == "langchain"
68
- Requires-Dist: opentelemetry-instrumentation-llamaindex (>=0.38.12) ; extra == "all"
69
- Requires-Dist: opentelemetry-instrumentation-llamaindex (>=0.38.12) ; extra == "llamaindex"
70
- Requires-Dist: opentelemetry-instrumentation-marqo (>=0.38.12) ; extra == "all"
71
- Requires-Dist: opentelemetry-instrumentation-marqo (>=0.38.12) ; extra == "marqo"
72
- Requires-Dist: opentelemetry-instrumentation-milvus (>=0.38.12) ; extra == "all"
73
- Requires-Dist: opentelemetry-instrumentation-milvus (>=0.38.12) ; extra == "milvus"
74
- Requires-Dist: opentelemetry-instrumentation-mistralai (>=0.38.12) ; extra == "all"
75
- Requires-Dist: opentelemetry-instrumentation-mistralai (>=0.38.12) ; extra == "mistralai"
76
- Requires-Dist: opentelemetry-instrumentation-ollama (>=0.38.12) ; extra == "all"
77
- Requires-Dist: opentelemetry-instrumentation-ollama (>=0.38.12) ; extra == "ollama"
78
- Requires-Dist: opentelemetry-instrumentation-openai (>=0.38.12) ; extra == "all"
79
- Requires-Dist: opentelemetry-instrumentation-openai (>=0.38.12) ; extra == "openai"
80
- Requires-Dist: opentelemetry-instrumentation-pinecone (>=0.38.12) ; extra == "all"
81
- Requires-Dist: opentelemetry-instrumentation-pinecone (>=0.38.12) ; extra == "pinecone"
82
- Requires-Dist: opentelemetry-instrumentation-qdrant (>=0.38.12) ; extra == "all"
83
- Requires-Dist: opentelemetry-instrumentation-qdrant (>=0.38.12) ; extra == "qdrant"
84
- Requires-Dist: opentelemetry-instrumentation-replicate (>=0.38.12) ; extra == "all"
85
- Requires-Dist: opentelemetry-instrumentation-replicate (>=0.38.12) ; extra == "replicate"
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
86
  Requires-Dist: opentelemetry-instrumentation-requests (>=0.52b0)
87
- Requires-Dist: opentelemetry-instrumentation-sagemaker (>=0.38.12) ; extra == "all"
88
- Requires-Dist: opentelemetry-instrumentation-sagemaker (>=0.38.12) ; extra == "sagemaker"
87
+ Requires-Dist: opentelemetry-instrumentation-sagemaker (>=0.39.2) ; extra == "all"
88
+ Requires-Dist: opentelemetry-instrumentation-sagemaker (>=0.39.2) ; extra == "sagemaker"
89
89
  Requires-Dist: opentelemetry-instrumentation-sqlalchemy (>=0.52b0)
90
90
  Requires-Dist: opentelemetry-instrumentation-threading (>=0.52b0)
91
- Requires-Dist: opentelemetry-instrumentation-together (>=0.38.12) ; extra == "all"
92
- Requires-Dist: opentelemetry-instrumentation-together (>=0.38.12) ; extra == "together"
93
- Requires-Dist: opentelemetry-instrumentation-transformers (>=0.38.12) ; extra == "all"
94
- Requires-Dist: opentelemetry-instrumentation-transformers (>=0.38.12) ; extra == "transformers"
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
95
  Requires-Dist: opentelemetry-instrumentation-urllib3 (>=0.52b0)
96
- Requires-Dist: opentelemetry-instrumentation-vertexai (>=0.38.12) ; extra == "all"
97
- Requires-Dist: opentelemetry-instrumentation-vertexai (>=0.38.12) ; extra == "vertexai"
98
- Requires-Dist: opentelemetry-instrumentation-watsonx (>=0.38.12) ; extra == "all"
99
- Requires-Dist: opentelemetry-instrumentation-watsonx (>=0.38.12) ; extra == "watsonx"
100
- Requires-Dist: opentelemetry-instrumentation-weaviate (>=0.38.12) ; extra == "all"
101
- Requires-Dist: opentelemetry-instrumentation-weaviate (>=0.38.12) ; extra == "weaviate"
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
102
  Requires-Dist: opentelemetry-sdk (>=1.31.1)
103
103
  Requires-Dist: opentelemetry-semantic-conventions-ai (>=0.4.2)
104
- Requires-Dist: pydantic (>=2.0.3)
104
+ Requires-Dist: pydantic (>=2.0.3,<3.0.0)
105
105
  Requires-Dist: python-dotenv (>=1.0)
106
106
  Requires-Dist: tenacity (>=8.0)
107
107
  Requires-Dist: tqdm (>=4.0)
@@ -222,7 +222,7 @@ def handle_user_request(topic: str):
222
222
  Laminar allows you to automatically instrument majority of the most popular LLM, Vector DB, database, requests, and other libraries.
223
223
 
224
224
  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).
225
+ 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
226
 
227
227
  If you want to automatically instrument only specific LLM, Vector DB, or other
228
228
  calls with OpenTelemetry-compatible instrumentation, then pass the appropriate instruments to `.initialize()`.
@@ -335,9 +335,9 @@ for chunk in client.agent.run(
335
335
  prompt="What is the weather in London today?",
336
336
  stream=True
337
337
  ):
338
- if chunk.chunkType == 'step':
338
+ if chunk.chunk_type == 'step':
339
339
  print(chunk.summary)
340
- elif chunk.chunkType == 'finalOutput':
340
+ elif chunk.chunk_type == 'finalOutput':
341
341
  print(chunk.content.result.content)
342
342
  ```
343
343
 
@@ -371,9 +371,9 @@ async for chunk in client.agent.run(
371
371
  prompt="What is the weather in London today?",
372
372
  stream=True
373
373
  ):
374
- if chunk.chunkType == 'step':
374
+ if chunk.chunk_type == 'step':
375
375
  print(chunk.summary)
376
- elif chunk.chunkType == 'finalOutput':
376
+ elif chunk.chunk_type == 'finalOutput':
377
377
  print(chunk.content.result.content)
378
378
  ```
379
379
 
@@ -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()`.
@@ -226,9 +226,9 @@ for chunk in client.agent.run(
226
226
  prompt="What is the weather in London today?",
227
227
  stream=True
228
228
  ):
229
- if chunk.chunkType == 'step':
229
+ if chunk.chunk_type == 'step':
230
230
  print(chunk.summary)
231
- elif chunk.chunkType == 'finalOutput':
231
+ elif chunk.chunk_type == 'finalOutput':
232
232
  print(chunk.content.result.content)
233
233
  ```
234
234
 
@@ -262,8 +262,8 @@ async for chunk in client.agent.run(
262
262
  prompt="What is the weather in London today?",
263
263
  stream=True
264
264
  ):
265
- if chunk.chunkType == 'step':
265
+ if chunk.chunk_type == 'step':
266
266
  print(chunk.summary)
267
- elif chunk.chunkType == 'finalOutput':
267
+ elif chunk.chunk_type == 'finalOutput':
268
268
  print(chunk.content.result.content)
269
269
  ```
@@ -0,0 +1,129 @@
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.5.3"
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.9,<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.31.1)",
21
+ "opentelemetry-sdk (>=1.31.1)",
22
+ "opentelemetry-exporter-otlp-proto-http (>=1.31.1)",
23
+ "opentelemetry-exporter-otlp-proto-grpc (>=1.31.1)",
24
+ "opentelemetry-instrumentation-requests (>=0.52b0)",
25
+ "opentelemetry-instrumentation-sqlalchemy (>=0.52b0)",
26
+ "opentelemetry-instrumentation-urllib3 (>=0.52b0)",
27
+ "opentelemetry-instrumentation-threading (>=0.52b0)",
28
+ "opentelemetry-semantic-conventions-ai (>=0.4.2)",
29
+ "tqdm (>=4.0)",
30
+ "argparse (>=1.0)",
31
+ "tenacity (>=8.0)",
32
+ # explicitly freeze grpcio. Since 1.68.0, grpcio writes a warning message
33
+ # that looks scary, but is harmless.
34
+ # WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
35
+ # E0000 00:00:1737439981.199902 9456033 init.cc:229] grpc_wait_for_shutdown_with_timeout() timed out.
36
+ #
37
+ # Related issue:
38
+ # 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
39
+ # https://github.com/grpc/grpc/issues/38490
40
+ "grpcio<1.68.0",
41
+ "httpx>=0.25.0",
42
+ ]
43
+
44
+ [project.scripts]
45
+ lmnr = "lmnr.cli:cli"
46
+
47
+ [project.optional-dependencies]
48
+ # List of all possible extras. You can specify one or more of these extras
49
+ # when installing the package, using any of the following examples:
50
+ # `pip install 'lmnr[anthropic,openai]'`
51
+ # `uv pip install 'lmnr[anthropic,openai]'`
52
+ # `uv add lmnr --extra anthropic --extra openai`
53
+ # `poetry add 'lmnr[anthropic,openai]'`
54
+
55
+ alephalpha=["opentelemetry-instrumentation-alephalpha>=0.39.2"]
56
+ anthropic=["opentelemetry-instrumentation-anthropic>=0.39.2"]
57
+ bedrock=["opentelemetry-instrumentation-bedrock>=0.39.2"]
58
+ chromadb=["opentelemetry-instrumentation-chromadb>=0.39.2"]
59
+ cohere=["opentelemetry-instrumentation-cohere>=0.39.2"]
60
+ google-generativeai=["opentelemetry-instrumentation-google-generativeai>=0.39.2"]
61
+ groq=["opentelemetry-instrumentation-groq>=0.39.2"]
62
+ haystack=["opentelemetry-instrumentation-haystack>=0.39.2"]
63
+ lancedb=["opentelemetry-instrumentation-lancedb>=0.39.2"]
64
+ langchain=["opentelemetry-instrumentation-langchain>=0.39.2"]
65
+ llamaindex=["opentelemetry-instrumentation-llamaindex>=0.39.2"]
66
+ marqo=["opentelemetry-instrumentation-marqo>=0.39.2"]
67
+ milvus=["opentelemetry-instrumentation-milvus>=0.39.2"]
68
+ mistralai=["opentelemetry-instrumentation-mistralai>=0.39.2"]
69
+ ollama=["opentelemetry-instrumentation-ollama>=0.39.2"]
70
+ openai=["opentelemetry-instrumentation-openai>=0.39.2"]
71
+ pinecone=["opentelemetry-instrumentation-pinecone>=0.39.2"]
72
+ qdrant=["opentelemetry-instrumentation-qdrant>=0.39.2"]
73
+ replicate=["opentelemetry-instrumentation-replicate>=0.39.2"]
74
+ sagemaker=["opentelemetry-instrumentation-sagemaker>=0.39.2"]
75
+ together=["opentelemetry-instrumentation-together>=0.39.2"]
76
+ transformers=["opentelemetry-instrumentation-transformers>=0.39.2"]
77
+ vertexai=["opentelemetry-instrumentation-vertexai>=0.39.2"]
78
+ watsonx=["opentelemetry-instrumentation-watsonx>=0.39.2"]
79
+ weaviate=["opentelemetry-instrumentation-weaviate>=0.39.2"]
80
+ # `all` is the group added for convenience, if you want to install all
81
+ # the instrumentations.
82
+ all = [
83
+ "opentelemetry-instrumentation-alephalpha>=0.39.2",
84
+ "opentelemetry-instrumentation-anthropic>=0.39.2",
85
+ "opentelemetry-instrumentation-bedrock>=0.39.2",
86
+ "opentelemetry-instrumentation-chromadb>=0.39.2",
87
+ "opentelemetry-instrumentation-cohere>=0.39.2",
88
+ "opentelemetry-instrumentation-google-generativeai>=0.39.2",
89
+ "opentelemetry-instrumentation-groq>=0.39.2",
90
+ "opentelemetry-instrumentation-haystack>=0.39.2",
91
+ "opentelemetry-instrumentation-lancedb>=0.39.2",
92
+ "opentelemetry-instrumentation-langchain>=0.39.2",
93
+ "opentelemetry-instrumentation-llamaindex>=0.39.2",
94
+ "opentelemetry-instrumentation-marqo>=0.39.2",
95
+ "opentelemetry-instrumentation-milvus>=0.39.2",
96
+ "opentelemetry-instrumentation-mistralai>=0.39.2",
97
+ "opentelemetry-instrumentation-ollama>=0.39.2",
98
+ "opentelemetry-instrumentation-openai>=0.39.2",
99
+ "opentelemetry-instrumentation-pinecone>=0.39.2",
100
+ "opentelemetry-instrumentation-qdrant>=0.39.2",
101
+ "opentelemetry-instrumentation-replicate>=0.39.2",
102
+ "opentelemetry-instrumentation-sagemaker>=0.39.2",
103
+ "opentelemetry-instrumentation-together>=0.39.2",
104
+ "opentelemetry-instrumentation-transformers>=0.39.2",
105
+ "opentelemetry-instrumentation-vertexai>=0.39.2",
106
+ "opentelemetry-instrumentation-watsonx>=0.39.2",
107
+ "opentelemetry-instrumentation-weaviate>=0.39.2"
108
+ ]
109
+
110
+ [dependency-groups]
111
+ dev = [
112
+ "autopep8",
113
+ "flake8",
114
+ "pytest>=8.3.5",
115
+ "pytest-sugar>=1.0.0",
116
+ "pytest-asyncio>=0.26.0",
117
+ "playwright>=1.51.0"
118
+ ]
119
+
120
+ [build-system]
121
+ requires = ["poetry-core"]
122
+ build-backend = "poetry.core.masonry.api"
123
+
124
+ [tool.uv.workspace]
125
+ members = ["examples/fastapi-app"]
126
+ # we can move to uv_build, once it's more stable
127
+ # https://github.com/astral-sh/uv/issues/3957
128
+ # requires = ["uv_build>=0.6.16,<0.7"]
129
+ # build-backend = "uv_build"
@@ -6,26 +6,21 @@ from .sdk.laminar import Laminar
6
6
  from .sdk.types import (
7
7
  AgentOutput,
8
8
  FinalOutputChunkContent,
9
- ChatMessage,
10
9
  HumanEvaluator,
11
- NodeInput,
12
- PipelineRunError,
13
- PipelineRunResponse,
14
10
  RunAgentResponseChunk,
15
11
  StepChunkContent,
16
12
  TracingLevel,
17
13
  )
18
14
  from .sdk.decorators import observe
19
15
  from .sdk.types import LaminarSpanContext
20
- from .openllmetry_sdk import Instruments
21
- from .openllmetry_sdk.tracing.attributes import Attributes
16
+ from .opentelemetry_lib import Instruments
17
+ from .opentelemetry_lib.tracing.attributes import Attributes
22
18
  from opentelemetry.trace import use_span
23
19
 
24
20
  __all__ = [
25
21
  "AgentOutput",
26
22
  "AsyncLaminarClient",
27
23
  "Attributes",
28
- "ChatMessage",
29
24
  "EvaluationDataset",
30
25
  "FinalOutputChunkContent",
31
26
  "HumanEvaluator",
@@ -34,9 +29,6 @@ __all__ = [
34
29
  "LaminarClient",
35
30
  "LaminarDataset",
36
31
  "LaminarSpanContext",
37
- "NodeInput",
38
- "PipelineRunError",
39
- "PipelineRunResponse",
40
32
  "RunAgentResponseChunk",
41
33
  "StepChunkContent",
42
34
  "TracingLevel",
@@ -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:
@@ -1,6 +1,5 @@
1
1
  import sys
2
2
 
3
- from contextlib import contextmanager
4
3
  from typing import Optional, Set
5
4
  from opentelemetry.sdk.trace import SpanProcessor
6
5
  from opentelemetry.sdk.trace.export import SpanExporter
@@ -8,18 +7,17 @@ from opentelemetry.sdk.resources import SERVICE_NAME
8
7
  from opentelemetry.propagators.textmap import TextMapPropagator
9
8
  from opentelemetry.util.re import parse_env_headers
10
9
 
11
- from lmnr.openllmetry_sdk.instruments import Instruments
12
- from lmnr.openllmetry_sdk.config import (
10
+ from lmnr.opentelemetry_lib.instruments import Instruments
11
+ from lmnr.opentelemetry_lib.config import (
13
12
  is_content_tracing_enabled,
14
13
  is_tracing_enabled,
15
14
  )
16
- from lmnr.openllmetry_sdk.tracing.tracing import TracerWrapper
15
+ from lmnr.opentelemetry_lib.tracing.tracing import TracerWrapper
17
16
  from typing import Dict
18
17
 
19
18
 
20
19
  class TracerManager:
21
20
  __tracer_wrapper: TracerWrapper
22
- __initialized: bool = False
23
21
 
24
22
  @staticmethod
25
23
  def init(
@@ -53,6 +51,9 @@ class TracerManager:
53
51
 
54
52
  # Tracer init
55
53
  resource_attributes.update({SERVICE_NAME: app_name})
54
+ TracerWrapper.set_static_params(
55
+ resource_attributes, enable_content_tracing, api_endpoint, headers
56
+ )
56
57
  TracerManager.__tracer_wrapper = TracerWrapper(
57
58
  disable_batch=disable_batch,
58
59
  processor=processor,
@@ -63,41 +64,12 @@ class TracerManager:
63
64
  base_http_url=base_http_url,
64
65
  project_api_key=project_api_key,
65
66
  max_export_batch_size=max_export_batch_size,
66
- resource_attributes=resource_attributes,
67
- enable_content_tracing=enable_content_tracing,
68
- endpoint=api_endpoint,
69
- headers=headers,
70
67
  )
71
- TracerManager.__initialized = True
72
68
 
73
69
  @staticmethod
74
70
  def flush() -> bool:
75
71
  return TracerManager.__tracer_wrapper.flush()
76
72
 
77
73
  @staticmethod
78
- def shutdown() -> bool:
79
- try:
80
- res = TracerManager.__tracer_wrapper.shutdown()
81
- TracerManager.__tracer_wrapper = None
82
- TracerManager.__initialized = False
83
- return res
84
- except Exception:
85
- return False
86
-
87
- @staticmethod
88
- def is_initialized() -> bool:
89
- return TracerManager.__initialized
90
-
91
- @staticmethod
92
- def get_tracer_wrapper() -> TracerWrapper:
93
- return TracerManager.__tracer_wrapper
94
-
95
-
96
- @contextmanager
97
- def get_tracer(flush_on_exit: bool = False):
98
- wrapper = TracerManager.get_tracer_wrapper()
99
- try:
100
- yield wrapper.get_tracer()
101
- finally:
102
- if flush_on_exit:
103
- wrapper.flush()
74
+ def shutdown():
75
+ TracerManager.__tracer_wrapper.shutdown()
@@ -1,7 +1,6 @@
1
1
  import json
2
2
  from functools import wraps
3
3
  import logging
4
- import os
5
4
  import pydantic
6
5
  import types
7
6
  from typing import Any, Literal, Optional, Union
@@ -11,11 +10,11 @@ from opentelemetry import context as context_api
11
10
  from opentelemetry.trace import Span
12
11
 
13
12
  from lmnr.sdk.utils import get_input_from_func_args, is_method
14
- from lmnr.openllmetry_sdk import get_tracer
15
- from lmnr.openllmetry_sdk.tracing.attributes import SPAN_INPUT, SPAN_OUTPUT, SPAN_TYPE
16
- from lmnr.openllmetry_sdk import TracerManager
17
- from lmnr.openllmetry_sdk.utils.json_encoder import JSONEncoder
18
- from lmnr.openllmetry_sdk.config import MAX_MANUAL_SPAN_PAYLOAD_SIZE
13
+ from lmnr.opentelemetry_lib.tracing import get_tracer
14
+ from lmnr.opentelemetry_lib.tracing.attributes import SPAN_INPUT, SPAN_OUTPUT, SPAN_TYPE
15
+ from lmnr.opentelemetry_lib.tracing.tracing import TracerWrapper
16
+ from lmnr.opentelemetry_lib.utils.json_encoder import JSONEncoder
17
+ from lmnr.opentelemetry_lib.config import MAX_MANUAL_SPAN_PAYLOAD_SIZE
19
18
 
20
19
 
21
20
  class CustomJSONEncoder(JSONEncoder):
@@ -40,13 +39,14 @@ def json_dumps(data: dict) -> str:
40
39
  def entity_method(
41
40
  name: Optional[str] = None,
42
41
  ignore_input: bool = False,
42
+ ignore_inputs: Optional[list[str]] = None,
43
43
  ignore_output: bool = False,
44
44
  span_type: Union[Literal["DEFAULT"], Literal["LLM"], Literal["TOOL"]] = "DEFAULT",
45
45
  ):
46
46
  def decorate(fn):
47
47
  @wraps(fn)
48
48
  def wrap(*args, **kwargs):
49
- if not TracerManager.is_initialized():
49
+ if not TracerWrapper.verify_initialized():
50
50
  return fn(*args, **kwargs)
51
51
 
52
52
  span_name = name or fn.__name__
@@ -58,9 +58,15 @@ def entity_method(
58
58
  ctx_token = context_api.attach(ctx)
59
59
 
60
60
  try:
61
- if _should_send_prompts() and not ignore_input:
61
+ if not ignore_input:
62
62
  inp = json_dumps(
63
- get_input_from_func_args(fn, is_method(fn), args, kwargs)
63
+ get_input_from_func_args(
64
+ fn,
65
+ is_method=is_method(fn),
66
+ func_args=args,
67
+ func_kwargs=kwargs,
68
+ ignore_inputs=ignore_inputs,
69
+ )
64
70
  )
65
71
  if len(inp) > MAX_MANUAL_SPAN_PAYLOAD_SIZE:
66
72
  span.set_attribute(
@@ -83,7 +89,7 @@ def entity_method(
83
89
  return _handle_generator(span, res)
84
90
 
85
91
  try:
86
- if _should_send_prompts() and not ignore_output:
92
+ if not ignore_output:
87
93
  output = json_dumps(res)
88
94
  if len(output) > MAX_MANUAL_SPAN_PAYLOAD_SIZE:
89
95
  span.set_attribute(
@@ -108,13 +114,14 @@ def entity_method(
108
114
  def aentity_method(
109
115
  name: Optional[str] = None,
110
116
  ignore_input: bool = False,
117
+ ignore_inputs: Optional[list[str]] = None,
111
118
  ignore_output: bool = False,
112
119
  span_type: Union[Literal["DEFAULT"], Literal["LLM"], Literal["TOOL"]] = "DEFAULT",
113
120
  ):
114
121
  def decorate(fn):
115
122
  @wraps(fn)
116
123
  async def wrap(*args, **kwargs):
117
- if not TracerManager.is_initialized():
124
+ if not TracerWrapper.verify_initialized():
118
125
  return await fn(*args, **kwargs)
119
126
 
120
127
  span_name = name or fn.__name__
@@ -126,9 +133,15 @@ def aentity_method(
126
133
  ctx_token = context_api.attach(ctx)
127
134
 
128
135
  try:
129
- if _should_send_prompts() and not ignore_input:
136
+ if not ignore_input:
130
137
  inp = json_dumps(
131
- get_input_from_func_args(fn, is_method(fn), args, kwargs)
138
+ get_input_from_func_args(
139
+ fn,
140
+ is_method=is_method(fn),
141
+ func_args=args,
142
+ func_kwargs=kwargs,
143
+ ignore_inputs=ignore_inputs,
144
+ )
132
145
  )
133
146
  if len(inp) > MAX_MANUAL_SPAN_PAYLOAD_SIZE:
134
147
  span.set_attribute(
@@ -151,7 +164,7 @@ def aentity_method(
151
164
  return await _ahandle_generator(span, ctx_token, res)
152
165
 
153
166
  try:
154
- if _should_send_prompts() and not ignore_output:
167
+ if not ignore_output:
155
168
  output = json_dumps(res)
156
169
  if len(output) > MAX_MANUAL_SPAN_PAYLOAD_SIZE:
157
170
  span.set_attribute(
@@ -192,12 +205,6 @@ async def _ahandle_generator(span, ctx_token, res):
192
205
  context_api.detach(ctx_token)
193
206
 
194
207
 
195
- def _should_send_prompts():
196
- return (
197
- os.getenv("TRACELOOP_TRACE_CONTENT") or "true"
198
- ).lower() == "true" or context_api.get_value("override_enable_content_tracing")
199
-
200
-
201
208
  def _process_exception(span: Span, e: Exception):
202
209
  # Note that this `escaped` is sent as a StringValue("True"), not a boolean.
203
210
  span.record_exception(e, escaped=True)
@@ -11,6 +11,7 @@ class Instruments(Enum):
11
11
  CHROMA = "chroma"
12
12
  COHERE = "cohere"
13
13
  GOOGLE_GENERATIVEAI = "google_generativeai"
14
+ GOOGLE_GENAI = "google_genai"
14
15
  GROQ = "groq"
15
16
  HAYSTACK = "haystack"
16
17
  LANCEDB = "lancedb"
@@ -23,6 +24,7 @@ class Instruments(Enum):
23
24
  OPENAI = "openai"
24
25
  PINECONE = "pinecone"
25
26
  PLAYWRIGHT = "playwright"
27
+ PATCHRIGHT = "patchright"
26
28
  QDRANT = "qdrant"
27
29
  REPLICATE = "replicate"
28
30
  SAGEMAKER = "sagemaker"