mseep-agentops 0.4.18__py3-none-any.whl → 0.4.22__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 (153) hide show
  1. agentops/__init__.py +0 -0
  2. agentops/client/api/base.py +28 -30
  3. agentops/client/api/versions/v3.py +29 -25
  4. agentops/client/api/versions/v4.py +87 -46
  5. agentops/client/client.py +98 -29
  6. agentops/client/http/README.md +87 -0
  7. agentops/client/http/http_client.py +126 -172
  8. agentops/config.py +8 -2
  9. agentops/instrumentation/OpenTelemetry.md +133 -0
  10. agentops/instrumentation/README.md +167 -0
  11. agentops/instrumentation/__init__.py +13 -1
  12. agentops/instrumentation/agentic/ag2/__init__.py +18 -0
  13. agentops/instrumentation/agentic/ag2/instrumentor.py +922 -0
  14. agentops/instrumentation/agentic/agno/__init__.py +19 -0
  15. agentops/instrumentation/agentic/agno/attributes/__init__.py +20 -0
  16. agentops/instrumentation/agentic/agno/attributes/agent.py +250 -0
  17. agentops/instrumentation/agentic/agno/attributes/metrics.py +214 -0
  18. agentops/instrumentation/agentic/agno/attributes/storage.py +158 -0
  19. agentops/instrumentation/agentic/agno/attributes/team.py +195 -0
  20. agentops/instrumentation/agentic/agno/attributes/tool.py +210 -0
  21. agentops/instrumentation/agentic/agno/attributes/workflow.py +254 -0
  22. agentops/instrumentation/agentic/agno/instrumentor.py +1313 -0
  23. agentops/instrumentation/agentic/crewai/LICENSE +201 -0
  24. agentops/instrumentation/agentic/crewai/NOTICE.md +10 -0
  25. agentops/instrumentation/agentic/crewai/__init__.py +6 -0
  26. agentops/instrumentation/agentic/crewai/crewai_span_attributes.py +335 -0
  27. agentops/instrumentation/agentic/crewai/instrumentation.py +535 -0
  28. agentops/instrumentation/agentic/crewai/version.py +1 -0
  29. agentops/instrumentation/agentic/google_adk/__init__.py +19 -0
  30. agentops/instrumentation/agentic/google_adk/instrumentor.py +68 -0
  31. agentops/instrumentation/agentic/google_adk/patch.py +767 -0
  32. agentops/instrumentation/agentic/haystack/__init__.py +1 -0
  33. agentops/instrumentation/agentic/haystack/instrumentor.py +186 -0
  34. agentops/instrumentation/agentic/langgraph/__init__.py +3 -0
  35. agentops/instrumentation/agentic/langgraph/attributes.py +54 -0
  36. agentops/instrumentation/agentic/langgraph/instrumentation.py +598 -0
  37. agentops/instrumentation/agentic/langgraph/version.py +1 -0
  38. agentops/instrumentation/agentic/openai_agents/README.md +156 -0
  39. agentops/instrumentation/agentic/openai_agents/SPANS.md +145 -0
  40. agentops/instrumentation/agentic/openai_agents/TRACING_API.md +144 -0
  41. agentops/instrumentation/agentic/openai_agents/__init__.py +30 -0
  42. agentops/instrumentation/agentic/openai_agents/attributes/common.py +549 -0
  43. agentops/instrumentation/agentic/openai_agents/attributes/completion.py +172 -0
  44. agentops/instrumentation/agentic/openai_agents/attributes/model.py +58 -0
  45. agentops/instrumentation/agentic/openai_agents/attributes/tokens.py +275 -0
  46. agentops/instrumentation/agentic/openai_agents/exporter.py +469 -0
  47. agentops/instrumentation/agentic/openai_agents/instrumentor.py +107 -0
  48. agentops/instrumentation/agentic/openai_agents/processor.py +58 -0
  49. agentops/instrumentation/agentic/smolagents/README.md +88 -0
  50. agentops/instrumentation/agentic/smolagents/__init__.py +12 -0
  51. agentops/instrumentation/agentic/smolagents/attributes/agent.py +354 -0
  52. agentops/instrumentation/agentic/smolagents/attributes/model.py +205 -0
  53. agentops/instrumentation/agentic/smolagents/instrumentor.py +286 -0
  54. agentops/instrumentation/agentic/smolagents/stream_wrapper.py +258 -0
  55. agentops/instrumentation/agentic/xpander/__init__.py +15 -0
  56. agentops/instrumentation/agentic/xpander/context.py +112 -0
  57. agentops/instrumentation/agentic/xpander/instrumentor.py +877 -0
  58. agentops/instrumentation/agentic/xpander/trace_probe.py +86 -0
  59. agentops/instrumentation/agentic/xpander/version.py +3 -0
  60. agentops/instrumentation/common/README.md +65 -0
  61. agentops/instrumentation/common/attributes.py +1 -2
  62. agentops/instrumentation/providers/anthropic/__init__.py +24 -0
  63. agentops/instrumentation/providers/anthropic/attributes/__init__.py +23 -0
  64. agentops/instrumentation/providers/anthropic/attributes/common.py +64 -0
  65. agentops/instrumentation/providers/anthropic/attributes/message.py +541 -0
  66. agentops/instrumentation/providers/anthropic/attributes/tools.py +231 -0
  67. agentops/instrumentation/providers/anthropic/event_handler_wrapper.py +90 -0
  68. agentops/instrumentation/providers/anthropic/instrumentor.py +146 -0
  69. agentops/instrumentation/providers/anthropic/stream_wrapper.py +436 -0
  70. agentops/instrumentation/providers/google_genai/README.md +33 -0
  71. agentops/instrumentation/providers/google_genai/__init__.py +24 -0
  72. agentops/instrumentation/providers/google_genai/attributes/__init__.py +25 -0
  73. agentops/instrumentation/providers/google_genai/attributes/chat.py +125 -0
  74. agentops/instrumentation/providers/google_genai/attributes/common.py +88 -0
  75. agentops/instrumentation/providers/google_genai/attributes/model.py +284 -0
  76. agentops/instrumentation/providers/google_genai/instrumentor.py +170 -0
  77. agentops/instrumentation/providers/google_genai/stream_wrapper.py +238 -0
  78. agentops/instrumentation/providers/ibm_watsonx_ai/__init__.py +28 -0
  79. agentops/instrumentation/providers/ibm_watsonx_ai/attributes/__init__.py +27 -0
  80. agentops/instrumentation/providers/ibm_watsonx_ai/attributes/attributes.py +277 -0
  81. agentops/instrumentation/providers/ibm_watsonx_ai/attributes/common.py +104 -0
  82. agentops/instrumentation/providers/ibm_watsonx_ai/instrumentor.py +162 -0
  83. agentops/instrumentation/providers/ibm_watsonx_ai/stream_wrapper.py +302 -0
  84. agentops/instrumentation/providers/mem0/__init__.py +45 -0
  85. agentops/instrumentation/providers/mem0/common.py +377 -0
  86. agentops/instrumentation/providers/mem0/instrumentor.py +270 -0
  87. agentops/instrumentation/providers/mem0/memory.py +430 -0
  88. agentops/instrumentation/providers/openai/__init__.py +21 -0
  89. agentops/instrumentation/providers/openai/attributes/__init__.py +7 -0
  90. agentops/instrumentation/providers/openai/attributes/common.py +55 -0
  91. agentops/instrumentation/providers/openai/attributes/response.py +607 -0
  92. agentops/instrumentation/providers/openai/config.py +36 -0
  93. agentops/instrumentation/providers/openai/instrumentor.py +312 -0
  94. agentops/instrumentation/providers/openai/stream_wrapper.py +941 -0
  95. agentops/instrumentation/providers/openai/utils.py +44 -0
  96. agentops/instrumentation/providers/openai/v0.py +176 -0
  97. agentops/instrumentation/providers/openai/v0_wrappers.py +483 -0
  98. agentops/instrumentation/providers/openai/wrappers/__init__.py +30 -0
  99. agentops/instrumentation/providers/openai/wrappers/assistant.py +277 -0
  100. agentops/instrumentation/providers/openai/wrappers/chat.py +259 -0
  101. agentops/instrumentation/providers/openai/wrappers/completion.py +109 -0
  102. agentops/instrumentation/providers/openai/wrappers/embeddings.py +94 -0
  103. agentops/instrumentation/providers/openai/wrappers/image_gen.py +75 -0
  104. agentops/instrumentation/providers/openai/wrappers/responses.py +191 -0
  105. agentops/instrumentation/providers/openai/wrappers/shared.py +81 -0
  106. agentops/instrumentation/utilities/concurrent_futures/__init__.py +10 -0
  107. agentops/instrumentation/utilities/concurrent_futures/instrumentation.py +206 -0
  108. agentops/integration/callbacks/dspy/__init__.py +11 -0
  109. agentops/integration/callbacks/dspy/callback.py +471 -0
  110. agentops/integration/callbacks/langchain/README.md +59 -0
  111. agentops/integration/callbacks/langchain/__init__.py +15 -0
  112. agentops/integration/callbacks/langchain/callback.py +791 -0
  113. agentops/integration/callbacks/langchain/utils.py +54 -0
  114. agentops/legacy/crewai.md +121 -0
  115. agentops/logging/instrument_logging.py +4 -0
  116. agentops/sdk/README.md +220 -0
  117. agentops/sdk/core.py +75 -32
  118. agentops/sdk/descriptors/classproperty.py +28 -0
  119. agentops/sdk/exporters.py +152 -33
  120. agentops/semconv/README.md +125 -0
  121. agentops/semconv/span_kinds.py +0 -2
  122. agentops/validation.py +102 -63
  123. {mseep_agentops-0.4.18.dist-info → mseep_agentops-0.4.22.dist-info}/METADATA +30 -40
  124. mseep_agentops-0.4.22.dist-info/RECORD +178 -0
  125. {mseep_agentops-0.4.18.dist-info → mseep_agentops-0.4.22.dist-info}/WHEEL +1 -2
  126. mseep_agentops-0.4.18.dist-info/RECORD +0 -94
  127. mseep_agentops-0.4.18.dist-info/top_level.txt +0 -2
  128. tests/conftest.py +0 -10
  129. tests/unit/client/__init__.py +0 -1
  130. tests/unit/client/test_http_adapter.py +0 -221
  131. tests/unit/client/test_http_client.py +0 -206
  132. tests/unit/conftest.py +0 -54
  133. tests/unit/sdk/__init__.py +0 -1
  134. tests/unit/sdk/instrumentation_tester.py +0 -207
  135. tests/unit/sdk/test_attributes.py +0 -392
  136. tests/unit/sdk/test_concurrent_instrumentation.py +0 -468
  137. tests/unit/sdk/test_decorators.py +0 -763
  138. tests/unit/sdk/test_exporters.py +0 -241
  139. tests/unit/sdk/test_factory.py +0 -1188
  140. tests/unit/sdk/test_internal_span_processor.py +0 -397
  141. tests/unit/sdk/test_resource_attributes.py +0 -35
  142. tests/unit/test_config.py +0 -82
  143. tests/unit/test_context_manager.py +0 -777
  144. tests/unit/test_events.py +0 -27
  145. tests/unit/test_host_env.py +0 -54
  146. tests/unit/test_init_py.py +0 -501
  147. tests/unit/test_serialization.py +0 -433
  148. tests/unit/test_session.py +0 -676
  149. tests/unit/test_user_agent.py +0 -34
  150. tests/unit/test_validation.py +0 -405
  151. {tests → agentops/instrumentation/agentic/openai_agents/attributes}/__init__.py +0 -0
  152. /tests/unit/__init__.py → /agentops/instrumentation/providers/openai/attributes/tools.py +0 -0
  153. {mseep_agentops-0.4.18.dist-info → mseep_agentops-0.4.22.dist-info}/licenses/LICENSE +0 -0
