lmnr 0.6.2__py3-none-any.whl → 0.6.4__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/cli.py +18 -11
- lmnr/opentelemetry_lib/__init__.py +6 -7
- lmnr/opentelemetry_lib/decorators/__init__.py +23 -8
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/__init__.py +2 -2
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/config.py +4 -4
- lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/utils.py +19 -19
- lmnr/opentelemetry_lib/tracing/__init__.py +6 -7
- lmnr/opentelemetry_lib/tracing/_instrument_initializers.py +32 -33
- lmnr/opentelemetry_lib/tracing/context_properties.py +2 -3
- lmnr/opentelemetry_lib/tracing/exporter.py +4 -5
- lmnr/opentelemetry_lib/tracing/instruments.py +5 -6
- lmnr/opentelemetry_lib/tracing/processor.py +6 -7
- lmnr/sdk/browser/utils.py +4 -3
- lmnr/sdk/client/asynchronous/async_client.py +26 -11
- lmnr/sdk/client/asynchronous/resources/__init__.py +2 -0
- lmnr/sdk/client/asynchronous/resources/agent.py +89 -91
- lmnr/sdk/client/asynchronous/resources/evals.py +8 -8
- lmnr/sdk/client/asynchronous/resources/tags.py +89 -0
- lmnr/sdk/client/synchronous/resources/__init__.py +2 -1
- lmnr/sdk/client/synchronous/resources/agent.py +91 -91
- lmnr/sdk/client/synchronous/resources/evals.py +8 -8
- lmnr/sdk/client/synchronous/resources/tags.py +89 -0
- lmnr/sdk/client/synchronous/sync_client.py +28 -13
- lmnr/sdk/decorators.py +43 -27
- lmnr/sdk/eval_control.py +1 -1
- lmnr/sdk/evaluations.py +75 -52
- lmnr/sdk/laminar.py +76 -58
- lmnr/sdk/types.py +47 -37
- lmnr/sdk/utils.py +3 -3
- lmnr/version.py +1 -1
- {lmnr-0.6.2.dist-info → lmnr-0.6.4.dist-info}/METADATA +1 -1
- lmnr-0.6.4.dist-info/RECORD +56 -0
- lmnr-0.6.2.dist-info/RECORD +0 -54
- {lmnr-0.6.2.dist-info → lmnr-0.6.4.dist-info}/LICENSE +0 -0
- {lmnr-0.6.2.dist-info → lmnr-0.6.4.dist-info}/WHEEL +0 -0
- {lmnr-0.6.2.dist-info → lmnr-0.6.4.dist-info}/entry_points.txt +0 -0
lmnr/sdk/eval_control.py
CHANGED
lmnr/sdk/evaluations.py
CHANGED
@@ -3,7 +3,7 @@ import re
|
|
3
3
|
import uuid
|
4
4
|
|
5
5
|
from tqdm import tqdm
|
6
|
-
from typing import Any, Awaitable
|
6
|
+
from typing import Any, Awaitable
|
7
7
|
|
8
8
|
from lmnr.opentelemetry_lib.tracing.instruments import Instruments
|
9
9
|
from lmnr.opentelemetry_lib.tracing.attributes import SPAN_TYPE
|
@@ -11,7 +11,7 @@ from lmnr.opentelemetry_lib.tracing.attributes import SPAN_TYPE
|
|
11
11
|
from lmnr.sdk.client.asynchronous.async_client import AsyncLaminarClient
|
12
12
|
from lmnr.sdk.client.synchronous.sync_client import LaminarClient
|
13
13
|
from lmnr.sdk.datasets import EvaluationDataset, LaminarDataset
|
14
|
-
from lmnr.sdk.eval_control import
|
14
|
+
from lmnr.sdk.eval_control import EVALUATION_INSTANCES, PREPARE_ONLY
|
15
15
|
from lmnr.sdk.laminar import Laminar as L
|
16
16
|
from lmnr.sdk.log import get_default_logger
|
17
17
|
from lmnr.sdk.types import (
|
@@ -33,7 +33,7 @@ MAX_EXPORT_BATCH_SIZE = 64
|
|
33
33
|
|
34
34
|
|
35
35
|
def get_evaluation_url(
|
36
|
-
project_id: str, evaluation_id: str, base_url:
|
36
|
+
project_id: str, evaluation_id: str, base_url: str | None = None
|
37
37
|
):
|
38
38
|
if not base_url or base_url == "https://api.lmnr.ai":
|
39
39
|
base_url = "https://www.lmnr.ai"
|
@@ -95,32 +95,34 @@ class EvaluationReporter:
|
|
95
95
|
class Evaluation:
|
96
96
|
def __init__(
|
97
97
|
self,
|
98
|
-
data:
|
98
|
+
data: EvaluationDataset | list[Datapoint | dict],
|
99
99
|
executor: Any,
|
100
100
|
evaluators: dict[str, EvaluatorFunction],
|
101
101
|
human_evaluators: list[HumanEvaluator] = [],
|
102
|
-
name:
|
103
|
-
group_name:
|
102
|
+
name: str | None = None,
|
103
|
+
group_name: str | None = None,
|
104
104
|
concurrency_limit: int = DEFAULT_BATCH_SIZE,
|
105
|
-
project_api_key:
|
106
|
-
base_url:
|
107
|
-
http_port:
|
108
|
-
grpc_port:
|
109
|
-
instruments:
|
110
|
-
max_export_batch_size:
|
111
|
-
trace_export_timeout_seconds:
|
105
|
+
project_api_key: str | None = None,
|
106
|
+
base_url: str | None = None,
|
107
|
+
http_port: int | None = None,
|
108
|
+
grpc_port: int | None = None,
|
109
|
+
instruments: set[Instruments] | None = None,
|
110
|
+
max_export_batch_size: int | None = MAX_EXPORT_BATCH_SIZE,
|
111
|
+
trace_export_timeout_seconds: int | None = None,
|
112
112
|
):
|
113
113
|
"""
|
114
114
|
Initializes an instance of the Evaluation class.
|
115
115
|
|
116
116
|
Parameters:
|
117
|
-
data (
|
117
|
+
data (list[Datapoint|dict] | EvaluationDataset):\
|
118
118
|
List of data points to evaluate or an evaluation dataset.
|
119
|
-
|
120
|
-
|
119
|
+
`data` is the input to the executor function.
|
120
|
+
`target` is the input to the evaluator function.
|
121
|
+
`metadata` is optional metadata to associate with the\
|
122
|
+
datapoint.
|
121
123
|
executor (Callable[..., Any]): The executor function.\
|
122
|
-
|
123
|
-
|
124
|
+
Takes the data point + any additional arguments and returns\
|
125
|
+
the output to evaluate.
|
124
126
|
evaluators (dict[str, Callable[..., Any]]): Evaluator functions and\
|
125
127
|
names. Each evaluator function takes the output of the executor\
|
126
128
|
_and_ the target data, and returns a score. The score can be a\
|
@@ -132,30 +134,31 @@ class Evaluation:
|
|
132
134
|
[Beta] List of instances of HumanEvaluator. For now, human\
|
133
135
|
evaluator only holds the queue name.
|
134
136
|
Defaults to an empty list.
|
135
|
-
name (
|
137
|
+
name (str | None, optional): Optional name of the evaluation.\
|
136
138
|
Used to identify the evaluation in the group.\
|
137
139
|
If not provided, a random name will be generated.
|
138
140
|
Defaults to None.
|
139
|
-
group_name (
|
141
|
+
group_name (str | None, optional): an identifier to group\
|
140
142
|
evaluations. Only evaluations within the same group_name can be\
|
141
143
|
visually compared. If not provided, "default" is assigned.
|
142
144
|
Defaults to None
|
143
|
-
concurrency_limit (int, optional): The concurrency limit for
|
144
|
-
data points will be evaluated in parallel
|
145
|
+
concurrency_limit (int, optional): The concurrency limit for\
|
146
|
+
evaluation. This many data points will be evaluated in parallel\
|
147
|
+
with a pool of workers.
|
145
148
|
Defaults to DEFAULT_BATCH_SIZE.
|
146
|
-
project_api_key (
|
149
|
+
project_api_key (str | None, optional): The project API key.\
|
147
150
|
If not provided, LMNR_PROJECT_API_KEY environment variable is\
|
148
151
|
used.
|
149
152
|
Defaults to an empty string.
|
150
|
-
base_url (
|
153
|
+
base_url (str | None, optional): The base URL for Laminar API.\
|
151
154
|
Useful if self-hosted. Do NOT include the port, use `http_port`\
|
152
155
|
and `grpc_port` instead.
|
153
156
|
Defaults to "https://api.lmnr.ai".
|
154
|
-
http_port (
|
157
|
+
http_port (int | None, optional): The port for Laminar API\
|
155
158
|
HTTP service. Defaults to 443 if not specified.
|
156
|
-
grpc_port (
|
159
|
+
grpc_port (int | None, optional): The port for Laminar API\
|
157
160
|
gRPC service. Defaults to 8443 if not specified.
|
158
|
-
instruments (
|
161
|
+
instruments (set[Instruments] | None, optional): Set of modules\
|
159
162
|
to auto-instrument. If None, all available instruments will be\
|
160
163
|
used.
|
161
164
|
See https://docs.lmnr.ai/tracing/automatic-instrumentation
|
@@ -204,6 +207,18 @@ class Evaluation:
|
|
204
207
|
)
|
205
208
|
self.project_api_key = api_key
|
206
209
|
|
210
|
+
if L.is_initialized():
|
211
|
+
self.client = AsyncLaminarClient(
|
212
|
+
base_url=L.get_base_http_url(),
|
213
|
+
project_api_key=L.get_project_api_key(),
|
214
|
+
)
|
215
|
+
if project_api_key and project_api_key != L.get_project_api_key():
|
216
|
+
self._logger.warning(
|
217
|
+
"Project API key is different from the one used to initialize"
|
218
|
+
" Laminar. Ignoring the project API key passed to the evaluation."
|
219
|
+
)
|
220
|
+
return
|
221
|
+
|
207
222
|
self.client = AsyncLaminarClient(
|
208
223
|
base_url=self.base_http_url,
|
209
224
|
project_api_key=self.project_api_key,
|
@@ -312,6 +327,7 @@ class Evaluation:
|
|
312
327
|
index=index,
|
313
328
|
trace_id=trace_id,
|
314
329
|
executor_span_id=executor_span_id,
|
330
|
+
metadata=datapoint.metadata,
|
315
331
|
)
|
316
332
|
# First, create datapoint with trace_id so that we can show the dp in the UI
|
317
333
|
await self.client._evals.save_datapoints(
|
@@ -367,6 +383,7 @@ class Evaluation:
|
|
367
383
|
human_evaluators=self.human_evaluators,
|
368
384
|
executor_span_id=executor_span_id,
|
369
385
|
index=index,
|
386
|
+
metadata=datapoint.metadata,
|
370
387
|
)
|
371
388
|
|
372
389
|
# Create background upload task without awaiting it
|
@@ -379,21 +396,21 @@ class Evaluation:
|
|
379
396
|
|
380
397
|
|
381
398
|
def evaluate(
|
382
|
-
data:
|
399
|
+
data: EvaluationDataset | list[Datapoint | dict],
|
383
400
|
executor: ExecutorFunction,
|
384
401
|
evaluators: dict[str, EvaluatorFunction],
|
385
402
|
human_evaluators: list[HumanEvaluator] = [],
|
386
|
-
name:
|
387
|
-
group_name:
|
403
|
+
name: str | None = None,
|
404
|
+
group_name: str | None = None,
|
388
405
|
concurrency_limit: int = DEFAULT_BATCH_SIZE,
|
389
|
-
project_api_key:
|
390
|
-
base_url:
|
391
|
-
http_port:
|
392
|
-
grpc_port:
|
393
|
-
instruments:
|
394
|
-
max_export_batch_size:
|
395
|
-
trace_export_timeout_seconds:
|
396
|
-
) ->
|
406
|
+
project_api_key: str | None = None,
|
407
|
+
base_url: str | None = None,
|
408
|
+
http_port: int | None = None,
|
409
|
+
grpc_port: int | None = None,
|
410
|
+
instruments: set[Instruments] | None = None,
|
411
|
+
max_export_batch_size: int | None = MAX_EXPORT_BATCH_SIZE,
|
412
|
+
trace_export_timeout_seconds: int | None = None,
|
413
|
+
) -> Awaitable[None] | None:
|
397
414
|
"""
|
398
415
|
If added to the file which is called through `lmnr eval` command, then
|
399
416
|
registers the evaluation; otherwise, runs the evaluation.
|
@@ -404,7 +421,7 @@ def evaluate(
|
|
404
421
|
You must await the call to `evaluate`.
|
405
422
|
|
406
423
|
Parameters:
|
407
|
-
data (
|
424
|
+
data (list[EvaluationDatapoint|dict] | EvaluationDataset):\
|
408
425
|
List of data points to evaluate or an evaluation dataset.
|
409
426
|
`data` is the input to the executor function,
|
410
427
|
`target` is the input to the evaluator function.
|
@@ -423,33 +440,33 @@ def evaluate(
|
|
423
440
|
[Beta] List of instances of HumanEvaluator. For now, human\
|
424
441
|
evaluator only holds the queue name.
|
425
442
|
Defaults to an empty list.
|
426
|
-
name (
|
443
|
+
name (str | None, optional): Optional name of the evaluation.\
|
427
444
|
Used to identify the evaluation in the group. If not provided, a\
|
428
445
|
random name will be generated.
|
429
446
|
Defaults to None.
|
430
|
-
group_name (
|
447
|
+
group_name (str | None, optional): An identifier to group evaluations.\
|
431
448
|
Only evaluations within the same group_name can be visually compared.\
|
432
449
|
If not provided, set to "default".
|
433
450
|
Defaults to None
|
434
451
|
concurrency_limit (int, optional): The concurrency limit for evaluation.
|
435
452
|
Defaults to DEFAULT_BATCH_SIZE.
|
436
|
-
project_api_key (
|
453
|
+
project_api_key (str | None, optional): The project API key.
|
437
454
|
Defaults to None.
|
438
|
-
base_url (
|
455
|
+
base_url (str | None, optional): The base URL for Laminar API.\
|
439
456
|
Useful if self-hosted elsewhere. Do NOT include the\
|
440
457
|
port, use `http_port` and `grpc_port` instead.
|
441
458
|
Defaults to "https://api.lmnr.ai".
|
442
|
-
http_port (
|
459
|
+
http_port (int | None, optional): The port for Laminar API's HTTP\
|
443
460
|
service. 443 is used if not specified.
|
444
461
|
Defaults to None.
|
445
|
-
grpc_port (
|
462
|
+
grpc_port (int | None, optional): The port for Laminar API's gRPC\
|
446
463
|
service. 8443 is used if not specified.
|
447
464
|
Defaults to None.
|
448
|
-
instruments (
|
465
|
+
instruments (set[Instruments] | None, optional): Set of modules to\
|
449
466
|
auto-instrument. If None, all available instruments\
|
450
467
|
will be used.
|
451
468
|
Defaults to None.
|
452
|
-
trace_export_timeout_seconds (
|
469
|
+
trace_export_timeout_seconds (int | None, optional): The timeout for\
|
453
470
|
trace export on OpenTelemetry exporter. Defaults to None.
|
454
471
|
"""
|
455
472
|
evaluation = Evaluation(
|
@@ -470,10 +487,16 @@ def evaluate(
|
|
470
487
|
)
|
471
488
|
|
472
489
|
if PREPARE_ONLY.get():
|
473
|
-
|
490
|
+
existing_evaluations = EVALUATION_INSTANCES.get([])
|
491
|
+
new_evaluations = (existing_evaluations or []) + [evaluation]
|
492
|
+
EVALUATION_INSTANCES.set(new_evaluations)
|
493
|
+
return None
|
474
494
|
else:
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
495
|
+
try:
|
496
|
+
loop = asyncio.get_event_loop()
|
497
|
+
if loop.is_running():
|
498
|
+
return evaluation.run()
|
499
|
+
else:
|
500
|
+
return asyncio.run(evaluation.run())
|
501
|
+
except RuntimeError:
|
479
502
|
return asyncio.run(evaluation.run())
|
lmnr/sdk/laminar.py
CHANGED
@@ -12,10 +12,11 @@ from lmnr.opentelemetry_lib import MAX_MANUAL_SPAN_PAYLOAD_SIZE
|
|
12
12
|
from lmnr.opentelemetry_lib.decorators import json_dumps
|
13
13
|
from opentelemetry import context as context_api, trace
|
14
14
|
from opentelemetry.context import attach, detach
|
15
|
+
from opentelemetry.trace import INVALID_TRACE_ID
|
15
16
|
from opentelemetry.sdk.trace.id_generator import RandomIdGenerator
|
16
17
|
from opentelemetry.util.types import AttributeValue
|
17
18
|
|
18
|
-
from typing import Any, Literal
|
19
|
+
from typing import Any, Literal
|
19
20
|
|
20
21
|
import copy
|
21
22
|
import datetime
|
@@ -48,21 +49,22 @@ from .types import (
|
|
48
49
|
|
49
50
|
|
50
51
|
class Laminar:
|
51
|
-
__project_api_key:
|
52
|
+
__project_api_key: str | None = None
|
52
53
|
__initialized: bool = False
|
54
|
+
__base_http_url: str | None = None
|
53
55
|
|
54
56
|
@classmethod
|
55
57
|
def initialize(
|
56
58
|
cls,
|
57
|
-
project_api_key:
|
58
|
-
base_url:
|
59
|
-
http_port:
|
60
|
-
grpc_port:
|
61
|
-
instruments:
|
62
|
-
disabled_instruments:
|
59
|
+
project_api_key: str | None = None,
|
60
|
+
base_url: str | None = None,
|
61
|
+
http_port: int | None = None,
|
62
|
+
grpc_port: int | None = None,
|
63
|
+
instruments: set[Instruments] | None = None,
|
64
|
+
disabled_instruments: set[Instruments] | None = None,
|
63
65
|
disable_batch: bool = False,
|
64
|
-
max_export_batch_size:
|
65
|
-
export_timeout_seconds:
|
66
|
+
max_export_batch_size: int | None = None,
|
67
|
+
export_timeout_seconds: int | None = None,
|
66
68
|
set_global_tracer_provider: bool = True,
|
67
69
|
otel_logger_level: int = logging.ERROR,
|
68
70
|
):
|
@@ -71,31 +73,31 @@ class Laminar:
|
|
71
73
|
decorators.
|
72
74
|
|
73
75
|
Args:
|
74
|
-
project_api_key (
|
76
|
+
project_api_key (str | None, optional): Laminar project api key.\
|
75
77
|
You can generate one by going to the projects\
|
76
78
|
settings page on the Laminar dashboard.\
|
77
79
|
If not specified, it will try to read from the\
|
78
80
|
LMNR_PROJECT_API_KEY environment variable\
|
79
81
|
in os.environ or in .env file.
|
80
82
|
Defaults to None.
|
81
|
-
base_url (
|
83
|
+
base_url (str | None, optional): Laminar API url. Do NOT include\
|
82
84
|
the port number, use `http_port` and `grpc_port`.\
|
83
85
|
If not specified, defaults to https://api.lmnr.ai.
|
84
|
-
http_port (
|
86
|
+
http_port (int | None, optional): Laminar API http port.\
|
85
87
|
If not specified, defaults to 443.
|
86
|
-
grpc_port (
|
88
|
+
grpc_port (int | None, optional): Laminar API grpc port.\
|
87
89
|
If not specified, defaults to 8443.
|
88
|
-
instruments (
|
90
|
+
instruments (set[Instruments] | None, optional): Instruments to\
|
89
91
|
enable. Defaults to all instruments. You can pass\
|
90
92
|
an empty set to disable all instruments. Read more:\
|
91
93
|
https://docs.lmnr.ai/tracing/automatic-instrumentation
|
92
|
-
disabled_instruments (
|
94
|
+
disabled_instruments (set[Instruments] | None, optional): Instruments to\
|
93
95
|
disable. Defaults to None.
|
94
96
|
disable_batch (bool, optional): If set to True, spans will be sent\
|
95
97
|
immediately to the backend. Useful for debugging, but\
|
96
98
|
may cause performance overhead in production.
|
97
99
|
Defaults to False.
|
98
|
-
export_timeout_seconds (
|
100
|
+
export_timeout_seconds (int | None, optional): Timeout for the OTLP\
|
99
101
|
exporter. Defaults to 30 seconds (unlike the\
|
100
102
|
OpenTelemetry default of 10 seconds).
|
101
103
|
Defaults to None.
|
@@ -133,6 +135,7 @@ class Laminar:
|
|
133
135
|
cls.__logger.info(f"Using HTTP port passed as an argument: {http_port}")
|
134
136
|
|
135
137
|
cls.__initialized = True
|
138
|
+
cls.__base_http_url = f"{url}:{http_port or 443}"
|
136
139
|
|
137
140
|
if not os.getenv("OTEL_ATTRIBUTE_COUNT_LIMIT"):
|
138
141
|
# each message is at least 2 attributes: role and content,
|
@@ -174,8 +177,8 @@ class Laminar:
|
|
174
177
|
def event(
|
175
178
|
cls,
|
176
179
|
name: str,
|
177
|
-
value:
|
178
|
-
timestamp:
|
180
|
+
value: AttributeValue | None = None,
|
181
|
+
timestamp: datetime.datetime | int | None = None,
|
179
182
|
):
|
180
183
|
"""Associate an event with the current span. If using manual\
|
181
184
|
instrumentation, use raw OpenTelemetry `span.add_event()` instead.\
|
@@ -183,14 +186,13 @@ class Laminar:
|
|
183
186
|
|
184
187
|
Args:
|
185
188
|
name (str): event name
|
186
|
-
value (
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
timestamp (
|
191
|
-
|
192
|
-
|
193
|
-
implementation. Defaults to None.
|
189
|
+
value (AttributeValue | None, optional): event value. Must be a\
|
190
|
+
primitive type. Boolean `True` is assumed in the backend if\
|
191
|
+
`value` is None.
|
192
|
+
Defaults to None.
|
193
|
+
timestamp (datetime.datetime | int | None, optional): If int, must\
|
194
|
+
be epoch nanoseconds. If not specified, relies on the underlying\
|
195
|
+
OpenTelemetry implementation. Defaults to None.
|
194
196
|
"""
|
195
197
|
if timestamp and isinstance(timestamp, datetime.datetime):
|
196
198
|
timestamp = int(timestamp.timestamp() * 1e9)
|
@@ -218,12 +220,10 @@ class Laminar:
|
|
218
220
|
cls,
|
219
221
|
name: str,
|
220
222
|
input: Any = None,
|
221
|
-
span_type:
|
222
|
-
|
223
|
-
] =
|
224
|
-
|
225
|
-
labels: Optional[list[str]] = None,
|
226
|
-
parent_span_context: Optional[LaminarSpanContext] = None,
|
223
|
+
span_type: Literal["DEFAULT", "LLM", "TOOL"] = "DEFAULT",
|
224
|
+
context: Context | None = None,
|
225
|
+
labels: list[str] | None = None,
|
226
|
+
parent_span_context: LaminarSpanContext | None = None,
|
227
227
|
):
|
228
228
|
"""Start a new span as the current span. Useful for manual
|
229
229
|
instrumentation. If `span_type` is set to `"LLM"`, you should report
|
@@ -241,12 +241,12 @@ class Laminar:
|
|
241
241
|
name (str): name of the span
|
242
242
|
input (Any, optional): input to the span. Will be sent as an\
|
243
243
|
attribute, so must be json serializable. Defaults to None.
|
244
|
-
span_type (
|
244
|
+
span_type (Literal["DEFAULT", "LLM", "TOOL"], optional):\
|
245
245
|
type of the span. If you use `"LLM"`, you should report usage\
|
246
246
|
and response attributes manually. Defaults to "DEFAULT".
|
247
|
-
context (
|
247
|
+
context (Context | None, optional): raw OpenTelemetry context\
|
248
248
|
to attach the span to. Defaults to None.
|
249
|
-
parent_span_context (
|
249
|
+
parent_span_context (LaminarSpanContext | None, optional): parent\
|
250
250
|
span context to use for the span. Useful for continuing traces\
|
251
251
|
across services. If parent_span_context is a\
|
252
252
|
raw OpenTelemetry span context, or if it is a dictionary or string\
|
@@ -256,7 +256,7 @@ class Laminar:
|
|
256
256
|
`Laminar.get_span_context`, `Laminar.get_span_context_dict` and\
|
257
257
|
`Laminar.get_span_context_str` for more information.
|
258
258
|
Defaults to None.
|
259
|
-
labels (
|
259
|
+
labels (list[str] | None, optional): labels to set for the\
|
260
260
|
span. Defaults to None.
|
261
261
|
"""
|
262
262
|
|
@@ -319,7 +319,7 @@ class Laminar:
|
|
319
319
|
|
320
320
|
@classmethod
|
321
321
|
@contextmanager
|
322
|
-
def with_labels(cls, labels: list[str], context:
|
322
|
+
def with_labels(cls, labels: list[str], context: Context | None = None):
|
323
323
|
"""Set labels for spans within this `with` context. This is useful for
|
324
324
|
adding labels to the spans created in the auto-instrumentations.
|
325
325
|
|
@@ -361,12 +361,10 @@ class Laminar:
|
|
361
361
|
cls,
|
362
362
|
name: str,
|
363
363
|
input: Any = None,
|
364
|
-
span_type:
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
parent_span_context: Optional[LaminarSpanContext] = None,
|
369
|
-
labels: Optional[dict[str, str]] = None,
|
364
|
+
span_type: Literal["DEFAULT", "LLM", "TOOL"] = "DEFAULT",
|
365
|
+
context: Context | None = None,
|
366
|
+
parent_span_context: LaminarSpanContext | None = None,
|
367
|
+
labels: dict[str, str] | None = None,
|
370
368
|
):
|
371
369
|
"""Start a new span. Useful for manual instrumentation.
|
372
370
|
If `span_type` is set to `"LLM"`, you should report usage and response
|
@@ -403,12 +401,12 @@ class Laminar:
|
|
403
401
|
name (str): name of the span
|
404
402
|
input (Any, optional): input to the span. Will be sent as an\
|
405
403
|
attribute, so must be json serializable. Defaults to None.
|
406
|
-
span_type (
|
404
|
+
span_type (Literal["DEFAULT", "LLM", "TOOL"], optional):\
|
407
405
|
type of the span. If you use `"LLM"`, you should report usage\
|
408
406
|
and response attributes manually. Defaults to "DEFAULT".
|
409
|
-
context (
|
407
|
+
context (Context | None, optional): raw OpenTelemetry context\
|
410
408
|
to attach the span to. Defaults to None.
|
411
|
-
parent_span_context (
|
409
|
+
parent_span_context (LaminarSpanContext | None, optional): parent\
|
412
410
|
span context to use for the span. Useful for continuing traces\
|
413
411
|
across services. If parent_span_context is a\
|
414
412
|
raw OpenTelemetry span context, or if it is a dictionary or string\
|
@@ -418,7 +416,7 @@ class Laminar:
|
|
418
416
|
`Laminar.get_span_context`, `Laminar.get_span_context_dict` and\
|
419
417
|
`Laminar.get_span_context_str` for more information.
|
420
418
|
Defaults to None.
|
421
|
-
labels (
|
419
|
+
labels (dict[str, str] | None, optional): labels to set for the\
|
422
420
|
span. Defaults to None.
|
423
421
|
"""
|
424
422
|
if not cls.is_initialized():
|
@@ -572,8 +570,8 @@ class Laminar:
|
|
572
570
|
|
573
571
|
@classmethod
|
574
572
|
def get_laminar_span_context(
|
575
|
-
cls, span:
|
576
|
-
) ->
|
573
|
+
cls, span: trace.Span | None = None
|
574
|
+
) -> LaminarSpanContext | None:
|
577
575
|
"""Get the laminar span context for a given span.
|
578
576
|
If no span is provided, the current active span will be used.
|
579
577
|
"""
|
@@ -588,15 +586,15 @@ class Laminar:
|
|
588
586
|
|
589
587
|
@classmethod
|
590
588
|
def get_laminar_span_context_dict(
|
591
|
-
cls, span:
|
592
|
-
) ->
|
589
|
+
cls, span: trace.Span | None = None
|
590
|
+
) -> dict | None:
|
593
591
|
span_context = cls.get_laminar_span_context(span)
|
594
592
|
if span_context is None:
|
595
593
|
return None
|
596
594
|
return span_context.model_dump()
|
597
595
|
|
598
596
|
@classmethod
|
599
|
-
def serialize_span_context(cls, span:
|
597
|
+
def serialize_span_context(cls, span: trace.Span | None = None) -> str | None:
|
600
598
|
"""Get the laminar span context for a given span as a string.
|
601
599
|
If no span is provided, the current active span will be used.
|
602
600
|
|
@@ -630,9 +628,7 @@ class Laminar:
|
|
630
628
|
return str(span_context)
|
631
629
|
|
632
630
|
@classmethod
|
633
|
-
def deserialize_span_context(
|
634
|
-
cls, span_context: Union[dict, str]
|
635
|
-
) -> LaminarSpanContext:
|
631
|
+
def deserialize_span_context(cls, span_context: dict | str) -> LaminarSpanContext:
|
636
632
|
return LaminarSpanContext.deserialize(span_context)
|
637
633
|
|
638
634
|
@classmethod
|
@@ -655,14 +651,14 @@ class Laminar:
|
|
655
651
|
@classmethod
|
656
652
|
def set_session(
|
657
653
|
cls,
|
658
|
-
session_id:
|
654
|
+
session_id: str | None = None,
|
659
655
|
):
|
660
656
|
"""Set the session and user id for the current span and the context
|
661
657
|
(i.e. any children spans created from the current span in the current
|
662
658
|
thread).
|
663
659
|
|
664
660
|
Args:
|
665
|
-
session_id (
|
661
|
+
session_id (str | None, optional): Custom session id.\
|
666
662
|
Useful to debug and group long-running\
|
667
663
|
sessions/conversations.
|
668
664
|
Defaults to None.
|
@@ -700,6 +696,28 @@ class Laminar:
|
|
700
696
|
props.pop("user_id", None)
|
701
697
|
set_association_properties(props)
|
702
698
|
|
699
|
+
@classmethod
|
700
|
+
def get_base_http_url(cls):
|
701
|
+
return cls.__base_http_url
|
702
|
+
|
703
|
+
@classmethod
|
704
|
+
def get_project_api_key(cls):
|
705
|
+
return cls.__project_api_key
|
706
|
+
|
707
|
+
@classmethod
|
708
|
+
def get_trace_id(cls) -> uuid.UUID | None:
|
709
|
+
"""Get the trace id for the current active span represented as a UUID.
|
710
|
+
Returns None if there is no active span.
|
711
|
+
|
712
|
+
Returns:
|
713
|
+
uuid.UUID | None: The trace id for the current span, or None if\
|
714
|
+
there is no active span.
|
715
|
+
"""
|
716
|
+
trace_id = trace.get_current_span().get_span_context().trace_id
|
717
|
+
if trace_id == INVALID_TRACE_ID:
|
718
|
+
return None
|
719
|
+
return uuid.UUID(int=trace_id)
|
720
|
+
|
703
721
|
@classmethod
|
704
722
|
def _headers(cls):
|
705
723
|
assert cls.__project_api_key is not None, "Project API key is not set"
|