lmnr 0.4.8__py3-none-any.whl → 0.4.10__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/decorators.py +3 -3
- lmnr/sdk/laminar.py +12 -58
- lmnr/sdk/types.py +1 -1
- lmnr/traceloop_sdk/__init__.py +7 -17
- lmnr/traceloop_sdk/decorators/__init__.py +0 -131
- lmnr/traceloop_sdk/decorators/base.py +6 -98
- lmnr/traceloop_sdk/tests/__init__.py +1 -1
- lmnr/traceloop_sdk/tests/conftest.py +83 -83
- lmnr/traceloop_sdk/tests/test_association_properties.py +229 -229
- lmnr/traceloop_sdk/tests/test_manual.py +41 -41
- lmnr/traceloop_sdk/tests/test_nested_tasks.py +47 -47
- lmnr/traceloop_sdk/tests/test_privacy_no_prompts.py +50 -50
- lmnr/traceloop_sdk/tests/test_sdk_initialization.py +40 -40
- lmnr/traceloop_sdk/tests/test_tasks.py +24 -24
- lmnr/traceloop_sdk/tests/test_workflows.py +262 -261
- lmnr/traceloop_sdk/tracing/__init__.py +0 -1
- lmnr/traceloop_sdk/tracing/tracing.py +19 -30
- {lmnr-0.4.8.dist-info → lmnr-0.4.10.dist-info}/METADATA +44 -49
- {lmnr-0.4.8.dist-info → lmnr-0.4.10.dist-info}/RECORD +23 -24
- lmnr/traceloop_sdk/README.md +0 -16
- {lmnr-0.4.8.dist-info → lmnr-0.4.10.dist-info}/LICENSE +0 -0
- {lmnr-0.4.8.dist-info → lmnr-0.4.10.dist-info}/WHEEL +0 -0
- {lmnr-0.4.8.dist-info → lmnr-0.4.10.dist-info}/entry_points.txt +0 -0
lmnr/__init__.py
CHANGED
lmnr/sdk/decorators.py
CHANGED
@@ -3,11 +3,11 @@ from lmnr.traceloop_sdk.decorators.base import (
|
|
3
3
|
aentity_method,
|
4
4
|
)
|
5
5
|
from opentelemetry.trace import INVALID_SPAN, get_current_span
|
6
|
-
from lmnr.traceloop_sdk import Traceloop
|
7
6
|
|
8
7
|
from typing import Callable, Optional, ParamSpec, TypeVar, cast
|
9
8
|
|
10
|
-
from .
|
9
|
+
from lmnr.traceloop_sdk.tracing.tracing import update_association_properties
|
10
|
+
|
11
11
|
from .utils import is_async
|
12
12
|
|
13
13
|
P = ParamSpec("P")
|
@@ -57,7 +57,7 @@ def observe(
|
|
57
57
|
association_properties["session_id"] = session_id
|
58
58
|
if user_id is not None:
|
59
59
|
association_properties["user_id"] = user_id
|
60
|
-
|
60
|
+
update_association_properties(association_properties)
|
61
61
|
return (
|
62
62
|
aentity_method(name=name)(func)
|
63
63
|
if is_async(func)
|
lmnr/sdk/laminar.py
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
+
from lmnr.traceloop_sdk.instruments import Instruments
|
1
2
|
from opentelemetry import context
|
2
3
|
from opentelemetry.trace import (
|
3
4
|
INVALID_SPAN,
|
4
5
|
get_current_span,
|
5
|
-
set_span_in_context,
|
6
|
-
Span,
|
7
6
|
SpanKind,
|
8
7
|
)
|
9
8
|
from opentelemetry.semconv_ai import SpanAttributes
|
@@ -16,7 +15,7 @@ from contextlib import contextmanager
|
|
16
15
|
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
|
17
16
|
|
18
17
|
from pydantic.alias_generators import to_snake
|
19
|
-
from typing import Any, Optional, Union
|
18
|
+
from typing import Any, Optional, Set, Union
|
20
19
|
|
21
20
|
import copy
|
22
21
|
import datetime
|
@@ -27,6 +26,8 @@ import os
|
|
27
26
|
import requests
|
28
27
|
import uuid
|
29
28
|
|
29
|
+
from lmnr.traceloop_sdk.tracing.tracing import set_association_properties, update_association_properties
|
30
|
+
|
30
31
|
from .log import VerboseColorfulFormatter
|
31
32
|
|
32
33
|
from .types import (
|
@@ -51,6 +52,7 @@ class Laminar:
|
|
51
52
|
project_api_key: Optional[str] = None,
|
52
53
|
env: dict[str, str] = {},
|
53
54
|
base_url: Optional[str] = None,
|
55
|
+
instruments: Optional[Set[Instruments]] = None,
|
54
56
|
):
|
55
57
|
"""Initialize Laminar context across the application.
|
56
58
|
This method must be called before using any other Laminar methods or
|
@@ -104,6 +106,7 @@ class Laminar:
|
|
104
106
|
endpoint=cls.__base_url,
|
105
107
|
headers={"authorization": f"Bearer {cls.__project_api_key}"},
|
106
108
|
),
|
109
|
+
instruments=instruments,
|
107
110
|
)
|
108
111
|
|
109
112
|
@classmethod
|
@@ -354,50 +357,15 @@ class Laminar:
|
|
354
357
|
yield span
|
355
358
|
|
356
359
|
@classmethod
|
357
|
-
def
|
358
|
-
|
359
|
-
name: str,
|
360
|
-
input: Any = None,
|
361
|
-
) -> Span:
|
362
|
-
"""Start a new span with the given name. Useful for manual
|
363
|
-
instrumentation.
|
364
|
-
|
365
|
-
Args:
|
366
|
-
name (str): name of the span
|
367
|
-
input (Any, optional): input to the span. Will be sent as an
|
368
|
-
attribute, so must be json serializable. Defaults to None.
|
369
|
-
|
370
|
-
Returns:
|
371
|
-
Tuple[Span, object]: Span - the started span, object -
|
372
|
-
context token
|
373
|
-
that must be passed to `end_span` to end the span.
|
374
|
-
|
375
|
-
"""
|
376
|
-
tracer = get_tracer().__enter__()
|
377
|
-
span = tracer.start_span(name)
|
378
|
-
# apparently, detaching from this context is not mandatory.
|
379
|
-
# According to traceloop, and the github issue in opentelemetry,
|
380
|
-
# the context is collected by the garbage collector.
|
381
|
-
# https://github.com/open-telemetry/opentelemetry-python/issues/2606#issuecomment-2106320379
|
382
|
-
context.attach(set_span_in_context(span))
|
383
|
-
|
384
|
-
if input is not None:
|
385
|
-
span.set_attribute(
|
386
|
-
SpanAttributes.TRACELOOP_ENTITY_INPUT, json.dumps({"input": input})
|
387
|
-
)
|
388
|
-
|
389
|
-
return span
|
390
|
-
|
391
|
-
@classmethod
|
392
|
-
def set_span_output(cls, span: Span, output: Any = None):
|
393
|
-
"""Set the output of the span. Useful for manual instrumentation.
|
360
|
+
def set_span_output(cls, output: Any = None):
|
361
|
+
"""Set the output of the current span. Useful for manual instrumentation.
|
394
362
|
|
395
363
|
Args:
|
396
|
-
span (Span): the span to set the output for
|
397
364
|
output (Any, optional): output of the span. Will be sent as an
|
398
365
|
attribute, so must be json serializable. Defaults to None.
|
399
366
|
"""
|
400
|
-
|
367
|
+
span = get_current_span()
|
368
|
+
if output is not None and span != INVALID_SPAN:
|
401
369
|
span.set_attribute(
|
402
370
|
SpanAttributes.TRACELOOP_ENTITY_OUTPUT, json.dumps(output)
|
403
371
|
)
|
@@ -421,26 +389,12 @@ class Laminar:
|
|
421
389
|
Useful for grouping spans or traces by user.
|
422
390
|
Defaults to None.
|
423
391
|
"""
|
424
|
-
current_span = get_current_span()
|
425
|
-
if current_span != INVALID_SPAN:
|
426
|
-
cls.__logger.debug(
|
427
|
-
"Laminar().set_session() called inside a span context. Setting"
|
428
|
-
" it manually in the current span."
|
429
|
-
)
|
430
|
-
if session_id is not None:
|
431
|
-
current_span.set_attribute(
|
432
|
-
"traceloop.association.properties.session_id", session_id
|
433
|
-
)
|
434
|
-
if user_id is not None:
|
435
|
-
current_span.set_attribute(
|
436
|
-
"traceloop.association.properties.user_id", user_id
|
437
|
-
)
|
438
392
|
association_properties = {}
|
439
393
|
if session_id is not None:
|
440
394
|
association_properties["session_id"] = session_id
|
441
395
|
if user_id is not None:
|
442
396
|
association_properties["user_id"] = user_id
|
443
|
-
|
397
|
+
update_association_properties(association_properties)
|
444
398
|
|
445
399
|
@classmethod
|
446
400
|
def clear_session(cls):
|
@@ -448,7 +402,7 @@ class Laminar:
|
|
448
402
|
props: dict = copy.copy(context.get_value("association_properties"))
|
449
403
|
props.pop("session_id", None)
|
450
404
|
props.pop("user_id", None)
|
451
|
-
|
405
|
+
set_association_properties(props)
|
452
406
|
|
453
407
|
@classmethod
|
454
408
|
def create_evaluation(cls, name: str) -> CreateEvaluationResponse:
|
lmnr/sdk/types.py
CHANGED
lmnr/traceloop_sdk/__init__.py
CHANGED
@@ -18,11 +18,7 @@ from lmnr.traceloop_sdk.config import (
|
|
18
18
|
is_tracing_enabled,
|
19
19
|
is_metrics_enabled,
|
20
20
|
)
|
21
|
-
from lmnr.traceloop_sdk.tracing.tracing import
|
22
|
-
TracerWrapper,
|
23
|
-
set_association_properties,
|
24
|
-
set_external_prompt_tracing_context,
|
25
|
-
)
|
21
|
+
from lmnr.traceloop_sdk.tracing.tracing import TracerWrapper
|
26
22
|
from typing import Dict
|
27
23
|
|
28
24
|
|
@@ -38,14 +34,14 @@ class Traceloop:
|
|
38
34
|
def init(
|
39
35
|
app_name: Optional[str] = sys.argv[0],
|
40
36
|
api_endpoint: str = "https://api.lmnr.ai",
|
41
|
-
api_key: str = None,
|
37
|
+
api_key: Optional[str] = None,
|
42
38
|
headers: Dict[str, str] = {},
|
43
39
|
disable_batch=False,
|
44
|
-
exporter: SpanExporter = None,
|
45
|
-
metrics_exporter: MetricExporter = None,
|
46
|
-
metrics_headers: Dict[str, str] = None,
|
47
|
-
processor: SpanProcessor = None,
|
48
|
-
propagator: TextMapPropagator = None,
|
40
|
+
exporter: Optional[SpanExporter] = None,
|
41
|
+
metrics_exporter: Optional[MetricExporter] = None,
|
42
|
+
metrics_headers: Optional[Dict[str, str]] = None,
|
43
|
+
processor: Optional[SpanProcessor] = None,
|
44
|
+
propagator: Optional[TextMapPropagator] = None,
|
49
45
|
should_enrich_metrics: bool = True,
|
50
46
|
resource_attributes: dict = {},
|
51
47
|
instruments: Optional[Set[Instruments]] = None,
|
@@ -130,9 +126,3 @@ class Traceloop:
|
|
130
126
|
)
|
131
127
|
|
132
128
|
Traceloop.__metrics_wrapper = MetricsWrapper(exporter=metrics_exporter)
|
133
|
-
|
134
|
-
def set_association_properties(properties: dict) -> None:
|
135
|
-
set_association_properties(properties)
|
136
|
-
|
137
|
-
def set_prompt(template: str, variables: dict, version: int):
|
138
|
-
set_external_prompt_tracing_context(template, variables, version)
|
@@ -1,131 +0,0 @@
|
|
1
|
-
from typing import Optional
|
2
|
-
|
3
|
-
from opentelemetry.semconv_ai import TraceloopSpanKindValues
|
4
|
-
|
5
|
-
from lmnr.traceloop_sdk.decorators.base import (
|
6
|
-
aentity_class,
|
7
|
-
aentity_method,
|
8
|
-
entity_class,
|
9
|
-
entity_method,
|
10
|
-
)
|
11
|
-
|
12
|
-
|
13
|
-
def task(
|
14
|
-
name: Optional[str] = None,
|
15
|
-
version: Optional[int] = None,
|
16
|
-
method_name: Optional[str] = None,
|
17
|
-
tlp_span_kind: Optional[TraceloopSpanKindValues] = TraceloopSpanKindValues.TASK,
|
18
|
-
):
|
19
|
-
if method_name is None:
|
20
|
-
return entity_method(name=name, version=version, tlp_span_kind=tlp_span_kind)
|
21
|
-
else:
|
22
|
-
return entity_class(
|
23
|
-
name=name,
|
24
|
-
version=version,
|
25
|
-
method_name=method_name,
|
26
|
-
tlp_span_kind=tlp_span_kind,
|
27
|
-
)
|
28
|
-
|
29
|
-
|
30
|
-
def workflow(
|
31
|
-
name: Optional[str] = None,
|
32
|
-
version: Optional[int] = None,
|
33
|
-
method_name: Optional[str] = None,
|
34
|
-
tlp_span_kind: Optional[TraceloopSpanKindValues] = TraceloopSpanKindValues.WORKFLOW,
|
35
|
-
):
|
36
|
-
if method_name is None:
|
37
|
-
return entity_method(name=name, version=version, tlp_span_kind=tlp_span_kind)
|
38
|
-
else:
|
39
|
-
return entity_class(
|
40
|
-
name=name,
|
41
|
-
version=version,
|
42
|
-
method_name=method_name,
|
43
|
-
tlp_span_kind=tlp_span_kind,
|
44
|
-
)
|
45
|
-
|
46
|
-
|
47
|
-
def agent(
|
48
|
-
name: Optional[str] = None,
|
49
|
-
version: Optional[int] = None,
|
50
|
-
method_name: Optional[str] = None,
|
51
|
-
):
|
52
|
-
return workflow(
|
53
|
-
name=name,
|
54
|
-
version=version,
|
55
|
-
method_name=method_name,
|
56
|
-
tlp_span_kind=TraceloopSpanKindValues.AGENT,
|
57
|
-
)
|
58
|
-
|
59
|
-
|
60
|
-
def tool(
|
61
|
-
name: Optional[str] = None,
|
62
|
-
version: Optional[int] = None,
|
63
|
-
method_name: Optional[str] = None,
|
64
|
-
):
|
65
|
-
return task(
|
66
|
-
name=name,
|
67
|
-
version=version,
|
68
|
-
method_name=method_name,
|
69
|
-
tlp_span_kind=TraceloopSpanKindValues.TOOL,
|
70
|
-
)
|
71
|
-
|
72
|
-
|
73
|
-
# Async Decorators
|
74
|
-
def atask(
|
75
|
-
name: Optional[str] = None,
|
76
|
-
version: Optional[int] = None,
|
77
|
-
method_name: Optional[str] = None,
|
78
|
-
tlp_span_kind: Optional[TraceloopSpanKindValues] = TraceloopSpanKindValues.TASK,
|
79
|
-
):
|
80
|
-
if method_name is None:
|
81
|
-
return aentity_method(name=name, version=version, tlp_span_kind=tlp_span_kind)
|
82
|
-
else:
|
83
|
-
return aentity_class(
|
84
|
-
name=name,
|
85
|
-
version=version,
|
86
|
-
method_name=method_name,
|
87
|
-
tlp_span_kind=tlp_span_kind,
|
88
|
-
)
|
89
|
-
|
90
|
-
|
91
|
-
def aworkflow(
|
92
|
-
name: Optional[str] = None,
|
93
|
-
version: Optional[int] = None,
|
94
|
-
method_name: Optional[str] = None,
|
95
|
-
tlp_span_kind: Optional[TraceloopSpanKindValues] = TraceloopSpanKindValues.WORKFLOW,
|
96
|
-
):
|
97
|
-
if method_name is None:
|
98
|
-
return aentity_method(name=name, version=version, tlp_span_kind=tlp_span_kind)
|
99
|
-
else:
|
100
|
-
return aentity_class(
|
101
|
-
name=name,
|
102
|
-
version=version,
|
103
|
-
method_name=method_name,
|
104
|
-
tlp_span_kind=tlp_span_kind,
|
105
|
-
)
|
106
|
-
|
107
|
-
|
108
|
-
def aagent(
|
109
|
-
name: Optional[str] = None,
|
110
|
-
version: Optional[int] = None,
|
111
|
-
method_name: Optional[str] = None,
|
112
|
-
):
|
113
|
-
return atask(
|
114
|
-
name=name,
|
115
|
-
version=version,
|
116
|
-
method_name=method_name,
|
117
|
-
tlp_span_kind=TraceloopSpanKindValues.AGENT,
|
118
|
-
)
|
119
|
-
|
120
|
-
|
121
|
-
def atool(
|
122
|
-
name: Optional[str] = None,
|
123
|
-
version: Optional[int] = None,
|
124
|
-
method_name: Optional[str] = None,
|
125
|
-
):
|
126
|
-
return atask(
|
127
|
-
name=name,
|
128
|
-
version=version,
|
129
|
-
method_name=method_name,
|
130
|
-
tlp_span_kind=TraceloopSpanKindValues.TOOL,
|
131
|
-
)
|
@@ -7,15 +7,10 @@ import warnings
|
|
7
7
|
|
8
8
|
from opentelemetry import trace
|
9
9
|
from opentelemetry import context as context_api
|
10
|
-
from opentelemetry.semconv_ai import SpanAttributes
|
11
|
-
|
12
|
-
from lmnr.traceloop_sdk.tracing import get_tracer
|
13
|
-
from lmnr.traceloop_sdk.tracing.tracing import
|
14
|
-
TracerWrapper,
|
15
|
-
set_entity_path,
|
16
|
-
get_chained_entity_path,
|
17
|
-
)
|
18
|
-
from lmnr.traceloop_sdk.utils import camel_to_snake
|
10
|
+
from opentelemetry.semconv_ai import SpanAttributes
|
11
|
+
|
12
|
+
from lmnr.traceloop_sdk.tracing import get_tracer
|
13
|
+
from lmnr.traceloop_sdk.tracing.tracing import TracerWrapper
|
19
14
|
from lmnr.traceloop_sdk.utils.json_encoder import JSONEncoder
|
20
15
|
|
21
16
|
|
@@ -40,8 +35,6 @@ def _json_dumps(data: dict) -> str:
|
|
40
35
|
|
41
36
|
def entity_method(
|
42
37
|
name: Optional[str] = None,
|
43
|
-
version: Optional[int] = None,
|
44
|
-
tlp_span_kind: Optional[TraceloopSpanKindValues] = TraceloopSpanKindValues.TASK,
|
45
38
|
):
|
46
39
|
def decorate(fn):
|
47
40
|
@wraps(fn)
|
@@ -49,33 +42,13 @@ def entity_method(
|
|
49
42
|
if not TracerWrapper.verify_initialized():
|
50
43
|
return fn(*args, **kwargs)
|
51
44
|
|
52
|
-
|
53
|
-
if tlp_span_kind in [
|
54
|
-
TraceloopSpanKindValues.WORKFLOW,
|
55
|
-
TraceloopSpanKindValues.AGENT,
|
56
|
-
]:
|
57
|
-
set_workflow_name(entity_name)
|
58
|
-
span_name = f"{entity_name}.{tlp_span_kind.value}"
|
45
|
+
span_name = name or fn.__name__
|
59
46
|
|
60
47
|
with get_tracer() as tracer:
|
61
48
|
span = tracer.start_span(span_name)
|
62
49
|
ctx = trace.set_span_in_context(span)
|
63
50
|
ctx_token = context_api.attach(ctx)
|
64
51
|
|
65
|
-
if tlp_span_kind in [
|
66
|
-
TraceloopSpanKindValues.TASK,
|
67
|
-
TraceloopSpanKindValues.TOOL,
|
68
|
-
]:
|
69
|
-
entity_path = get_chained_entity_path(entity_name)
|
70
|
-
set_entity_path(entity_path)
|
71
|
-
|
72
|
-
span.set_attribute(
|
73
|
-
SpanAttributes.TRACELOOP_SPAN_KIND, tlp_span_kind.value
|
74
|
-
)
|
75
|
-
span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_NAME, entity_name)
|
76
|
-
if version:
|
77
|
-
span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_VERSION, version)
|
78
|
-
|
79
52
|
try:
|
80
53
|
if _should_send_prompts():
|
81
54
|
span.set_attribute(
|
@@ -110,69 +83,25 @@ def entity_method(
|
|
110
83
|
return decorate
|
111
84
|
|
112
85
|
|
113
|
-
def entity_class(
|
114
|
-
name: Optional[str],
|
115
|
-
version: Optional[int],
|
116
|
-
method_name: str,
|
117
|
-
tlp_span_kind: Optional[TraceloopSpanKindValues] = TraceloopSpanKindValues.TASK,
|
118
|
-
):
|
119
|
-
def decorator(cls):
|
120
|
-
task_name = name if name else camel_to_snake(cls.__name__)
|
121
|
-
method = getattr(cls, method_name)
|
122
|
-
setattr(
|
123
|
-
cls,
|
124
|
-
method_name,
|
125
|
-
entity_method(name=task_name, version=version, tlp_span_kind=tlp_span_kind)(
|
126
|
-
method
|
127
|
-
),
|
128
|
-
)
|
129
|
-
return cls
|
130
|
-
|
131
|
-
return decorator
|
132
|
-
|
133
|
-
|
134
86
|
# Async Decorators
|
135
87
|
|
136
88
|
|
137
89
|
def aentity_method(
|
138
90
|
name: Optional[str] = None,
|
139
|
-
version: Optional[int] = None,
|
140
|
-
tlp_span_kind: Optional[TraceloopSpanKindValues] = TraceloopSpanKindValues.TASK,
|
141
91
|
):
|
142
92
|
def decorate(fn):
|
143
93
|
@wraps(fn)
|
144
94
|
async def wrap(*args, **kwargs):
|
145
95
|
if not TracerWrapper.verify_initialized():
|
146
|
-
print("Tracer not initialized")
|
147
96
|
return await fn(*args, **kwargs)
|
148
97
|
|
149
|
-
|
150
|
-
if tlp_span_kind in [
|
151
|
-
TraceloopSpanKindValues.WORKFLOW,
|
152
|
-
TraceloopSpanKindValues.AGENT,
|
153
|
-
]:
|
154
|
-
set_workflow_name(entity_name)
|
155
|
-
span_name = f"{entity_name}.{tlp_span_kind.value}"
|
98
|
+
span_name = name or fn.__name__
|
156
99
|
|
157
100
|
with get_tracer() as tracer:
|
158
101
|
span = tracer.start_span(span_name)
|
159
102
|
ctx = trace.set_span_in_context(span)
|
160
103
|
ctx_token = context_api.attach(ctx)
|
161
104
|
|
162
|
-
if tlp_span_kind in [
|
163
|
-
TraceloopSpanKindValues.TASK,
|
164
|
-
TraceloopSpanKindValues.TOOL,
|
165
|
-
]:
|
166
|
-
entity_path = get_chained_entity_path(entity_name)
|
167
|
-
set_entity_path(entity_path)
|
168
|
-
|
169
|
-
span.set_attribute(
|
170
|
-
SpanAttributes.TRACELOOP_SPAN_KIND, tlp_span_kind.value
|
171
|
-
)
|
172
|
-
span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_NAME, entity_name)
|
173
|
-
if version:
|
174
|
-
span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_VERSION, version)
|
175
|
-
|
176
105
|
try:
|
177
106
|
if _should_send_prompts():
|
178
107
|
span.set_attribute(
|
@@ -206,27 +135,6 @@ def aentity_method(
|
|
206
135
|
return decorate
|
207
136
|
|
208
137
|
|
209
|
-
def aentity_class(
|
210
|
-
name: Optional[str],
|
211
|
-
version: Optional[int],
|
212
|
-
method_name: str,
|
213
|
-
tlp_span_kind: Optional[TraceloopSpanKindValues] = TraceloopSpanKindValues.TASK,
|
214
|
-
):
|
215
|
-
def decorator(cls):
|
216
|
-
task_name = name if name else camel_to_snake(cls.__name__)
|
217
|
-
method = getattr(cls, method_name)
|
218
|
-
setattr(
|
219
|
-
cls,
|
220
|
-
method_name,
|
221
|
-
aentity_method(
|
222
|
-
name=task_name, version=version, tlp_span_kind=tlp_span_kind
|
223
|
-
)(method),
|
224
|
-
)
|
225
|
-
return cls
|
226
|
-
|
227
|
-
return decorator
|
228
|
-
|
229
|
-
|
230
138
|
def _handle_generator(span, res):
|
231
139
|
# for some reason the SPAN_KEY is not being set in the context of the generator, so we re-set it
|
232
140
|
context_api.attach(trace.set_span_in_context(span))
|
@@ -1 +1 @@
|
|
1
|
-
"""unit tests."""
|
1
|
+
# """unit tests."""
|