lmnr 0.4.4__py3-none-any.whl → 0.4.5__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/sdk/laminar.py CHANGED
@@ -11,7 +11,7 @@ from traceloop.sdk import Traceloop
11
11
  from traceloop.sdk.tracing import get_tracer
12
12
 
13
13
  from pydantic.alias_generators import to_snake
14
- from typing import Any, Optional, Tuple, Union
14
+ from typing import Any, Optional, Union
15
15
 
16
16
  import copy
17
17
  import datetime
@@ -289,7 +289,7 @@ class Laminar:
289
289
  cls,
290
290
  name: str,
291
291
  input: Any = None,
292
- ) -> Tuple[Span, object]:
292
+ ) -> Span:
293
293
  """Start a new span with the given name. Useful for manual
294
294
  instrumentation.
295
295
 
@@ -304,33 +304,34 @@ class Laminar:
304
304
  that must be passed to `end_span` to end the span.
305
305
 
306
306
  """
307
- with get_tracer() as tracer:
308
- span = tracer.start_span(name)
309
- ctx = set_span_in_context(span)
310
- token = context.attach(ctx)
311
- span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_NAME, name)
312
- if input is not None:
313
- span.set_attribute(
314
- SpanAttributes.TRACELOOP_ENTITY_INPUT, json.dumps({"input": input})
315
- )
316
- return (span, token)
307
+ tracer = get_tracer().__enter__()
308
+ span = tracer.start_span(name)
309
+ # apparently, detaching from this context is not mandatory.
310
+ # According to traceloop, and the github issue in opentelemetry,
311
+ # the context is collected by the garbage collector.
312
+ # https://github.com/open-telemetry/opentelemetry-python/issues/2606#issuecomment-2106320379
313
+ context.attach(set_span_in_context(span))
314
+
315
+ if input is not None:
316
+ span.set_attribute(
317
+ SpanAttributes.TRACELOOP_ENTITY_INPUT, json.dumps({"input": input})
318
+ )
319
+
320
+ return span
317
321
 
318
322
  @classmethod
319
- def end_span(cls, span: Span, token: object, output: Any = None):
320
- """End the span started with `start_span`
323
+ def set_span_output(cls, span: Span, output: Any = None):
324
+ """Set the output of the span. Useful for manual instrumentation.
321
325
 
322
326
  Args:
323
- span (Span): span returned by `start_span`
324
- token (object): context token returned by `start_span`
327
+ span (Span): the span to set the output for
325
328
  output (Any, optional): output of the span. Will be sent as an
326
329
  attribute, so must be json serializable. Defaults to None.
