agenta 0.52.6__py3-none-any.whl → 0.63.2__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 (271) hide show
  1. agenta/__init__.py +12 -3
  2. agenta/client/__init__.py +4 -4
  3. agenta/client/backend/__init__.py +4 -4
  4. agenta/client/backend/api_keys/client.py +2 -2
  5. agenta/client/backend/billing/client.py +2 -2
  6. agenta/client/backend/billing/raw_client.py +2 -2
  7. agenta/client/backend/client.py +56 -48
  8. agenta/client/backend/core/client_wrapper.py +2 -2
  9. agenta/client/backend/core/file.py +3 -1
  10. agenta/client/backend/core/http_client.py +3 -3
  11. agenta/client/backend/core/pydantic_utilities.py +13 -3
  12. agenta/client/backend/human_evaluations/client.py +2 -2
  13. agenta/client/backend/human_evaluations/raw_client.py +2 -2
  14. agenta/client/backend/organization/client.py +46 -34
  15. agenta/client/backend/organization/raw_client.py +32 -26
  16. agenta/client/backend/raw_client.py +26 -26
  17. agenta/client/backend/testsets/client.py +18 -18
  18. agenta/client/backend/testsets/raw_client.py +30 -30
  19. agenta/client/backend/types/__init__.py +4 -4
  20. agenta/client/backend/types/account_request.py +3 -1
  21. agenta/client/backend/types/account_response.py +3 -1
  22. agenta/client/backend/types/agenta_node_dto.py +3 -1
  23. agenta/client/backend/types/agenta_nodes_response.py +3 -1
  24. agenta/client/backend/types/agenta_root_dto.py +3 -1
  25. agenta/client/backend/types/agenta_roots_response.py +3 -1
  26. agenta/client/backend/types/agenta_tree_dto.py +3 -1
  27. agenta/client/backend/types/agenta_trees_response.py +3 -1
  28. agenta/client/backend/types/aggregated_result.py +3 -1
  29. agenta/client/backend/types/analytics_response.py +3 -1
  30. agenta/client/backend/types/annotation.py +6 -4
  31. agenta/client/backend/types/annotation_create.py +3 -1
  32. agenta/client/backend/types/annotation_edit.py +3 -1
  33. agenta/client/backend/types/annotation_link.py +3 -1
  34. agenta/client/backend/types/annotation_link_response.py +3 -1
  35. agenta/client/backend/types/annotation_query.py +3 -1
  36. agenta/client/backend/types/annotation_query_request.py +3 -1
  37. agenta/client/backend/types/annotation_reference.py +3 -1
  38. agenta/client/backend/types/annotation_references.py +3 -1
  39. agenta/client/backend/types/annotation_response.py +3 -1
  40. agenta/client/backend/types/annotations_response.py +3 -1
  41. agenta/client/backend/types/app.py +3 -1
  42. agenta/client/backend/types/app_variant_response.py +3 -1
  43. agenta/client/backend/types/app_variant_revision.py +3 -1
  44. agenta/client/backend/types/artifact.py +6 -4
  45. agenta/client/backend/types/base_output.py +3 -1
  46. agenta/client/backend/types/body_fetch_workflow_revision.py +3 -1
  47. agenta/client/backend/types/body_import_testset.py +3 -1
  48. agenta/client/backend/types/bucket_dto.py +3 -1
  49. agenta/client/backend/types/collect_status_response.py +3 -1
  50. agenta/client/backend/types/config_db.py +3 -1
  51. agenta/client/backend/types/config_dto.py +3 -1
  52. agenta/client/backend/types/config_response_model.py +3 -1
  53. agenta/client/backend/types/correct_answer.py +3 -1
  54. agenta/client/backend/types/create_app_output.py +3 -1
  55. agenta/client/backend/types/custom_model_settings_dto.py +3 -1
  56. agenta/client/backend/types/custom_provider_dto.py +3 -1
  57. agenta/client/backend/types/custom_provider_kind.py +1 -1
  58. agenta/client/backend/types/custom_provider_settings_dto.py +3 -1
  59. agenta/client/backend/types/delete_evaluation.py +3 -1
  60. agenta/client/backend/types/environment_output.py +3 -1
  61. agenta/client/backend/types/environment_output_extended.py +3 -1
  62. agenta/client/backend/types/environment_revision.py +3 -1
  63. agenta/client/backend/types/error.py +3 -1
  64. agenta/client/backend/types/evaluation.py +3 -1
  65. agenta/client/backend/types/evaluation_scenario.py +3 -1
  66. agenta/client/backend/types/evaluation_scenario_input.py +3 -1
  67. agenta/client/backend/types/evaluation_scenario_output.py +3 -1
  68. agenta/client/backend/types/evaluation_scenario_result.py +3 -1
  69. agenta/client/backend/types/evaluator.py +6 -4
  70. agenta/client/backend/types/evaluator_config.py +6 -4
  71. agenta/client/backend/types/evaluator_flags.py +3 -1
  72. agenta/client/backend/types/evaluator_mapping_output_interface.py +3 -1
  73. agenta/client/backend/types/evaluator_output_interface.py +3 -1
  74. agenta/client/backend/types/evaluator_query.py +3 -1
  75. agenta/client/backend/types/evaluator_query_request.py +3 -1
  76. agenta/client/backend/types/evaluator_request.py +3 -1
  77. agenta/client/backend/types/evaluator_response.py +3 -1
  78. agenta/client/backend/types/evaluators_response.py +3 -1
  79. agenta/client/backend/types/exception_dto.py +3 -1
  80. agenta/client/backend/types/extended_o_tel_tracing_response.py +3 -1
  81. agenta/client/backend/types/get_config_response.py +3 -1
  82. agenta/client/backend/types/header.py +3 -1
  83. agenta/client/backend/types/http_validation_error.py +3 -1
  84. agenta/client/backend/types/human_evaluation.py +3 -1
  85. agenta/client/backend/types/human_evaluation_scenario.py +3 -1
  86. agenta/client/backend/types/human_evaluation_scenario_input.py +3 -1
  87. agenta/client/backend/types/human_evaluation_scenario_output.py +3 -1
  88. agenta/client/backend/types/invite_request.py +3 -1
  89. agenta/client/backend/types/legacy_analytics_response.py +3 -1
  90. agenta/client/backend/types/legacy_data_point.py +3 -1
  91. agenta/client/backend/types/legacy_evaluator.py +3 -1
  92. agenta/client/backend/types/legacy_scope_request.py +3 -1
  93. agenta/client/backend/types/legacy_scopes_response.py +3 -1
  94. agenta/client/backend/types/legacy_subscription_request.py +3 -1
  95. agenta/client/backend/types/legacy_user_request.py +3 -1
  96. agenta/client/backend/types/legacy_user_response.py +3 -1
  97. agenta/client/backend/types/lifecycle_dto.py +3 -1
  98. agenta/client/backend/types/link_dto.py +3 -1
  99. agenta/client/backend/types/list_api_keys_response.py +3 -1
  100. agenta/client/backend/types/llm_run_rate_limit.py +3 -1
  101. agenta/client/backend/types/meta_request.py +3 -1
  102. agenta/client/backend/types/metrics_dto.py +3 -1
  103. agenta/client/backend/types/new_testset.py +3 -1
  104. agenta/client/backend/types/node_dto.py +3 -1
  105. agenta/client/backend/types/o_tel_context_dto.py +3 -1
  106. agenta/client/backend/types/o_tel_event.py +6 -4
  107. agenta/client/backend/types/o_tel_event_dto.py +3 -1
  108. agenta/client/backend/types/o_tel_extra_dto.py +3 -1
  109. agenta/client/backend/types/o_tel_flat_span.py +6 -4
  110. agenta/client/backend/types/o_tel_link.py +6 -4
  111. agenta/client/backend/types/o_tel_link_dto.py +3 -1
  112. agenta/client/backend/types/o_tel_links_response.py +3 -1
  113. agenta/client/backend/types/o_tel_span.py +1 -1
  114. agenta/client/backend/types/o_tel_span_dto.py +3 -1
  115. agenta/client/backend/types/o_tel_spans_tree.py +3 -1
  116. agenta/client/backend/types/o_tel_tracing_data_response.py +3 -1
  117. agenta/client/backend/types/o_tel_tracing_request.py +3 -1
  118. agenta/client/backend/types/o_tel_tracing_response.py +3 -1
  119. agenta/client/backend/types/organization.py +3 -1
  120. agenta/client/backend/types/organization_details.py +3 -1
  121. agenta/client/backend/types/organization_membership_request.py +3 -1
  122. agenta/client/backend/types/organization_output.py +3 -1
  123. agenta/client/backend/types/organization_request.py +3 -1
  124. agenta/client/backend/types/parent_dto.py +3 -1
  125. agenta/client/backend/types/project_membership_request.py +3 -1
  126. agenta/client/backend/types/project_request.py +3 -1
  127. agenta/client/backend/types/project_scope.py +3 -1
  128. agenta/client/backend/types/projects_response.py +3 -1
  129. agenta/client/backend/types/reference.py +6 -4
  130. agenta/client/backend/types/reference_dto.py +3 -1
  131. agenta/client/backend/types/reference_request_model.py +3 -1
  132. agenta/client/backend/types/result.py +3 -1
  133. agenta/client/backend/types/root_dto.py +3 -1
  134. agenta/client/backend/types/scopes_response_model.py +3 -1
  135. agenta/client/backend/types/secret_dto.py +3 -1
  136. agenta/client/backend/types/secret_response_dto.py +3 -1
  137. agenta/client/backend/types/simple_evaluation_output.py +3 -1
  138. agenta/client/backend/types/span_dto.py +6 -4
  139. agenta/client/backend/types/standard_provider_dto.py +3 -1
  140. agenta/client/backend/types/standard_provider_settings_dto.py +3 -1
  141. agenta/client/backend/types/status_dto.py +3 -1
  142. agenta/client/backend/types/tags_request.py +3 -1
  143. agenta/client/backend/types/testcase_response.py +6 -4
  144. agenta/client/backend/types/testset.py +6 -4
  145. agenta/client/backend/types/{test_set_output_response.py → testset_output_response.py} +4 -2
  146. agenta/client/backend/types/testset_request.py +3 -1
  147. agenta/client/backend/types/testset_response.py +3 -1
  148. agenta/client/backend/types/{test_set_simple_response.py → testset_simple_response.py} +4 -2
  149. agenta/client/backend/types/testsets_response.py +3 -1
  150. agenta/client/backend/types/time_dto.py +3 -1
  151. agenta/client/backend/types/tree_dto.py +3 -1
  152. agenta/client/backend/types/update_app_output.py +3 -1
  153. agenta/client/backend/types/user_request.py +3 -1
  154. agenta/client/backend/types/validation_error.py +3 -1
  155. agenta/client/backend/types/workflow_artifact.py +6 -4
  156. agenta/client/backend/types/workflow_data.py +3 -1
  157. agenta/client/backend/types/workflow_flags.py +3 -1
  158. agenta/client/backend/types/workflow_request.py +3 -1
  159. agenta/client/backend/types/workflow_response.py +3 -1
  160. agenta/client/backend/types/workflow_revision.py +6 -4
  161. agenta/client/backend/types/workflow_revision_request.py +3 -1
  162. agenta/client/backend/types/workflow_revision_response.py +3 -1
  163. agenta/client/backend/types/workflow_revisions_response.py +3 -1
  164. agenta/client/backend/types/workflow_variant.py +6 -4
  165. agenta/client/backend/types/workflow_variant_request.py +3 -1
  166. agenta/client/backend/types/workflow_variant_response.py +3 -1
  167. agenta/client/backend/types/workflow_variants_response.py +3 -1
  168. agenta/client/backend/types/workflows_response.py +3 -1
  169. agenta/client/backend/types/workspace.py +3 -1
  170. agenta/client/backend/types/workspace_member_response.py +3 -1
  171. agenta/client/backend/types/workspace_membership_request.py +3 -1
  172. agenta/client/backend/types/workspace_permission.py +3 -1
  173. agenta/client/backend/types/workspace_request.py +3 -1
  174. agenta/client/backend/types/workspace_response.py +3 -1
  175. agenta/client/backend/vault/raw_client.py +4 -4
  176. agenta/client/backend/workspace/client.py +2 -2
  177. agenta/client/client.py +102 -88
  178. agenta/sdk/__init__.py +52 -3
  179. agenta/sdk/agenta_init.py +43 -16
  180. agenta/sdk/assets.py +23 -15
  181. agenta/sdk/context/serving.py +20 -8
  182. agenta/sdk/context/tracing.py +40 -22
  183. agenta/sdk/contexts/__init__.py +0 -0
  184. agenta/sdk/contexts/routing.py +38 -0
  185. agenta/sdk/contexts/running.py +57 -0
  186. agenta/sdk/contexts/tracing.py +86 -0
  187. agenta/sdk/decorators/__init__.py +1 -0
  188. agenta/sdk/decorators/routing.py +284 -0
  189. agenta/sdk/decorators/running.py +692 -98
  190. agenta/sdk/decorators/serving.py +20 -21
  191. agenta/sdk/decorators/tracing.py +176 -131
  192. agenta/sdk/engines/__init__.py +0 -0
  193. agenta/sdk/engines/running/__init__.py +0 -0
  194. agenta/sdk/engines/running/utils.py +17 -0
  195. agenta/sdk/engines/tracing/__init__.py +1 -0
  196. agenta/sdk/engines/tracing/attributes.py +185 -0
  197. agenta/sdk/engines/tracing/conventions.py +49 -0
  198. agenta/sdk/engines/tracing/exporters.py +130 -0
  199. agenta/sdk/engines/tracing/inline.py +1154 -0
  200. agenta/sdk/engines/tracing/processors.py +190 -0
  201. agenta/sdk/engines/tracing/propagation.py +102 -0
  202. agenta/sdk/engines/tracing/spans.py +136 -0
  203. agenta/sdk/engines/tracing/tracing.py +324 -0
  204. agenta/sdk/evaluations/__init__.py +2 -0
  205. agenta/sdk/evaluations/metrics.py +37 -0
  206. agenta/sdk/evaluations/preview/__init__.py +0 -0
  207. agenta/sdk/evaluations/preview/evaluate.py +765 -0
  208. agenta/sdk/evaluations/preview/utils.py +861 -0
  209. agenta/sdk/evaluations/results.py +66 -0
  210. agenta/sdk/evaluations/runs.py +153 -0
  211. agenta/sdk/evaluations/scenarios.py +48 -0
  212. agenta/sdk/litellm/litellm.py +12 -0
  213. agenta/sdk/litellm/mockllm.py +6 -8
  214. agenta/sdk/litellm/mocks/__init__.py +5 -5
  215. agenta/sdk/managers/applications.py +304 -0
  216. agenta/sdk/managers/config.py +2 -2
  217. agenta/sdk/managers/evaluations.py +0 -0
  218. agenta/sdk/managers/evaluators.py +303 -0
  219. agenta/sdk/managers/secrets.py +161 -24
  220. agenta/sdk/managers/shared.py +3 -1
  221. agenta/sdk/managers/testsets.py +441 -0
  222. agenta/sdk/managers/vault.py +3 -3
  223. agenta/sdk/middleware/auth.py +0 -176
  224. agenta/sdk/middleware/config.py +27 -9
  225. agenta/sdk/middleware/vault.py +204 -9
  226. agenta/sdk/middlewares/__init__.py +0 -0
  227. agenta/sdk/middlewares/routing/__init__.py +0 -0
  228. agenta/sdk/middlewares/routing/auth.py +263 -0
  229. agenta/sdk/middlewares/routing/cors.py +30 -0
  230. agenta/sdk/middlewares/routing/otel.py +29 -0
  231. agenta/sdk/middlewares/running/__init__.py +0 -0
  232. agenta/sdk/middlewares/running/normalizer.py +321 -0
  233. agenta/sdk/middlewares/running/resolver.py +161 -0
  234. agenta/sdk/middlewares/running/vault.py +140 -0
  235. agenta/sdk/models/__init__.py +0 -0
  236. agenta/sdk/models/blobs.py +33 -0
  237. agenta/sdk/models/evaluations.py +119 -0
  238. agenta/sdk/models/git.py +126 -0
  239. agenta/sdk/models/shared.py +167 -0
  240. agenta/sdk/models/testsets.py +163 -0
  241. agenta/sdk/models/tracing.py +202 -0
  242. agenta/sdk/models/workflows.py +753 -0
  243. agenta/sdk/tracing/attributes.py +4 -4
  244. agenta/sdk/tracing/exporters.py +67 -17
  245. agenta/sdk/tracing/inline.py +37 -45
  246. agenta/sdk/tracing/processors.py +97 -0
  247. agenta/sdk/tracing/propagation.py +3 -1
  248. agenta/sdk/tracing/spans.py +4 -0
  249. agenta/sdk/tracing/tracing.py +13 -15
  250. agenta/sdk/types.py +222 -22
  251. agenta/sdk/utils/cache.py +1 -1
  252. agenta/sdk/utils/client.py +38 -0
  253. agenta/sdk/utils/helpers.py +13 -12
  254. agenta/sdk/utils/logging.py +18 -78
  255. agenta/sdk/utils/references.py +23 -0
  256. agenta/sdk/workflows/builtin.py +600 -0
  257. agenta/sdk/workflows/configurations.py +22 -0
  258. agenta/sdk/workflows/errors.py +292 -0
  259. agenta/sdk/workflows/handlers.py +1791 -0
  260. agenta/sdk/workflows/interfaces.py +948 -0
  261. agenta/sdk/workflows/sandbox.py +118 -0
  262. agenta/sdk/workflows/utils.py +303 -6
  263. {agenta-0.52.6.dist-info → agenta-0.63.2.dist-info}/METADATA +37 -33
  264. agenta-0.63.2.dist-info/RECORD +421 -0
  265. {agenta-0.52.6.dist-info → agenta-0.63.2.dist-info}/WHEEL +1 -1
  266. agenta/sdk/middleware/adapt.py +0 -253
  267. agenta/sdk/middleware/base.py +0 -40
  268. agenta/sdk/middleware/flags.py +0 -40
  269. agenta/sdk/workflows/types.py +0 -472
  270. agenta-0.52.6.dist-info/RECORD +0 -371
  271. /agenta/sdk/{workflows → engines/running}/registry.py +0 -0
