lmnr 0.4.36__py3-none-any.whl → 0.4.37__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.
Files changed (48) hide show
  1. lmnr/__init__.py +2 -2
  2. lmnr/{traceloop_sdk → openllmetry_sdk}/__init__.py +3 -3
  3. lmnr/{traceloop_sdk → openllmetry_sdk}/decorators/base.py +4 -4
  4. lmnr/openllmetry_sdk/tracing/__init__.py +1 -0
  5. lmnr/{traceloop_sdk → openllmetry_sdk}/tracing/context_manager.py +1 -1
  6. lmnr/{traceloop_sdk → openllmetry_sdk}/tracing/tracing.py +61 -47
  7. lmnr/sdk/decorators.py +3 -3
  8. lmnr/sdk/evaluations.py +2 -2
  9. lmnr/sdk/laminar.py +7 -7
  10. {lmnr-0.4.36.dist-info → lmnr-0.4.37.dist-info}/METADATA +2 -2
  11. lmnr-0.4.37.dist-info/RECORD +32 -0
  12. lmnr/traceloop_sdk/tests/__init__.py +0 -1
  13. lmnr/traceloop_sdk/tests/cassettes/test_association_properties/test_langchain_and_external_association_properties.yaml +0 -101
  14. lmnr/traceloop_sdk/tests/cassettes/test_association_properties/test_langchain_association_properties.yaml +0 -99
  15. lmnr/traceloop_sdk/tests/cassettes/test_manual/test_manual_report.yaml +0 -98
  16. lmnr/traceloop_sdk/tests/cassettes/test_manual/test_resource_attributes.yaml +0 -98
  17. lmnr/traceloop_sdk/tests/cassettes/test_privacy_no_prompts/test_simple_workflow.yaml +0 -199
  18. lmnr/traceloop_sdk/tests/cassettes/test_prompt_management/test_prompt_management.yaml +0 -202
  19. lmnr/traceloop_sdk/tests/cassettes/test_sdk_initialization/test_resource_attributes.yaml +0 -199
  20. lmnr/traceloop_sdk/tests/cassettes/test_tasks/test_task_io_serialization_with_langchain.yaml +0 -96
  21. lmnr/traceloop_sdk/tests/cassettes/test_workflows/test_simple_aworkflow.yaml +0 -98
  22. lmnr/traceloop_sdk/tests/cassettes/test_workflows/test_simple_workflow.yaml +0 -199
  23. lmnr/traceloop_sdk/tests/cassettes/test_workflows/test_streaming_workflow.yaml +0 -167
  24. lmnr/traceloop_sdk/tests/conftest.py +0 -111
  25. lmnr/traceloop_sdk/tests/test_association_properties.py +0 -229
  26. lmnr/traceloop_sdk/tests/test_manual.py +0 -48
  27. lmnr/traceloop_sdk/tests/test_nested_tasks.py +0 -47
  28. lmnr/traceloop_sdk/tests/test_privacy_no_prompts.py +0 -50
  29. lmnr/traceloop_sdk/tests/test_sdk_initialization.py +0 -57
  30. lmnr/traceloop_sdk/tests/test_tasks.py +0 -32
  31. lmnr/traceloop_sdk/tests/test_workflows.py +0 -262
  32. lmnr/traceloop_sdk/tracing/__init__.py +0 -1
  33. lmnr-0.4.36.dist-info/RECORD +0 -52
  34. /lmnr/{traceloop_sdk → openllmetry_sdk}/.flake8 +0 -0
  35. /lmnr/{traceloop_sdk → openllmetry_sdk}/.python-version +0 -0
  36. /lmnr/{traceloop_sdk → openllmetry_sdk}/config/__init__.py +0 -0
  37. /lmnr/{traceloop_sdk → openllmetry_sdk}/decorators/__init__.py +0 -0
  38. /lmnr/{traceloop_sdk → openllmetry_sdk}/instruments.py +0 -0
  39. /lmnr/{traceloop_sdk → openllmetry_sdk}/tracing/attributes.py +0 -0
  40. /lmnr/{traceloop_sdk → openllmetry_sdk}/tracing/content_allow_list.py +0 -0
  41. /lmnr/{traceloop_sdk → openllmetry_sdk}/utils/__init__.py +0 -0
  42. /lmnr/{traceloop_sdk → openllmetry_sdk}/utils/in_memory_span_exporter.py +0 -0
  43. /lmnr/{traceloop_sdk → openllmetry_sdk}/utils/json_encoder.py +0 -0
  44. /lmnr/{traceloop_sdk → openllmetry_sdk}/utils/package_check.py +0 -0
  45. /lmnr/{traceloop_sdk → openllmetry_sdk}/version.py +0 -0
  46. {lmnr-0.4.36.dist-info → lmnr-0.4.37.dist-info}/LICENSE +0 -0
  47. {lmnr-0.4.36.dist-info → lmnr-0.4.37.dist-info}/WHEEL +0 -0
  48. {lmnr-0.4.36.dist-info → lmnr-0.4.37.dist-info}/entry_points.txt +0 -0