327
330
  """
328
331
  if output is not None:
329
332
  span.set_attribute(
330
- SpanAttributes.TRACELOOP_ENTITY_OUTPUT, json.dumps({"output": output})
333
+ SpanAttributes.TRACELOOP_ENTITY_OUTPUT, json.dumps({output})
331
334
  )
332
- span.end()
333
- context.detach(token)
334
335
 
335
336
  @classmethod
336
337
  def set_session(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lmnr
3
- Version: 0.4.4
3
+ Version: 0.4.5
4
4
  Summary: Python SDK for Laminar AI
5
5
  License: Apache-2.0
6
6
  Author: lmnr.ai
@@ -89,6 +89,44 @@ def poem_writer(topic="turbulence"):
89
89
  print(poem_writer(topic="laminar flow"))
90
90
  ```
91
91
 
92
+ ### Manual instrumentation
93
+
94
+ Our manual instrumentation is a very thin wrapper around OpenTelemetry's
95
+ `trace.start_span`. Our wrapper sets the span into the active context.
96
+ You don't have to explicitly pass the spans around, it is enough to
97
+ just call `L.start_span`, and OpenTelemetry will handle the context management
98
+
99
+ ```python
100
+ from lmnr import observe, Laminar as L
101
+ L.initialize(project_api_key="<LMNR_PROJECT_API_KEY>")
102
+
103
+ def poem_writer(topic="turbulence"):
104
+
105
+ span = L.start_span("poem_writer", topic) # start a span
106
+
107
+ prompt = f"write a poem about {topic}"
108
+
109
+ # OpenAI calls are still automatically instrumented with OpenLLMetry
110
+ response = client.chat.completions.create(
111
+ model="gpt-4o",
112
+ messages=[
113
+ {"role": "system", "content": "You are a helpful assistant."},
114
+ {"role": "user", "content": prompt},
115
+ ],
116
+ )
117
+ poem = response.choices[0].message.content
118
+ # while within the span, you can attach laminar events to it
119
+ L.event("event_name", "event_value")
120
+
121
+ L.set_span_output(span, poem) # set an output
122
+
123
+ # IMPORTANT: don't forget to end all the spans (usually in `finally` blocks)
124
+ # Otherwise, the trace may not be sent/displayed correctly
125
+ span.end()
126
+
127
+ return poem
128
+ ```
129
+
92
130
 
93
131
  ## Sending events
94
132
 
@@ -2,12 +2,12 @@ lmnr/__init__.py,sha256=wQwnHl662Xcz7GdSofFsEjmAK0nxioYA2Yq6Q78m4ps,194
2
2
  lmnr/sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  lmnr/sdk/decorators.py,sha256=Xs6n0TGX9LZ9i1hE_UZz4LEyd_ZAfpVGfNQh_rKwOuA,2493
4
4
  lmnr/sdk/evaluations.py,sha256=Z0j2HyXgrwlGyiT_Ql7W3e_ZWjOlNlIj9RWAKjEgkkE,6366
5
- lmnr/sdk/laminar.py,sha256=DQ6EvuYK0elERNDcGyKyMmHrkEJZT66-vgBmCJ8fv4Q,17077
5
+ lmnr/sdk/laminar.py,sha256=LOttLBrQoAlduqLYL6sODYHzqRrt44mDNgnnE2it5CE,17114
6
6
  lmnr/sdk/log.py,sha256=EgAMY77Zn1bv1imCqrmflD3imoAJ2yveOkIcrIP3e98,1170
7
7
  lmnr/sdk/types.py,sha256=gDwRSWR9A1__FGtQhVaFc6PUYQuIhubo5tpfYAajTQQ,4055
8
8
  lmnr/sdk/utils.py,sha256=ZsGJ86tq8lIbvOhSb1gJWH5K3GylO_lgX68FN6rG2nM,3358
9
- lmnr-0.4.4.dist-info/LICENSE,sha256=67b_wJHVV1CBaWkrKFWU1wyqTPSdzH77Ls-59631COg,10411
10
- lmnr-0.4.4.dist-info/METADATA,sha256=gBmo93OeKl55jRIEJ4Fz8bvb1CTZzWVfCp3HQ8BAKHw,7025
11
- lmnr-0.4.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
12
- lmnr-0.4.4.dist-info/entry_points.txt,sha256=Qg7ZRax4k-rcQsZ26XRYQ8YFSBiyY2PNxYfq4a6PYXI,41
13
- lmnr-0.4.4.dist-info/RECORD,,
9
+ lmnr-0.4.5.dist-info/LICENSE,sha256=67b_wJHVV1CBaWkrKFWU1wyqTPSdzH77Ls-59631COg,10411
10
+ lmnr-0.4.5.dist-info/METADATA,sha256=tmHMhn3OT6gvymqbZk1aDp5_LH-dHiOMc2m_Lpt8ptU,8292
11
+ lmnr-0.4.5.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
12
+ lmnr-0.4.5.dist-info/entry_points.txt,sha256=Qg7ZRax4k-rcQsZ26XRYQ8YFSBiyY2PNxYfq4a6PYXI,41
13
+ lmnr-0.4.5.dist-info/RECORD,,
File without changes
File without changes