@@ -0,0 +1,190 @@
1
+ from typing import Optional, Dict, List
2
+ from threading import Lock
3
+
4
+ from opentelemetry.baggage import get_all as get_baggage
5
+ from opentelemetry.context import Context
6
+ from opentelemetry.sdk.trace import Span, SpanProcessor
7
+ from opentelemetry.sdk.trace.export import (
8
+ SpanExporter,
9
+ ReadableSpan,
10
+ BatchSpanProcessor,
11
+ )
12
+
13
+ from agenta.sdk.utils.logging import get_module_logger
14
+ from agenta.sdk.engines.tracing.conventions import Reference
15
+
16
+ log = get_module_logger(__name__)
17
+
18
+
19
+ class TraceProcessor(SpanProcessor):
20
+ def __init__(
21
+ self,
22
+ span_exporter: SpanExporter,
23
+ references: Dict[str, str] = None,
24
+ inline: bool = False,
25
+ max_queue_size: int = None,
26
+ schedule_delay_millis: float = None,
27
+ max_export_batch_size: int = None,
28
+ export_timeout_millis: float = None,
29
+ ):
30
+ self.references = references or dict()
31
+ self.inline = inline is True
32
+
33
+ self._registry = dict()
34
+ self._exporter = span_exporter
35
+ self._spans: Dict[int, List[ReadableSpan]] = dict()
36
+
37
+ # --- DISTRIBUTED
38
+ if not self.inline:
39
+ self._delegate = BatchSpanProcessor(
40
+ span_exporter,
41
+ max_queue_size,
42
+ schedule_delay_millis,
43
+ max_export_batch_size,
44
+ export_timeout_millis,
45
+ )
46
+ # --- DISTRIBUTED
47
+
48
+ def on_start(
49
+ self,
50
+ span: Span,
51
+ parent_context: Optional[Context] = None,
52
+ ) -> None:
53
+ for key in self.references.keys():
54
+ span.set_attribute(f"ag.refs.{key}", self.references[key])
55
+
56
+ baggage = get_baggage(parent_context)
57
+
58
+ for key in baggage.keys():
59
+ if key.startswith("ag.refs."):
60
+ _key = key.replace("ag.refs.", "")
61
+ if _key in [_.value for _ in Reference.__members__.values()]:
62
+ span.set_attribute(key, baggage[key])
63
+
64
+ trace_id = span.context.trace_id
65
+ span_id = span.context.span_id
66
+
67
+ self._registry.setdefault(trace_id, {})
68
+ self._registry[trace_id][span_id] = True
69
+
70
+ def on_end(
71
+ self,
72
+ span: ReadableSpan,
73
+ ):
74
+ trace_id = span.context.trace_id
75
+ span_id = span.context.span_id
76
+
77
+ self._spans.setdefault(trace_id, []).append(span)
78
+ self._registry.setdefault(trace_id, {})
79
+ self._registry[trace_id].pop(span_id, None)
80
+
81
+ if not self._registry[trace_id]:
82
+ spans = self._spans.pop(trace_id, [])
83
+ self._registry.pop(trace_id, None)
84
+
85
+ # --- INLINE
86
+ if self.inline:
87
+ self._exporter.export(spans)
88
+ # --- INLINE
89
+
90
+ # --- DISTRIBUTED
91
+ else:
92
+ for span in spans:
93
+ self._delegate.on_end(span)
94
+
95
+ self._delegate.force_flush()
96
+ # --- DISTRIBUTED
97
+
98
+ def force_flush(
99
+ self,
100
+ timeout_millis: int = None,
101
+ ) -> bool:
102
+ # --- INLINE
103
+ if self.inline:
104
+ try:
105
+ ret = self._exporter.force_flush(timeout_millis)
106
+ except: # pylint: disable=bare-except
107
+ ret = True
108
+ # --- INLINE
109
+
110
+ # --- DISTRIBUTED
111
+ else:
112
+ ret = self._delegate.force_flush(timeout_millis)
113
+ # --- DISTRIBUTED
114
+
115
+ if not ret:
116
+ log.warning("Agenta - Skipping export due to timeout.")
117
+
118
+ return ret
119
+
120
+ def shutdown(self) -> None:
121
+ # --- INLINE
122
+ if self.inline:
123
+ self._exporter.shutdown()
124
+ # --- INLINE
125
+
126
+ # --- DISTRIBUTED
127
+ else:
128
+ self._delegate.shutdown()
129
+ # --- DISTRIBUTED
130
+
131
+ def is_ready(
132
+ self,
133
+ trace_id: Optional[int] = None,
134
+ ) -> bool:
135
+ is_ready = True
136
+
137
+ # --- INLINE
138
+ if self.inline:
139
+ try:
140
+ is_ready = self._exporter.is_ready(trace_id)
141
+ except: # pylint: disable=bare-except
142
+ pass
143
+ # --- INLINE
144
+
145
+ return is_ready
146
+
147
+ def fetch(
148
+ self,
149
+ trace_id: Optional[int] = None,
150
+ ) -> Dict[str, ReadableSpan]:
151
+ trace = None
152
+
153
+ # --- INLINE
154
+ if self.inline:
155
+ try:
156
+ trace = self._exporter.fetch(trace_id) # type: ignore
157
+ except: # pylint: disable=bare-except
158
+ pass
159
+ # --- INLINE
160
+
161
+ return trace
162
+
163
+
164
+ # Internal storage for the last ended span context
165
+ _last_ended_span_context = None
166
+ _lock = Lock()
167
+
168
+
169
+ def _set_last_ended(span_ctx) -> None:
170
+ """Set the last ended span context"""
171
+ with _lock:
172
+ global _last_ended_span_context
173
+ _last_ended_span_context = span_ctx
174
+
175
+
176
+ def _get_last_ended():
177
+ """Get the last ended span context"""
178
+ with _lock:
179
+ return _last_ended_span_context
180
+
181
+
182
+ class EndedSpanRecorder(SpanProcessor):
183
+ """Records the last ended span context for later reference.
184
+
185
+ This allows accessing span information even after the span has been ended,
186
+ which is useful for linking annotations to auto-instrumented spans.
187
+ """
188
+
189
+ def on_end(self, span):
190
+ _set_last_ended(span.get_span_context())
@@ -0,0 +1,102 @@
1
+ from typing import Tuple, Optional, Dict, Any
2
+
3
+ from opentelemetry.trace import Span, set_span_in_context, get_current_span
4
+ from opentelemetry.baggage.propagation import W3CBaggagePropagator
5
+ from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
6
+ from opentelemetry.baggage import set_baggage
7
+ from opentelemetry.context import get_current
8
+
9
+ from agenta.sdk.contexts.tracing import TracingContext
10
+
11
+ import agenta as ag
12
+
13
+
14
+ def extract(
15
+ headers: Dict[str, str],
16
+ ) -> Tuple[Optional[str], Optional[Any], Dict[str, str]]:
17
+ # --- Extract credentials --- #
18
+ credentials = None
19
+
20
+ try:
21
+ credentials = (
22
+ headers.get("Authorization") # Uppercase
23
+ or headers.get("authorization") # Lowercase
24
+ or None
25
+ )
26
+
27
+ except: # pylint: disable=bare-except
28
+ pass
29
+
30
+ # --- Extract traceparent --- #
31
+ traceparent = None
32
+
33
+ try:
34
+ _carrier = {
35
+ "traceparent": headers.get("Traceparent") # Uppercase
36
+ or headers.get("traceparent") # Lowercase
37
+ or "",
38
+ }
39
+
40
+ _context = TraceContextTextMapPropagator().extract(_carrier)
41
+
42
+ traceparent = _context
43
+ except: # pylint: disable=bare-except
44
+ pass
45
+
46
+ # --- Extract baggage --- #
47
+ baggage = {}
48
+
49
+ try:
50
+ _carrier = {
51
+ "baggage": headers.get("Baggage") # Uppercase
52
+ or headers.get("baggage") # Lowercase
53
+ or "",
54
+ }
55
+
56
+ _context = W3CBaggagePropagator().extract(_carrier)
57
+
58
+ if _context:
59
+ for partial in _context.values():
60
+ for key, value in partial.items():
61
+ baggage[key] = value
62
+
63
+ except: # pylint: disable=bare-except
64
+ pass
65
+
66
+ # --- #
67
+ return credentials, traceparent, baggage
68
+
69
+
70
+ def inject(
71
+ headers: Optional[Dict[str, str]] = None,
72
+ ) -> Dict[str, str]:
73
+ headers = headers or {}
74
+
75
+ _context = get_current()
76
+
77
+ ctx = TracingContext.get()
78
+
79
+ # --- Inject traceparent --- #
80
+ try:
81
+ TraceContextTextMapPropagator().inject(headers, context=_context)
82
+
83
+ except: # pylint: disable=bare-except
84
+ pass
85
+
86
+ # --- Inject baggage --- #
87
+ try:
88
+ if ctx.baggage:
89
+ for key, value in ctx.baggage.items():
90
+ _context = set_baggage(key, value, context=_context)
91
+
92
+ W3CBaggagePropagator().inject(headers, context=_context)
93
+
94
+ except: # pylint: disable=bare-except
95
+ pass
96
+
97
+ # --- Inject credentials --- #
98
+ if ctx.credentials:
99
+ headers["Authorization"] = ctx.credentials
100
+
101
+ # --- #
102
+ return headers
@@ -0,0 +1,136 @@
1
+ from typing import Optional, Union, Any, Dict
2
+
3
+ from opentelemetry.trace import SpanContext
4
+ from opentelemetry.trace.status import Status, StatusCode
5
+ from opentelemetry.sdk.trace import Span
6
+
7
+ from agenta.sdk.engines.tracing.attributes import serialize
8
+
9
+
10
+ class CustomSpan(Span): # INHERITANCE FOR TYPING ONLY
11
+ def __init__(
12
+ self,
13
+ span: Span,
14
+ ) -> None:
15
+ super().__init__( # INHERITANCE FOR TYPING ONLY
16
+ name=span.name,
17
+ context=span.context,
18
+ parent=span.parent,
19
+ sampler=span._sampler,
20
+ trace_config=span._trace_config,
21
+ resource=span.resource,
22
+ attributes=span.attributes,
23
+ events=span.events,
24
+ links=span.links,
25
+ kind=span.kind,
26
+ span_processor=span._span_processor,
27
+ instrumentation_info=span.instrumentation_info,
28
+ record_exception=span._record_exception,
29
+ set_status_on_exception=span._set_status_on_exception,
30
+ limits=span._limits,
31
+ instrumentation_scope=span.instrumentation_scope,
32
+ )
33
+
34
+ self._span = span
35
+
36
+ ## --- PROXY METHODS --- ##
37
+
38
+ def get_span_context(self):
39
+ return self._span.get_span_context()
40
+
41
+ def is_recording(self) -> bool:
42
+ return self._span.is_recording()
43
+
44
+ def update_name(
45
+ self,
46
+ name: str,
47
+ ) -> None:
48
+ self._span.update_name(name)
49
+
50
+ def set_status(
51
+ self,
52
+ status: Union[Status, StatusCode],
53
+ description: Optional[str] = None,
54
+ ) -> None:
55
+ self._span.set_status(
56
+ status=status,
57
+ description=description,
58
+ )
59
+
60
+ def end(self) -> None:
61
+ self._span.end()
62
+
63
+ ## --- CUSTOM METHODS W/ ATTRIBUTES SERALIZATION --- ##
64
+
65
+ def set_attributes(
66
+ self,
67
+ attributes: Dict[str, Any],
68
+ namespace: Optional[str] = None,
69
+ max_depth: Optional[int] = None,
70
+ ) -> None:
71
+ self._span.set_attributes(
72
+ attributes=serialize(
73
+ namespace=namespace,
74
+ attributes=attributes,
75
+ max_depth=max_depth,
76
+ )
77
+ )
78
+
79
+ def set_attribute(
80
+ self,
81
+ key: str,
82
+ value: Any,
83
+ namespace: Optional[str] = None,
84
+ ) -> None:
85
+ self.set_attributes(
86
+ attributes={key: value},
87
+ namespace=namespace,
88
+ )
89
+
90
+ def add_event(
91
+ self,
92
+ name: str,
93
+ attributes: Optional[Dict[str, Any]] = None,
94
+ timestamp: Optional[int] = None,
95
+ namespace: Optional[str] = None,
96
+ ) -> None:
97
+ self._span.add_event(
98
+ name=name,
99
+ attributes=serialize(
100
+ namespace=namespace,
101
+ attributes=attributes,
102
+ ),
103
+ timestamp=timestamp,
104
+ )
105
+
106
+ def add_link(
107
+ self,
108
+ context: SpanContext,
109
+ attributes: Optional[Dict[str, Any]] = None,
110
+ namespace: Optional[str] = None,
111
+ ) -> None:
112
+ self._span.add_link(
113
+ context=context,
114
+ attributes=serialize(
115
+ namespace=namespace,
116
+ attributes=attributes,
117
+ ),
118
+ )
119
+
120
+ def record_exception(
121
+ self,
122
+ exception: BaseException,
123
+ attributes: Optional[Dict[str, Any]] = None,
124
+ timestamp: Optional[int] = None,
125
+ escaped: bool = False,
126
+ namespace: Optional[str] = None,
127
+ ) -> None:
128
+ self._span.record_exception(
129
+ exception=exception,
130
+ attributes=serialize(
131
+ namespace=namespace,
132
+ attributes=attributes,
133
+ ),
134
+ timestamp=timestamp,
135
+ escaped=escaped,
136
+ )