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 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.0b1
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
- lmnr_context.event("topic_alignment") # send an event with a pre-defined name
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.check_span_event("excessive_wordiness")
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 = None)` - emit a custom event at any point
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=None)
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, not only `llm_span.check_span_event()`
132
- llm_span.end(output=poem, check_event_names=["excessive_wordiness"])
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="user", session_id="session", release="release")
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=U3sQyxCHM9ojzfo05XYxM0T_Bh1StZFSp5K82NjATxc,242
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=6mp4sQF1IEESPYe6ABFgchMBQBKr2AT7eqP-mIC5cEA,5482
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.0b1.dist-info/LICENSE,sha256=67b_wJHVV1CBaWkrKFWU1wyqTPSdzH77Ls-59631COg,10411
18
- lmnr-0.3.0b1.dist-info/METADATA,sha256=U5UBpCkOSbDzsoQw4b4GkJxGKgMlxv8qoVRLzAVupiw,6700
19
- lmnr-0.3.0b1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
20
- lmnr-0.3.0b1.dist-info/entry_points.txt,sha256=Qg7ZRax4k-rcQsZ26XRYQ8YFSBiyY2PNxYfq4a6PYXI,41
21
- lmnr-0.3.0b1.dist-info/RECORD,,
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