@@ -1,167 +0,0 @@
1
- interactions:
2
- - request:
3
- body: '{"messages": [{"role": "user", "content": "Tell me a joke about OpenTelemetry"}],
4
- "model": "gpt-3.5-turbo", "stream": true}'
5
- headers:
6
- accept:
7
- - application/json
8
- accept-encoding:
9
- - gzip, deflate
10
- connection:
11
- - keep-alive
12
- content-length:
13
- - '123'
14
- content-type:
15
- - application/json
16
- host:
17
- - api.openai.com
18
- user-agent:
19
- - OpenAI/Python 1.29.0
20
- x-stainless-arch:
21
- - arm64
22
- x-stainless-async:
23
- - 'false'
24
- x-stainless-lang:
25
- - python
26
- x-stainless-os:
27
- - MacOS
28
- x-stainless-package-version:
29
- - 1.29.0
30
- x-stainless-runtime:
31
- - CPython
32
- x-stainless-runtime-version:
33
- - 3.9.5
34
- method: POST
35
- uri: https://api.openai.com/v1/chat/completions
36
- response:
37
- body:
38
- string: 'data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
39
-
40
-
41
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Why"},"logprobs":null,"finish_reason":null}]}
42
-
43
-
44
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
45
- did"},"logprobs":null,"finish_reason":null}]}
46
-
47
-
48
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
49
- the"},"logprobs":null,"finish_reason":null}]}
50
-
51
-
52
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
53
- Open"},"logprobs":null,"finish_reason":null}]}
54
-
55
-
56
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Te"},"logprobs":null,"finish_reason":null}]}
57
-
58
-
59
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"lemetry"},"logprobs":null,"finish_reason":null}]}
60
-
61
-
62
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
63
- project"},"logprobs":null,"finish_reason":null}]}
64
-
65
-
66
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
67
- go"},"logprobs":null,"finish_reason":null}]}
68
-
69
-
70
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
71
- to"},"logprobs":null,"finish_reason":null}]}
72
-
73
-
74
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
75
- therapy"},"logprobs":null,"finish_reason":null}]}
76
-
77
-
78
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"?"},"logprobs":null,"finish_reason":null}]}
79
-
80
-
81
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
82
- Because"},"logprobs":null,"finish_reason":null}]}
83
-
84
-
85
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
86
- it"},"logprobs":null,"finish_reason":null}]}
87
-
88
-
89
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
90
- had"},"logprobs":null,"finish_reason":null}]}
91
-
92
-
93
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
94
- too"},"logprobs":null,"finish_reason":null}]}
95
-
96
-
97
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
98
- many"},"logprobs":null,"finish_reason":null}]}
99
-
100
-
101
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
102
- mixed"},"logprobs":null,"finish_reason":null}]}
103
-
104
-
105
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
106
- signals"},"logprobs":null,"finish_reason":null}]}
107
-
108
-
109
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"!"},"logprobs":null,"finish_reason":null}]}
110
-
111
-
112
- data: {"id":"chatcmpl-9OmDmBFHEMbZ31rnA9lGQVDOehR90","object":"chat.completion.chunk","created":1715692262,"model":"gpt-3.5-turbo-0125","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
113
-
114
-
115
- data: [DONE]
116
-
117
-
118
- '
119
- headers:
120
- CF-Cache-Status:
121
- - DYNAMIC
122
- CF-RAY:
123
- - 883b21bd48433757-MXP
124
- Connection:
125
- - keep-alive
126
- Content-Type:
127
- - text/event-stream; charset=utf-8
128
- Date:
129
- - Tue, 14 May 2024 13:11:02 GMT
130
- Server:
131
- - cloudflare
132
- Set-Cookie:
133
- - __cf_bm=.XvQIxrHkdjS_lppgd.ONqVkLX2zudBgR.99K5inab0-1715692262-1.0.1.1-4NFlLxxPE4GhJUwcqVuShu7r29Wsv6mCxObuGBm7WaBuVBW22_MYG6uT0eJ1DUdmuZ9nykZ7bwQeYmQRkGgCdA;
134
- path=/; expires=Tue, 14-May-24 13:41:02 GMT; domain=.api.openai.com; HttpOnly;
135
- Secure; SameSite=None
136
- - _cfuvid=l3N15ZuTdlc6cNEordeiaV5FrYGVfteXAquEnUzpYpk-1715692262541-0.0.1.1-604800000;
137
- path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
138
- Transfer-Encoding:
139
- - chunked
140
- alt-svc:
141
- - h3=":443"; ma=86400
142
- openai-organization:
143
- - traceloop
144
- openai-processing-ms:
145
- - '268'
146
- openai-version:
147
- - '2020-10-01'
148
- strict-transport-security:
149
- - max-age=15724800; includeSubDomains
150
- x-ratelimit-limit-requests:
151
- - '5000'
152
- x-ratelimit-limit-tokens:
153
- - '160000'
154
- x-ratelimit-remaining-requests:
155
- - '4999'
156
- x-ratelimit-remaining-tokens:
157
- - '159974'
158
- x-ratelimit-reset-requests:
159
- - 12ms
160
- x-ratelimit-reset-tokens:
161
- - 9ms
162
- x-request-id:
163
- - req_1bf87984992f16d43b7eb6e9338a0d05
164
- status:
165
- code: 200
166
- message: OK
167
- version: 1
@@ -1,111 +0,0 @@
1
- # """Unit tests configuration module."""
2
-
3
- # import os
4
- # import pytest
5
- # from lmnr.traceloop_sdk import Traceloop
6
- # from lmnr.traceloop_sdk.instruments import Instruments
7
- # from lmnr.traceloop_sdk.tracing.tracing import TracerWrapper
8
- # from opentelemetry.sdk.trace.export import SimpleSpanProcessor
9
- # from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
10
-
11
- # # pytest_plugins = []
12
-
13
-
14
- # @pytest.fixture(scope="session")
15
- # def exporter():
16
- # exporter = InMemorySpanExporter()
17
- # Traceloop.init(
18
- # app_name="test",
19
- # resource_attributes={"something": "yes"},
20
- # disable_batch=True,
21
- # exporter=exporter,
22
- # )
23
- # return exporter
24
-
25
-
26
- # @pytest.fixture(autouse=True)
27
- # def clear_exporter(exporter):
28
- # exporter.clear()
29
-
30
-
31
- # @pytest.fixture(autouse=True)
32
- # def environment():
33
- # if "OPENAI_API_KEY" not in os.environ:
34
- # os.environ["OPENAI_API_KEY"] = "test_api_key"
35
-
36
-
37
- # @pytest.fixture(scope="module")
38
- # def vcr_config():
39
- # return {
40
- # "filter_headers": ["authorization"],
41
- # "ignore_hosts": ["openaipublic.blob.core.windows.net"],
42
- # }
43
-
44
-
45
- # @pytest.fixture
46
- # def exporter_with_custom_span_processor():
47
- # # Clear singleton if existed
48
- # if hasattr(TracerWrapper, "instance"):
49
- # _trace_wrapper_instance = TracerWrapper.instance
50
- # del TracerWrapper.instance
51
-
52
- # class CustomSpanProcessor(SimpleSpanProcessor):
53
- # def on_start(self, span, parent_context=None):
54
- # span.set_attribute("custom_span", "yes")
55
-
56
- # exporter = InMemorySpanExporter()
57
- # Traceloop.init(
58
- # exporter=exporter,
59
- # processor=CustomSpanProcessor(exporter),
60
- # )
61
-
62
- # yield exporter
63
-
64
- # # Restore singleton if any
65
- # if _trace_wrapper_instance:
66
- # TracerWrapper.instance = _trace_wrapper_instance
67
-
68
-
69
- # @pytest.fixture
70
- # def exporter_with_custom_instrumentations():
71
- # # Clear singleton if existed
72
- # if hasattr(TracerWrapper, "instance"):
73
- # _trace_wrapper_instance = TracerWrapper.instance
74
- # del TracerWrapper.instance
75
-
76
- # exporter = InMemorySpanExporter()
77
- # Traceloop.init(
78
- # exporter=exporter,
79
- # disable_batch=True,
80
- # instruments=[i for i in Instruments],
81
- # )
82
-
83
- # yield exporter
84
-
85
- # # Restore singleton if any
86
- # if _trace_wrapper_instance:
87
- # TracerWrapper.instance = _trace_wrapper_instance
88
-
89
-
90
- # @pytest.fixture
91
- # def exporter_with_no_metrics():
92
- # # Clear singleton if existed
93
- # if hasattr(TracerWrapper, "instance"):
94
- # _trace_wrapper_instance = TracerWrapper.instance
95
- # del TracerWrapper.instance
96
-
97
- # os.environ["TRACELOOP_METRICS_ENABLED"] = "false"
98
-
99
- # exporter = InMemorySpanExporter()
100
-
101
- # Traceloop.init(
102
- # exporter=exporter,
103
- # disable_batch=True,
104
- # )
105
-
106
- # yield exporter
107
-
108
- # # Restore singleton if any
109
- # if _trace_wrapper_instance:
110
- # TracerWrapper.instance = _trace_wrapper_instance
111
- # os.environ["TRACELOOP_METRICS_ENABLED"] = "true"
@@ -1,229 +0,0 @@
1
- # import pytest
2
- # from langchain_openai import ChatOpenAI
3
- # from langchain.prompts import ChatPromptTemplate
4
- # from opentelemetry.semconv_ai import SpanAttributes
5
- # from lmnr.traceloop_sdk import Traceloop
6
- # from lmnr.traceloop_sdk.decorators import task, workflow
7
-
8
-
9
- # def test_association_properties(exporter):
10
- # @workflow(name="test_workflow")
11
- # def test_workflow():
12
- # return test_task()
13
-
14
- # @task(name="test_task")
15
- # def test_task():
16
- # return
17
-
18
- # Traceloop.set_association_properties({"user_id": 1, "user_name": "John Doe"})
19
- # test_workflow()
20
-
21
- # spans = exporter.get_finished_spans()
22
- # assert [span.name for span in spans] == [
23
- # "test_task.task",
24
- # "test_workflow.workflow",
25
- # ]
26
-
27
- # some_task_span = spans[0]
28
- # some_workflow_span = spans[1]
29
- # assert (
30
- # some_workflow_span.attributes[
31
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.user_id"
32
- # ]
33
- # == 1
34
- # )
35
- # assert (
36
- # some_workflow_span.attributes[
37
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.user_name"
38
- # ]
39
- # == "John Doe"
40
- # )
41
- # assert (
42
- # some_task_span.attributes[
43
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.user_id"
44
- # ]
45
- # == 1
46
- # )
47
- # assert (
48
- # some_task_span.attributes[
49
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.user_name"
50
- # ]
51
- # == "John Doe"
52
- # )
53
-
54
-
55
- # def test_association_properties_within_workflow(exporter):
56
- # @workflow(name="test_workflow_within")
57
- # def test_workflow():
58
- # Traceloop.set_association_properties({"session_id": 15})
59
- # return
60
-
61
- # test_workflow()
62
-
63
- # spans = exporter.get_finished_spans()
64
- # assert [span.name for span in spans] == [
65
- # "test_workflow_within.workflow",
66
- # ]
67
-
68
- # some_workflow_span = spans[0]
69
- # assert (
70
- # some_workflow_span.attributes[
71
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.session_id"
72
- # ]
73
- # == 15
74
- # )
75
-
76
-
77
- # @pytest.mark.vcr
78
- # def test_langchain_association_properties(exporter):
79
- # prompt = ChatPromptTemplate.from_messages(
80
- # [("system", "You are helpful assistant"), ("user", "{input}")]
81
- # )
82
- # model = ChatOpenAI(model="gpt-3.5-turbo")
83
-
84
- # chain = prompt | model
85
- # chain.invoke(
86
- # {"input": "tell me a short joke"},
87
- # {"metadata": {"user_id": "1234", "session_id": 456}},
88
- # )
89
-
90
- # spans = exporter.get_finished_spans()
91
-
92
- # assert [
93
- # "ChatPromptTemplate.task",
94
- # "ChatOpenAI.chat",
95
- # "RunnableSequence.workflow",
96
- # ] == [span.name for span in spans], [span.name for span in spans]
97
-
98
- # workflow_span = next(
99
- # span for span in spans if span.name == "RunnableSequence.workflow"
100
- # )
101
- # prompt_span = next(span for span in spans if span.name == "ChatPromptTemplate.task")
102
- # chat_span = next(span for span in spans if span.name == "ChatOpenAI.chat")
103
-
104
- # assert (
105
- # workflow_span.attributes[
106
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.user_id"
107
- # ]
108
- # == "1234"
109
- # )
110
- # assert (
111
- # workflow_span.attributes[
112
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.session_id"
113
- # ]
114
- # == 456
115
- # )
116
- # assert (
117
- # chat_span.attributes[
118
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.user_id"
119
- # ]
120
- # == "1234"
121
- # )
122
- # assert (
123
- # chat_span.attributes[
124
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.session_id"
125
- # ]
126
- # == 456
127
- # )
128
- # assert (
129
- # prompt_span.attributes[
130
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.user_id"
131
- # ]
132
- # == "1234"
133
- # )
134
- # assert (
135
- # prompt_span.attributes[
136
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.session_id"
137
- # ]
138
- # == 456
139
- # )
140
-
141
-
142
- # @pytest.mark.vcr
143
- # def test_langchain_and_external_association_properties(exporter):
144
- # @workflow(name="test_workflow_external")
145
- # def test_workflow_external():
146
- # Traceloop.set_association_properties({"workspace_id": "789"})
147
-
148
- # prompt = ChatPromptTemplate.from_messages(
149
- # [("system", "You are helpful assistant"), ("user", "{input}")]
150
- # )
151
- # model = ChatOpenAI(model="gpt-3.5-turbo")
152
-
153
- # chain = prompt | model
154
- # chain.invoke(
155
- # {"input": "tell me a short joke"},
156
- # {"metadata": {"user_id": "1234", "session_id": 456}},
157
- # )
158
-
159
- # test_workflow_external()
160
-
161
- # spans = exporter.get_finished_spans()
162
-
163
- # assert [
164
- # "ChatPromptTemplate.task",
165
- # "ChatOpenAI.chat",
166
- # "RunnableSequence.workflow",
167
- # "test_workflow_external.workflow",
168
- # ] == [span.name for span in spans], [span.name for span in spans]
169
-
170
- # workflow_span = next(
171
- # span for span in spans if span.name == "RunnableSequence.workflow"
172
- # )
173
- # prompt_span = next(span for span in spans if span.name == "ChatPromptTemplate.task")
174
- # chat_span = next(span for span in spans if span.name == "ChatOpenAI.chat")
175
-
176
- # assert (
177
- # workflow_span.attributes[
178
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.user_id"
179
- # ]
180
- # == "1234"
181
- # )
182
- # assert (
183
- # workflow_span.attributes[
184
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.session_id"
185
- # ]
186
- # == 456
187
- # )
188
- # assert (
189
- # workflow_span.attributes[
190
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.workspace_id"
191
- # ]
192
- # == "789"
193
- # )
194
- # assert (
195
- # chat_span.attributes[
196
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.user_id"
197
- # ]
198
- # == "1234"
199
- # )
200
- # assert (
201
- # chat_span.attributes[
202
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.session_id"
203
- # ]
204
- # == 456
205
- # )
206
- # assert (
207
- # chat_span.attributes[
208
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.workspace_id"
209
- # ]
210
- # == "789"
211
- # )
212
- # assert (
213
- # prompt_span.attributes[
214
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.user_id"
215
- # ]
216
- # == "1234"
217
- # )
218
- # assert (
219
- # prompt_span.attributes[
220
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.session_id"
221
- # ]
222
- # == 456
223
- # )
224
- # assert (
225
- # prompt_span.attributes[
226
- # f"{SpanAttributes.TRACELOOP_ASSOCIATION_PROPERTIES}.workspace_id"
227
- # ]
228
- # == "789"
229
- # )
@@ -1,48 +0,0 @@
1
- # from opentelemetry.semconv_ai import SpanAttributes
2
- # import pytest
3
- # from openai import OpenAI
4
- # from lmnr.traceloop_sdk.tracing.manual import LLMMessage, track_llm_call
5
-
6
-
7
- # @pytest.fixture
8
- # def openai_client():
9
- # return OpenAI()
10
-
11
-
12
- # @pytest.mark.vcr
13
- # def test_manual_report(exporter, openai_client):
14
- # with track_llm_call(vendor="openai", type="chat") as span:
15
- # span.report_request(
16
- # model="gpt-3.5-turbo",
17
- # messages=[
18
- # LLMMessage(role="user", content="Tell me a joke about opentelemetry")
19
- # ],
20
- # )
21
-
22
- # res = openai_client.chat.completions.create(
23
- # model="gpt-3.5-turbo",
24
- # messages=[
25
- # {"role": "user", "content": "Tell me a joke about opentelemetry"}
26
- # ],
27
- # )
28
-
29
- # span.report_response(res.model, [text.message.content for text in res.choices])
30
-
31
- # spans = exporter.get_finished_spans()
32
- # open_ai_span = spans[0]
33
- # assert open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo"
34
- # assert open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "user"
35
- # assert (
36
- # open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"]
37
- # == "Tell me a joke about opentelemetry"
38
- # )
39
- # assert (
40
- # open_ai_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL]
41
- # == "gpt-3.5-turbo-0125"
42
- # )
43
- # assert (
44
- # open_ai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"]
45
- # == "Why did the opentelemetry developer break up with their partner? Because they were tired"
46
- # + " of constantly tracing their every move!"
47
- # )
48
- # assert open_ai_span.end_time > open_ai_span.start_time
@@ -1,47 +0,0 @@
1
- # from opentelemetry.semconv_ai import SpanAttributes
2
- # from lmnr.traceloop_sdk.decorators import task, workflow
3
- # from pytest import raises
4
-
5
-
6
- # def test_nested_tasks(exporter):
7
- # @workflow(name="some_workflow")
8
- # def some_workflow():
9
- # return outer_task()
10
-
11
- # @task(name="outer_task")
12
- # def outer_task():
13
- # return inner_task()
14
-
15
- # @task(name="inner_task")
16
- # def inner_task():
17
- # return inner_inner_task()
18
-
19
- # @task(name="inner_inner_task")
20
- # def inner_inner_task():
21
- # return
22
-
23
- # some_workflow()
24
-
25
- # spans = exporter.get_finished_spans()
26
- # assert [span.name for span in spans] == [
27
- # "inner_inner_task.task",
28
- # "inner_task.task",
29
- # "outer_task.task",
30
- # "some_workflow.workflow",
31
- # ]
32
-
33
- # inner_inner_task_span = spans[0]
34
- # inner_task_span = spans[1]
35
- # outer_task_span = spans[2]
36
- # some_workflow_span = spans[3]
37
-
38
- # assert (
39
- # inner_inner_task_span.attributes[SpanAttributes.TRACELOOP_ENTITY_PATH]
40
- # == "outer_task.inner_task"
41
- # )
42
- # assert (
43
- # inner_task_span.attributes[SpanAttributes.TRACELOOP_ENTITY_PATH] == "outer_task"
44
- # )
45
- # with raises(KeyError):
46
- # _ = outer_task_span.attributes[SpanAttributes.TRACELOOP_ENTITY_PATH]
47
- # _ = some_workflow_span.attributes[SpanAttributes.TRACELOOP_ENTITY_PATH]
@@ -1,50 +0,0 @@
1
- # import os
2
-
3
- # import pytest
4
- # from openai import OpenAI
5
- # from opentelemetry.semconv_ai import SpanAttributes
6
- # from lmnr.traceloop_sdk.decorators import workflow, task
7
-
8
-
9
- # @pytest.fixture(autouse=True)
10
- # def disable_trace_content():
11
- # os.environ["TRACELOOP_TRACE_CONTENT"] = "false"
12
- # yield
13
- # os.environ["TRACELOOP_TRACE_CONTENT"] = "true"
14
-
15
-
16
- # @pytest.fixture
17
- # def openai_client():
18
- # return OpenAI()
19
-
20
-
21
- # @pytest.mark.vcr
22
- # def test_simple_workflow(exporter, openai_client):
23
- # @task(name="joke_creation")
24
- # def create_joke():
25
- # completion = openai_client.chat.completions.create(
26
- # model="gpt-3.5-turbo",
27
- # messages=[
28
- # {"role": "user", "content": "Tell me a joke about opentelemetry"}
29
- # ],
30
- # )
31
- # return completion.choices[0].message.content
32
-
33
- # @workflow(name="pirate_joke_generator")
34
- # def joke_workflow():
35
- # create_joke()
36
-
37
- # joke_workflow()
38
-
39
- # spans = exporter.get_finished_spans()
40
- # assert [span.name for span in spans] == [
41
- # "openai.chat",
42
- # "joke_creation.task",
43
- # "pirate_joke_generator.workflow",
44
- # ]
45
- # open_ai_span = spans[0]
46
- # assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 15
47
- # assert not open_ai_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content")
48
- # assert not open_ai_span.attributes.get(
49
- # f"{SpanAttributes.LLM_PROMPTS}.0.completions"
50
- # )