@@ -1,392 +0,0 @@
1
- """
2
- Tests for agentops.sdk.attributes module.
3
-
4
- This module tests all attribute management functions for telemetry contexts.
5
- """
6
-
7
- import platform
8
- from unittest.mock import Mock, patch
9
-
10
- import pytest
11
-
12
- from agentops.sdk.attributes import (
13
- get_system_resource_attributes,
14
- get_global_resource_attributes,
15
- get_trace_attributes,
16
- get_span_attributes,
17
- get_session_end_attributes,
18
- )
19
- from agentops.semconv import ResourceAttributes, SpanAttributes, CoreAttributes
20
-
21
-
22
- class TestGetSystemResourceAttributes:
23
- """Test get_system_resource_attributes function."""
24
-
25
- def test_basic_system_attributes(self):
26
- """Test that basic system attributes are included."""
27
- attributes = get_system_resource_attributes()
28
-
29
- # Check that all basic platform attributes are present
30
- assert ResourceAttributes.HOST_MACHINE in attributes
31
- assert ResourceAttributes.HOST_NAME in attributes
32
- assert ResourceAttributes.HOST_NODE in attributes
33
- assert ResourceAttributes.HOST_PROCESSOR in attributes
34
- assert ResourceAttributes.HOST_SYSTEM in attributes
35
- assert ResourceAttributes.HOST_VERSION in attributes
36
- assert ResourceAttributes.HOST_OS_RELEASE in attributes
37
-
38
- # Check that values match platform module
39
- assert attributes[ResourceAttributes.HOST_MACHINE] == platform.machine()
40
- assert attributes[ResourceAttributes.HOST_NAME] == platform.node()
41
- assert attributes[ResourceAttributes.HOST_NODE] == platform.node()
42
- assert attributes[ResourceAttributes.HOST_PROCESSOR] == platform.processor()
43
- assert attributes[ResourceAttributes.HOST_SYSTEM] == platform.system()
44
- assert attributes[ResourceAttributes.HOST_VERSION] == platform.version()
45
- assert attributes[ResourceAttributes.HOST_OS_RELEASE] == platform.release()
46
-
47
- @patch("agentops.sdk.attributes.os.cpu_count")
48
- @patch("agentops.sdk.attributes.psutil.cpu_percent")
49
- def test_cpu_stats_success(self, mock_cpu_percent, mock_cpu_count):
50
- """Test CPU stats when successfully retrieved."""
51
- mock_cpu_count.return_value = 8
52
- mock_cpu_percent.return_value = 25.5
53
-
54
- attributes = get_system_resource_attributes()
55
-
56
- assert ResourceAttributes.CPU_COUNT in attributes
57
- assert ResourceAttributes.CPU_PERCENT in attributes
58
- assert attributes[ResourceAttributes.CPU_COUNT] == 8
59
- assert attributes[ResourceAttributes.CPU_PERCENT] == 25.5
60
-
61
- @patch("agentops.sdk.attributes.os.cpu_count")
62
- @patch("agentops.sdk.attributes.psutil.cpu_percent")
63
- def test_cpu_stats_cpu_count_none(self, mock_cpu_percent, mock_cpu_count):
64
- """Test CPU stats when cpu_count returns None."""
65
- mock_cpu_count.return_value = None
66
- mock_cpu_percent.return_value = 25.5
67
-
68
- attributes = get_system_resource_attributes()
69
-
70
- assert ResourceAttributes.CPU_COUNT in attributes
71
- assert attributes[ResourceAttributes.CPU_COUNT] == 0
72
-
73
- @patch("agentops.sdk.attributes.os.cpu_count")
74
- @patch("agentops.sdk.attributes.psutil.cpu_percent")
75
- def test_cpu_stats_exception(self, mock_cpu_percent, mock_cpu_count):
76
- """Test CPU stats when exception occurs."""
77
- mock_cpu_count.side_effect = Exception("CPU count error")
78
- mock_cpu_percent.side_effect = Exception("CPU percent error")
79
-
80
- attributes = get_system_resource_attributes()
81
-
82
- # Should not include CPU attributes when exception occurs
83
- assert ResourceAttributes.CPU_COUNT not in attributes
84
- assert ResourceAttributes.CPU_PERCENT not in attributes
85
-
86
- @patch("agentops.sdk.attributes.psutil.virtual_memory")
87
- def test_memory_stats_success(self, mock_virtual_memory):
88
- """Test memory stats when successfully retrieved."""
89
- mock_memory = Mock()
90
- mock_memory.total = 8589934592 # 8GB
91
- mock_memory.available = 4294967296 # 4GB
92
- mock_memory.used = 4294967296 # 4GB
93
- mock_memory.percent = 50.0
94
- mock_virtual_memory.return_value = mock_memory
95
-
96
- attributes = get_system_resource_attributes()
97
-
98
- assert ResourceAttributes.MEMORY_TOTAL in attributes
99
- assert ResourceAttributes.MEMORY_AVAILABLE in attributes
100
- assert ResourceAttributes.MEMORY_USED in attributes
101
- assert ResourceAttributes.MEMORY_PERCENT in attributes
102
- assert attributes[ResourceAttributes.MEMORY_TOTAL] == 8589934592
103
- assert attributes[ResourceAttributes.MEMORY_AVAILABLE] == 4294967296
104
- assert attributes[ResourceAttributes.MEMORY_USED] == 4294967296
105
- assert attributes[ResourceAttributes.MEMORY_PERCENT] == 50.0
106
-
107
- @patch("agentops.sdk.attributes.psutil.virtual_memory")
108
- def test_memory_stats_exception(self, mock_virtual_memory):
109
- """Test memory stats when exception occurs."""
110
- mock_virtual_memory.side_effect = Exception("Memory error")
111
-
112
- attributes = get_system_resource_attributes()
113
-
114
- # Should not include memory attributes when exception occurs
115
- assert ResourceAttributes.MEMORY_TOTAL not in attributes
116
- assert ResourceAttributes.MEMORY_AVAILABLE not in attributes
117
- assert ResourceAttributes.MEMORY_USED not in attributes
118
- assert ResourceAttributes.MEMORY_PERCENT not in attributes
119
-
120
-
121
- class TestGetGlobalResourceAttributes:
122
- """Test get_global_resource_attributes function."""
123
-
124
- @patch("agentops.sdk.attributes.get_imported_libraries")
125
- def test_basic_attributes_with_project_id(self, mock_get_libs):
126
- """Test basic attributes with project ID."""
127
- mock_get_libs.return_value = ["requests", "pandas"]
128
-
129
- attributes = get_global_resource_attributes("test-service", project_id="test-project")
130
-
131
- assert ResourceAttributes.SERVICE_NAME in attributes
132
- assert ResourceAttributes.PROJECT_ID in attributes
133
- assert ResourceAttributes.IMPORTED_LIBRARIES in attributes
134
- assert attributes[ResourceAttributes.SERVICE_NAME] == "test-service"
135
- assert attributes[ResourceAttributes.PROJECT_ID] == "test-project"
136
- assert attributes[ResourceAttributes.IMPORTED_LIBRARIES] == ["requests", "pandas"]
137
-
138
- @patch("agentops.sdk.attributes.get_imported_libraries")
139
- def test_basic_attributes_without_project_id(self, mock_get_libs):
140
- """Test basic attributes without project ID."""
141
- mock_get_libs.return_value = ["requests", "pandas"]
142
-
143
- attributes = get_global_resource_attributes("test-service")
144
-
145
- assert ResourceAttributes.SERVICE_NAME in attributes
146
- assert ResourceAttributes.PROJECT_ID not in attributes
147
- assert ResourceAttributes.IMPORTED_LIBRARIES in attributes
148
- assert attributes[ResourceAttributes.SERVICE_NAME] == "test-service"
149
- assert attributes[ResourceAttributes.IMPORTED_LIBRARIES] == ["requests", "pandas"]
150
-
151
- @patch("agentops.sdk.attributes.get_imported_libraries")
152
- def test_no_imported_libraries(self, mock_get_libs):
153
- """Test when no imported libraries are found."""
154
- mock_get_libs.return_value = None
155
-
156
- attributes = get_global_resource_attributes("test-service", project_id="test-project")
157
-
158
- assert ResourceAttributes.SERVICE_NAME in attributes
159
- assert ResourceAttributes.PROJECT_ID in attributes
160
- assert ResourceAttributes.IMPORTED_LIBRARIES not in attributes
161
- assert attributes[ResourceAttributes.SERVICE_NAME] == "test-service"
162
- assert attributes[ResourceAttributes.PROJECT_ID] == "test-project"
163
-
164
- @patch("agentops.sdk.attributes.get_imported_libraries")
165
- def test_empty_imported_libraries(self, mock_get_libs):
166
- """Test when imported libraries list is empty."""
167
- mock_get_libs.return_value = []
168
-
169
- attributes = get_global_resource_attributes("test-service", project_id="test-project")
170
-
171
- assert ResourceAttributes.SERVICE_NAME in attributes
172
- assert ResourceAttributes.PROJECT_ID in attributes
173
- assert ResourceAttributes.IMPORTED_LIBRARIES not in attributes
174
- assert attributes[ResourceAttributes.SERVICE_NAME] == "test-service"
175
- assert attributes[ResourceAttributes.PROJECT_ID] == "test-project"
176
-
177
-
178
- class TestGetTraceAttributes:
179
- """Test get_trace_attributes function."""
180
-
181
- def test_no_tags(self):
182
- """Test when no tags are provided."""
183
- attributes = get_trace_attributes()
184
-
185
- assert attributes == {}
186
-
187
- def test_list_tags(self):
188
- """Test with list of tags."""
189
- tags = ["tag1", "tag2", "tag3"]
190
- attributes = get_trace_attributes(tags)
191
-
192
- assert CoreAttributes.TAGS in attributes
193
- assert attributes[CoreAttributes.TAGS] == ["tag1", "tag2", "tag3"]
194
-
195
- def test_dict_tags(self):
196
- """Test with dictionary of tags."""
197
- tags = {"key1": "value1", "key2": "value2"}
198
- attributes = get_trace_attributes(tags)
199
-
200
- assert "key1" in attributes
201
- assert "key2" in attributes
202
- assert attributes["key1"] == "value1"
203
- assert attributes["key2"] == "value2"
204
-
205
- def test_mixed_dict_tags(self):
206
- """Test with dictionary containing various value types."""
207
- tags = {
208
- "string_key": "string_value",
209
- "int_key": 42,
210
- "float_key": 3.14,
211
- "bool_key": True,
212
- "list_key": [1, 2, 3],
213
- }
214
- attributes = get_trace_attributes(tags)
215
-
216
- assert attributes["string_key"] == "string_value"
217
- assert attributes["int_key"] == 42
218
- assert attributes["float_key"] == 3.14
219
- assert attributes["bool_key"] is True
220
- assert attributes["list_key"] == [1, 2, 3]
221
-
222
- def test_invalid_tags_type(self):
223
- """Test with invalid tags type."""
224
- with patch("agentops.sdk.attributes.logger") as mock_logger:
225
- attributes = get_trace_attributes("invalid_tags")
226
-
227
- assert attributes == {}
228
- mock_logger.warning.assert_called_once()
229
-
230
- def test_none_tags(self):
231
- """Test with None tags."""
232
- attributes = get_trace_attributes(None)
233
-
234
- assert attributes == {}
235
-
236
-
237
- class TestGetSpanAttributes:
238
- """Test get_span_attributes function."""
239
-
240
- def test_basic_span_attributes(self):
241
- """Test basic span attributes."""
242
- attributes = get_span_attributes("test-operation", "test-kind")
243
-
244
- assert SpanAttributes.AGENTOPS_SPAN_KIND in attributes
245
- assert SpanAttributes.OPERATION_NAME in attributes
246
- assert attributes[SpanAttributes.AGENTOPS_SPAN_KIND] == "test-kind"
247
- assert attributes[SpanAttributes.OPERATION_NAME] == "test-operation"
248
- assert SpanAttributes.OPERATION_VERSION not in attributes
249
-
250
- def test_span_attributes_with_version(self):
251
- """Test span attributes with version."""
252
- attributes = get_span_attributes("test-operation", "test-kind", version=1)
253
-
254
- assert SpanAttributes.AGENTOPS_SPAN_KIND in attributes
255
- assert SpanAttributes.OPERATION_NAME in attributes
256
- assert SpanAttributes.OPERATION_VERSION in attributes
257
- assert attributes[SpanAttributes.AGENTOPS_SPAN_KIND] == "test-kind"
258
- assert attributes[SpanAttributes.OPERATION_NAME] == "test-operation"
259
- assert attributes[SpanAttributes.OPERATION_VERSION] == 1
260
-
261
- def test_span_attributes_with_version_zero(self):
262
- """Test span attributes with version zero."""
263
- attributes = get_span_attributes("test-operation", "test-kind", version=0)
264
-
265
- assert SpanAttributes.OPERATION_VERSION in attributes
266
- assert attributes[SpanAttributes.OPERATION_VERSION] == 0
267
-
268
- def test_span_attributes_with_additional_kwargs(self):
269
- """Test span attributes with additional keyword arguments."""
270
- attributes = get_span_attributes(
271
- "test-operation",
272
- "test-kind",
273
- version=1,
274
- custom_key="custom_value",
275
- another_key=42,
276
- )
277
-
278
- assert SpanAttributes.AGENTOPS_SPAN_KIND in attributes
279
- assert SpanAttributes.OPERATION_NAME in attributes
280
- assert SpanAttributes.OPERATION_VERSION in attributes
281
- assert "custom_key" in attributes
282
- assert "another_key" in attributes
283
- assert attributes["custom_key"] == "custom_value"
284
- assert attributes["another_key"] == 42
285
-
286
- def test_span_attributes_overwrite_kwargs(self):
287
- """Test that kwargs can overwrite default attributes."""
288
- attributes = get_span_attributes(
289
- "test-operation",
290
- "test-kind",
291
- version=1,
292
- custom_operation_name="overwritten-name",
293
- custom_span_kind="overwritten-kind",
294
- )
295
-
296
- # kwargs should overwrite the default values
297
- assert attributes["custom_operation_name"] == "overwritten-name"
298
- assert attributes["custom_span_kind"] == "overwritten-kind"
299
- # The original positional arguments should still be set
300
- assert attributes[SpanAttributes.OPERATION_NAME] == "test-operation"
301
- assert attributes[SpanAttributes.AGENTOPS_SPAN_KIND] == "test-kind"
302
-
303
-
304
- class TestGetSessionEndAttributes:
305
- """Test get_session_end_attributes function."""
306
-
307
- def test_session_end_attributes_success(self):
308
- """Test session end attributes with success state."""
309
- attributes = get_session_end_attributes("Success")
310
-
311
- assert SpanAttributes.AGENTOPS_SESSION_END_STATE in attributes
312
- assert attributes[SpanAttributes.AGENTOPS_SESSION_END_STATE] == "Success"
313
-
314
- def test_session_end_attributes_failure(self):
315
- """Test session end attributes with failure state."""
316
- attributes = get_session_end_attributes("Failure")
317
-
318
- assert SpanAttributes.AGENTOPS_SESSION_END_STATE in attributes
319
- assert attributes[SpanAttributes.AGENTOPS_SESSION_END_STATE] == "Failure"
320
-
321
- def test_session_end_attributes_custom_state(self):
322
- """Test session end attributes with custom state."""
323
- attributes = get_session_end_attributes("CustomState")
324
-
325
- assert SpanAttributes.AGENTOPS_SESSION_END_STATE in attributes
326
- assert attributes[SpanAttributes.AGENTOPS_SESSION_END_STATE] == "CustomState"
327
-
328
- def test_session_end_attributes_empty_string(self):
329
- """Test session end attributes with empty string."""
330
- attributes = get_session_end_attributes("")
331
-
332
- assert SpanAttributes.AGENTOPS_SESSION_END_STATE in attributes
333
- assert attributes[SpanAttributes.AGENTOPS_SESSION_END_STATE] == ""
334
-
335
-
336
- class TestAttributesIntegration:
337
- """Integration tests for attributes module."""
338
-
339
- def test_all_functions_work_together(self):
340
- """Test that all attribute functions work together without conflicts."""
341
- # Get system attributes
342
- system_attrs = get_system_resource_attributes()
343
- assert isinstance(system_attrs, dict)
344
-
345
- # Get global attributes
346
- global_attrs = get_global_resource_attributes("test-service", project_id="test-project")
347
- assert isinstance(global_attrs, dict)
348
-
349
- # Get trace attributes
350
- trace_attrs = get_trace_attributes(["tag1", "tag2"])
351
- assert isinstance(trace_attrs, dict)
352
-
353
- # Get span attributes
354
- span_attrs = get_span_attributes("test-operation", "test-kind", version=1)
355
- assert isinstance(span_attrs, dict)
356
-
357
- # Get session end attributes
358
- session_attrs = get_session_end_attributes("Success")
359
- assert isinstance(session_attrs, dict)
360
-
361
- # Verify no key conflicts between different attribute types
362
- all_keys = (
363
- set(system_attrs.keys())
364
- | set(global_attrs.keys())
365
- | set(trace_attrs.keys())
366
- | set(span_attrs.keys())
367
- | set(session_attrs.keys())
368
- )
369
- assert len(all_keys) == len(system_attrs) + len(global_attrs) + len(trace_attrs) + len(span_attrs) + len(
370
- session_attrs
371
- )
372
-
373
- def test_attribute_types_consistency(self):
374
- """Test that all attributes return consistent types."""
375
- # All functions should return dictionaries
376
- assert isinstance(get_system_resource_attributes(), dict)
377
- assert isinstance(get_global_resource_attributes("test"), dict)
378
- assert isinstance(get_trace_attributes(), dict)
379
- assert isinstance(get_span_attributes("test", "test"), dict)
380
- assert isinstance(get_session_end_attributes("test"), dict)
381
-
382
- # All dictionary values should be serializable
383
- import json
384
-
385
- try:
386
- json.dumps(get_system_resource_attributes())
387
- json.dumps(get_global_resource_attributes("test"))
388
- json.dumps(get_trace_attributes())
389
- json.dumps(get_span_attributes("test", "test"))
390
- json.dumps(get_session_end_attributes("test"))
391
- except (TypeError, ValueError) as e:
392
- pytest.fail(f"Attributes are not JSON serializable: {e}")