lmnr 0.3.0b1__py3-none-any.whl → 0.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lmnr/__init__.py +1 -0
- lmnr/sdk/client.py +5 -0
- {lmnr-0.3.0b1.dist-info → lmnr-0.3.1.dist-info}/METADATA +33 -14
- {lmnr-0.3.0b1.dist-info → lmnr-0.3.1.dist-info}/RECORD +7 -7
- {lmnr-0.3.0b1.dist-info → lmnr-0.3.1.dist-info}/LICENSE +0 -0
- {lmnr-0.3.0b1.dist-info → lmnr-0.3.1.dist-info}/WHEEL +0 -0
- {lmnr-0.3.0b1.dist-info → lmnr-0.3.1.dist-info}/entry_points.txt +0 -0
lmnr/__init__.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
from .sdk.client import Laminar
|
2
2
|
from .sdk.decorators import observe, lmnr_context, wrap_llm_call
|
3
3
|
from .sdk.interface import trace, TraceContext, SpanContext
|
4
|
+
from .sdk.tracing_types import EvaluateEvent
|
4
5
|
from .sdk.types import ChatMessage, PipelineRunError, PipelineRunResponse, NodeInput
|
lmnr/sdk/client.py
CHANGED
@@ -38,6 +38,11 @@ class Laminar:
|
|
38
38
|
self.project_api_key = dotenv.get_key(
|
39
39
|
dotenv_path=dotenv_path, key_to_get="LMNR_PROJECT_API_KEY"
|
40
40
|
)
|
41
|
+
if not self.project_api_key:
|
42
|
+
raise ValueError(
|
43
|
+
"Please initialize the Laminar object with your project API key or set "
|
44
|
+
"the LMNR_PROJECT_API_KEY environment variable in your environment or .env file"
|
45
|
+
)
|
41
46
|
|
42
47
|
def run(
|
43
48
|
self,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: lmnr
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.1
|
4
4
|
Summary: Python SDK for Laminar AI
|
5
5
|
License: Apache-2.0
|
6
6
|
Author: lmnr.ai
|
@@ -12,7 +12,6 @@ Classifier: Programming Language :: Python :: 3.10
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
14
14
|
Requires-Dist: backoff (>=2.2.1,<3.0.0)
|
15
|
-
Requires-Dist: black (>=24.4.2,<25.0.0)
|
16
15
|
Requires-Dist: openai (>=1.41.1,<2.0.0)
|
17
16
|
Requires-Dist: pydantic (>=2.7.4,<3.0.0)
|
18
17
|
Requires-Dist: python-dotenv (>=1.0.1,<2.0.0)
|
@@ -31,6 +30,24 @@ source .myenv/bin/activate # or use your favorite env management tool
|
|
31
30
|
pip install lmnr
|
32
31
|
```
|
33
32
|
|
33
|
+
Create .env file at the root and add `LMNR_PROJECT_API_KEY` value to it.
|
34
|
+
|
35
|
+
Read more [here](https://docs.lmnr.ai/api-reference/introduction#authentication) on how to get `LMNR_PROJECT_API_KEY`.
|
36
|
+
|
37
|
+
## Sending events
|
38
|
+
|
39
|
+
You can send events in two ways:
|
40
|
+
- `.event(name, value)` – for a pre-defined event with one of possible values.
|
41
|
+
- `.evaluate_event(name, data)` – for an event that our agent checks for and assigns a value from possible values.
|
42
|
+
|
43
|
+
There are 3 types of events:
|
44
|
+
- SCORE - this is an integer score where you specify inclusive minimum and maximum.
|
45
|
+
- CLASS - this is a classifier with one of the possible values.
|
46
|
+
- TAG - this event has no value and can be assigned to a span.
|
47
|
+
|
48
|
+
Important notes:
|
49
|
+
- If event name does not match anything pre-defined in the UI, the event won't be saved.
|
50
|
+
- If event value (when sent with `.event()`) is not in the domain, the event won't be saved.
|
34
51
|
|
35
52
|
## Decorator instrumentation example
|
36
53
|
|
@@ -65,10 +82,11 @@ def poem_writer(topic="turbulence"):
|
|
65
82
|
poem = response.choices[0].message.content
|
66
83
|
|
67
84
|
if topic in poem:
|
68
|
-
|
85
|
+
# send an event with a pre-defined name
|
86
|
+
lmnr_context.event("topic_alignment", "good")
|
69
87
|
|
70
88
|
# to trigger an automatic check for a possible event do:
|
71
|
-
lmnr_context.
|
89
|
+
lmnr_context.evaluate_event("excessive_wordiness", poem)
|
72
90
|
|
73
91
|
return poem
|
74
92
|
|
@@ -94,7 +112,7 @@ Both `TraceContext` and `SpanContext` expose the following interfaces:
|
|
94
112
|
- `end(**kwargs)` – update the current span, and terminate it
|
95
113
|
|
96
114
|
In addition, `SpanContext` allows you to:
|
97
|
-
- `event(name: str, value: str | int
|
115
|
+
- `event(name: str, value: str | int)` - emit a custom event at any point
|
98
116
|
- `evaluate_event(name: str, data: str)` - register a possible event for automatic checking by Laminar.
|
99
117
|
|
100
118
|
Example:
|
@@ -103,11 +121,11 @@ Example:
|
|
103
121
|
import os
|
104
122
|
from openai import OpenAI
|
105
123
|
|
106
|
-
from lmnr import trace, TraceContext, SpanContext
|
124
|
+
from lmnr import trace, TraceContext, SpanContext, EvaluateEvent
|
107
125
|
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
|
108
126
|
|
109
127
|
def poem_writer(t: TraceContext, topic = "turbulence"):
|
110
|
-
span: SpanContext = t.span(name="poem_writer", input=
|
128
|
+
span: SpanContext = t.span(name="poem_writer", input=topic)
|
111
129
|
|
112
130
|
prompt = f"write a poem about {topic}"
|
113
131
|
messages = [
|
@@ -126,15 +144,19 @@ def poem_writer(t: TraceContext, topic = "turbulence"):
|
|
126
144
|
)
|
127
145
|
poem = response.choices[0].message.content
|
128
146
|
if topic in poem:
|
129
|
-
llm_span.event("topic_alignment") # send an event with a pre-defined name
|
147
|
+
llm_span.event("topic_alignment", "good") # send an event with a pre-defined name
|
130
148
|
|
131
|
-
# note that you can register possible events here as well,
|
132
|
-
llm_span.
|
149
|
+
# note that you can register possible events here as well,
|
150
|
+
# not only `llm_span.evaluate_event()`
|
151
|
+
llm_span.end(
|
152
|
+
output=poem,
|
153
|
+
evaluate_events=[EvaluateEvent(name="excessive_wordines", data=poem)]
|
154
|
+
)
|
133
155
|
span.end(output=poem)
|
134
156
|
return poem
|
135
157
|
|
136
158
|
|
137
|
-
t: TraceContext = trace(user_id="
|
159
|
+
t: TraceContext = trace(user_id="user123", session_id="session123", release="release")
|
138
160
|
main(t, topic="laminar flow")
|
139
161
|
t.end(success=True)
|
140
162
|
```
|
@@ -180,7 +202,4 @@ PipelineRunResponse(
|
|
180
202
|
)
|
181
203
|
```
|
182
204
|
|
183
|
-
## PROJECT_API_KEY
|
184
|
-
|
185
|
-
Read more [here](https://docs.lmnr.ai/api-reference/introduction#authentication) on how to get `PROJECT_API_KEY`.
|
186
205
|
|
@@ -1,6 +1,6 @@
|
|
1
|
-
lmnr/__init__.py,sha256=
|
1
|
+
lmnr/__init__.py,sha256=zNJSRkUBTC0iKNvW7vitPS_W7uLnMc4ymAXJrnSM1gk,287
|
2
2
|
lmnr/sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
-
lmnr/sdk/client.py,sha256=
|
3
|
+
lmnr/sdk/client.py,sha256=e6cIvJq38a6XAU8FGWYtNXVAPlEoZEyKS7hC3M_6EkU,5749
|
4
4
|
lmnr/sdk/collector.py,sha256=6LRmPhOcmGplUDWm_sJh0dVrLTHknd_kmq7POGuAvoQ,5338
|
5
5
|
lmnr/sdk/constants.py,sha256=USCfwuUqRx6_0xC8WUxqGj766dInqQkWJcf8U5vPK7s,34
|
6
6
|
lmnr/sdk/context.py,sha256=jfu2HGyZEJYSDf-LQAmmK8MKFnNhYfR66k_baQWx99s,15271
|
@@ -14,8 +14,8 @@ lmnr/sdk/providers/utils.py,sha256=ROt82VrvezExYOxionAynD3dp6oX5JoPW6F1ayTm7q8,9
|
|
14
14
|
lmnr/sdk/tracing_types.py,sha256=RvVb8yCLjCu9DT59OX_tvUxaOTCtE6fcsDH4nMddzHA,6399
|
15
15
|
lmnr/sdk/types.py,sha256=hVxOsa3oCQQ-8aS_WkOtErg4nHJRkBVySfYlTgDlDyk,2084
|
16
16
|
lmnr/sdk/utils.py,sha256=1yhXtdGmVXfnc8SOQiTH_zAZGbZrzO8oaFd7q5nE7eY,3349
|
17
|
-
lmnr-0.3.
|
18
|
-
lmnr-0.3.
|
19
|
-
lmnr-0.3.
|
20
|
-
lmnr-0.3.
|
21
|
-
lmnr-0.3.
|
17
|
+
lmnr-0.3.1.dist-info/LICENSE,sha256=67b_wJHVV1CBaWkrKFWU1wyqTPSdzH77Ls-59631COg,10411
|
18
|
+
lmnr-0.3.1.dist-info/METADATA,sha256=tPHT-aNx5QDEHS6kJs7Z1gk_21_Z6y7hPfpA1klh4Cc,7505
|
19
|
+
lmnr-0.3.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
20
|
+
lmnr-0.3.1.dist-info/entry_points.txt,sha256=Qg7ZRax4k-rcQsZ26XRYQ8YFSBiyY2PNxYfq4a6PYXI,41
|
21
|
+
lmnr-0.3.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|