acceldata-sdk-python 26.7.0__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 (303) hide show
  1. acceldata/__init__.py +7 -0
  2. acceldata/client/__init__.py +0 -0
  3. acceldata/client/adoc_client.py +666 -0
  4. acceldata/client/http_client.py +346 -0
  5. acceldata/client/transient_retry.py +142 -0
  6. acceldata/constants/__init__.py +1 -0
  7. acceldata/constants/constants.py +13 -0
  8. acceldata/exceptions/__init__.py +52 -0
  9. acceldata/exceptions/api_errors.py +85 -0
  10. acceldata/exceptions/exceptions.py +174 -0
  11. acceldata/exceptions/sdk_exceptions.py +98 -0
  12. acceldata/mappers/__init__.py +21 -0
  13. acceldata/mappers/catalog_executions.py +107 -0
  14. acceldata/models/__init__.py +0 -0
  15. acceldata/models/api/catalog/above_configs.py +99 -0
  16. acceldata/models/api/catalog/above_configs_success.py +138 -0
  17. acceldata/models/api/catalog/absolute_configs.py +197 -0
  18. acceldata/models/api/catalog/absolute_configs_fallback.py +101 -0
  19. acceldata/models/api/catalog/absolute_threshold_config.py +105 -0
  20. acceldata/models/api/catalog/analysis_job_context.py +102 -0
  21. acceldata/models/api/catalog/analytics_pipeline.py +385 -0
  22. acceldata/models/api/catalog/analytics_pipeline_endpoint.py +136 -0
  23. acceldata/models/api/catalog/anomaly_config.py +95 -0
  24. acceldata/models/api/catalog/anomaly_details.py +119 -0
  25. acceldata/models/api/catalog/anomaly_threshold_config.py +105 -0
  26. acceldata/models/api/catalog/artifact.py +92 -0
  27. acceldata/models/api/catalog/assembly.py +171 -0
  28. acceldata/models/api/catalog/asset.py +162 -0
  29. acceldata/models/api/catalog/asset_catalog_listing.py +159 -0
  30. acceldata/models/api/catalog/asset_catalog_listing_response.py +102 -0
  31. acceldata/models/api/catalog/asset_label_request.py +96 -0
  32. acceldata/models/api/catalog/asset_progress.py +96 -0
  33. acceldata/models/api/catalog/asset_progress_details.py +117 -0
  34. acceldata/models/api/catalog/asset_tag.py +124 -0
  35. acceldata/models/api/catalog/asset_tag_info.py +140 -0
  36. acceldata/models/api/catalog/asset_tag_request.py +95 -0
  37. acceldata/models/api/catalog/asset_tag_response.py +96 -0
  38. acceldata/models/api/catalog/asset_tags_response.py +102 -0
  39. acceldata/models/api/catalog/asset_type.py +96 -0
  40. acceldata/models/api/catalog/auto_anomaly_feature_analysis.py +160 -0
  41. acceldata/models/api/catalog/auto_anomaly_item_execution.py +133 -0
  42. acceldata/models/api/catalog/auto_anomaly_meta_data.py +162 -0
  43. acceldata/models/api/catalog/auto_anomaly_rule_execution.py +102 -0
  44. acceldata/models/api/catalog/auto_anomaly_summary.py +124 -0
  45. acceldata/models/api/catalog/backing_asset.py +126 -0
  46. acceldata/models/api/catalog/below_configs.py +99 -0
  47. acceldata/models/api/catalog/big_decimal.py +100 -0
  48. acceldata/models/api/catalog/big_integer.py +98 -0
  49. acceldata/models/api/catalog/bounds_date_time_marker_config.py +110 -0
  50. acceldata/models/api/catalog/bounds_file_event_marker_config.py +108 -0
  51. acceldata/models/api/catalog/bounds_id_marker_config.py +96 -0
  52. acceldata/models/api/catalog/catalog_asset_meta_data.py +128 -0
  53. acceldata/models/api/catalog/changes_by_config.py +105 -0
  54. acceldata/models/api/catalog/column_mapping.py +139 -0
  55. acceldata/models/api/catalog/column_metadata.py +90 -0
  56. acceldata/models/api/catalog/column_metric_with_anomaly_details.py +119 -0
  57. acceldata/models/api/catalog/column_variable.py +111 -0
  58. acceldata/models/api/catalog/composite_policy_execution.py +102 -0
  59. acceldata/models/api/catalog/composite_policy_item_execution.py +104 -0
  60. acceldata/models/api/catalog/connection.py +118 -0
  61. acceldata/models/api/catalog/connection_test_result.py +106 -0
  62. acceldata/models/api/catalog/connection_type.py +90 -0
  63. acceldata/models/api/catalog/connection_types_response.py +96 -0
  64. acceldata/models/api/catalog/crawler.py +88 -0
  65. acceldata/models/api/catalog/crawler_action_response.py +90 -0
  66. acceldata/models/api/catalog/crawler_execution.py +147 -0
  67. acceldata/models/api/catalog/crawler_execution_response.py +102 -0
  68. acceldata/models/api/catalog/crawler_status_response.py +90 -0
  69. acceldata/models/api/catalog/create_profile.py +194 -0
  70. acceldata/models/api/catalog/custom_sql_config.py +121 -0
  71. acceldata/models/api/catalog/data_bricks_spark_resource_config.py +104 -0
  72. acceldata/models/api/catalog/data_cadence_rule.py +236 -0
  73. acceldata/models/api/catalog/data_cadence_rule_details.py +125 -0
  74. acceldata/models/api/catalog/data_cadence_rule_execution.py +102 -0
  75. acceldata/models/api/catalog/data_cadence_rule_item.py +104 -0
  76. acceldata/models/api/catalog/data_cadence_rule_item_execution.py +158 -0
  77. acceldata/models/api/catalog/data_cadence_rule_response.py +98 -0
  78. acceldata/models/api/catalog/data_drift_execution.py +102 -0
  79. acceldata/models/api/catalog/data_drift_item_execution.py +121 -0
  80. acceldata/models/api/catalog/data_quality_engine.py +90 -0
  81. acceldata/models/api/catalog/data_quality_execution.py +106 -0
  82. acceldata/models/api/catalog/data_quality_rule.py +323 -0
  83. acceldata/models/api/catalog/data_quality_rule_details.py +186 -0
  84. acceldata/models/api/catalog/data_quality_rule_response.py +120 -0
  85. acceldata/models/api/catalog/data_quality_rules_response.py +102 -0
  86. acceldata/models/api/catalog/databricks_compute_config.py +113 -0
  87. acceldata/models/api/catalog/dataplane_engine.py +105 -0
  88. acceldata/models/api/catalog/dataplane_health_metrics.py +101 -0
  89. acceldata/models/api/catalog/dataplane_job.py +216 -0
  90. acceldata/models/api/catalog/dataplane_job_status.py +113 -0
  91. acceldata/models/api/catalog/dataplane_request.py +96 -0
  92. acceldata/models/api/catalog/dataproc_compute_config.py +106 -0
  93. acceldata/models/api/catalog/dataproc_spark_resource_config.py +104 -0
  94. acceldata/models/api/catalog/date_based_partition_marker_config.py +116 -0
  95. acceldata/models/api/catalog/date_partitioning_marker_config.py +113 -0
  96. acceldata/models/api/catalog/date_time_marker_config.py +109 -0
  97. acceldata/models/api/catalog/day_month_year_based_partition_marker_config.py +124 -0
  98. acceldata/models/api/catalog/decreased_by_config.py +105 -0
  99. acceldata/models/api/catalog/delete_artifact_response.py +88 -0
  100. acceldata/models/api/catalog/dq_rule_execution.py +248 -0
  101. acceldata/models/api/catalog/drift.py +121 -0
  102. acceldata/models/api/catalog/enable_rule_request.py +88 -0
  103. acceldata/models/api/catalog/engine.py +90 -0
  104. acceldata/models/api/catalog/execution_cancellation_response.py +92 -0
  105. acceldata/models/api/catalog/execution_response.py +144 -0
  106. acceldata/models/api/catalog/execution_result.py +126 -0
  107. acceldata/models/api/catalog/executions_response.py +102 -0
  108. acceldata/models/api/catalog/failed_asset_detail.py +90 -0
  109. acceldata/models/api/catalog/failed_summary.py +98 -0
  110. acceldata/models/api/catalog/file.py +94 -0
  111. acceldata/models/api/catalog/file_marker_config.py +99 -0
  112. acceldata/models/api/catalog/generic_config_fallback.py +101 -0
  113. acceldata/models/api/catalog/generic_execution.py +221 -0
  114. acceldata/models/api/catalog/generic_rule_execution.py +137 -0
  115. acceldata/models/api/catalog/global_storage_config_dto.py +172 -0
  116. acceldata/models/api/catalog/hosted_dp_deployment_response.py +98 -0
  117. acceldata/models/api/catalog/id_marker_config.py +94 -0
  118. acceldata/models/api/catalog/increased_by_config.py +105 -0
  119. acceldata/models/api/catalog/item.py +160 -0
  120. acceldata/models/api/catalog/item_execution.py +192 -0
  121. acceldata/models/api/catalog/item_segment.py +131 -0
  122. acceldata/models/api/catalog/job_schedule.py +118 -0
  123. acceldata/models/api/catalog/job_spec.py +96 -0
  124. acceldata/models/api/catalog/kubernetes_metrics.py +91 -0
  125. acceldata/models/api/catalog/label.py +97 -0
  126. acceldata/models/api/catalog/livy_compute_config.py +103 -0
  127. acceldata/models/api/catalog/livy_spark_resource_config.py +106 -0
  128. acceldata/models/api/catalog/look_back_config.py +90 -0
  129. acceldata/models/api/catalog/manual_tag_request.py +92 -0
  130. acceldata/models/api/catalog/mapping.py +97 -0
  131. acceldata/models/api/catalog/marker.py +88 -0
  132. acceldata/models/api/catalog/marker_config.py +349 -0
  133. acceldata/models/api/catalog/marker_config_fallback.py +101 -0
  134. acceldata/models/api/catalog/meta.py +92 -0
  135. acceldata/models/api/catalog/meta_data.py +92 -0
  136. acceldata/models/api/catalog/meta_data_item.py +94 -0
  137. acceldata/models/api/catalog/mini_profile_request.py +112 -0
  138. acceldata/models/api/catalog/notification_payload.py +114 -0
  139. acceldata/models/api/catalog/offset_based_marker_config.py +97 -0
  140. acceldata/models/api/catalog/operational_config.py +92 -0
  141. acceldata/models/api/catalog/pattern_configuration.py +90 -0
  142. acceldata/models/api/catalog/pipe_line_request.py +92 -0
  143. acceldata/models/api/catalog/pipeline_compute_config.py +110 -0
  144. acceldata/models/api/catalog/policy_execution_marker_config.py +94 -0
  145. acceldata/models/api/catalog/policy_execution_request.py +229 -0
  146. acceldata/models/api/catalog/policy_group.py +114 -0
  147. acceldata/models/api/catalog/policy_transform_udf.py +113 -0
  148. acceldata/models/api/catalog/process_metrics.py +91 -0
  149. acceldata/models/api/catalog/profile_anomaly_details_response.py +109 -0
  150. acceldata/models/api/catalog/profile_anomaly_item_execution.py +127 -0
  151. acceldata/models/api/catalog/profile_anomaly_rule_execution.py +102 -0
  152. acceldata/models/api/catalog/profile_anomaly_rule_item.py +109 -0
  153. acceldata/models/api/catalog/profile_cancellation_response.py +92 -0
  154. acceldata/models/api/catalog/profile_request.py +211 -0
  155. acceldata/models/api/catalog/profile_request_response.py +92 -0
  156. acceldata/models/api/catalog/property_template.py +178 -0
  157. acceldata/models/api/catalog/property_templates.py +123 -0
  158. acceldata/models/api/catalog/pub_sub_lookback_marker_config.py +96 -0
  159. acceldata/models/api/catalog/pub_sub_timestamp_marker_config.py +108 -0
  160. acceldata/models/api/catalog/quality_rule.py +381 -0
  161. acceldata/models/api/catalog/quality_rule_execution_metrics.py +114 -0
  162. acceldata/models/api/catalog/quality_rule_with_latest_execution.py +115 -0
  163. acceldata/models/api/catalog/range_configs.py +109 -0
  164. acceldata/models/api/catalog/reconciliation_item.py +102 -0
  165. acceldata/models/api/catalog/reconciliation_item_execution.py +157 -0
  166. acceldata/models/api/catalog/reconciliation_rule.py +339 -0
  167. acceldata/models/api/catalog/reconciliation_rule_details.py +225 -0
  168. acceldata/models/api/catalog/reconciliation_rule_execution.py +102 -0
  169. acceldata/models/api/catalog/reconciliation_rule_response.py +98 -0
  170. acceldata/models/api/catalog/reconciliation_rules_response.py +102 -0
  171. acceldata/models/api/catalog/relative_config.py +197 -0
  172. acceldata/models/api/catalog/relative_config_fallback.py +101 -0
  173. acceldata/models/api/catalog/relative_threshold_config.py +111 -0
  174. acceldata/models/api/catalog/root_cause_analysis.py +108 -0
  175. acceldata/models/api/catalog/rule_execution.py +327 -0
  176. acceldata/models/api/catalog/rule_execution_result.py +90 -0
  177. acceldata/models/api/catalog/rule_item_result.py +125 -0
  178. acceldata/models/api/catalog/rule_meta_data.py +94 -0
  179. acceldata/models/api/catalog/rule_spark_sql_dynamic_filter_variable_mapping.py +100 -0
  180. acceldata/models/api/catalog/rule_tag.py +101 -0
  181. acceldata/models/api/catalog/rule_threshold_configuration.py +236 -0
  182. acceldata/models/api/catalog/rule_threshold_configuration_fallback.py +101 -0
  183. acceldata/models/api/catalog/rules_with_latest_execution_response.py +102 -0
  184. acceldata/models/api/catalog/sample_data_api_response.py +122 -0
  185. acceldata/models/api/catalog/schema_drift_item_execution.py +131 -0
  186. acceldata/models/api/catalog/schema_drift_rule_execution.py +102 -0
  187. acceldata/models/api/catalog/secret_manager_configuration.py +90 -0
  188. acceldata/models/api/catalog/secret_manager_configuration_with_option.py +98 -0
  189. acceldata/models/api/catalog/security_config.py +90 -0
  190. acceldata/models/api/catalog/segment_metric_json.py +142 -0
  191. acceldata/models/api/catalog/segments_analysis.py +145 -0
  192. acceldata/models/api/catalog/short_segment.py +97 -0
  193. acceldata/models/api/catalog/simple_quality_rule_response.py +92 -0
  194. acceldata/models/api/catalog/snapshot_data.py +117 -0
  195. acceldata/models/api/catalog/source_model.py +90 -0
  196. acceldata/models/api/catalog/source_type.py +100 -0
  197. acceldata/models/api/catalog/source_types_response.py +102 -0
  198. acceldata/models/api/catalog/spark_job_status.py +113 -0
  199. acceldata/models/api/catalog/spark_resource_config.py +114 -0
  200. acceldata/models/api/catalog/standard_response_assembly.py +92 -0
  201. acceldata/models/api/catalog/standard_response_crawler_action_response.py +92 -0
  202. acceldata/models/api/catalog/standard_response_crawler_status_response.py +92 -0
  203. acceldata/models/api/catalog/standard_response_delete_artifact_response.py +92 -0
  204. acceldata/models/api/catalog/standard_response_list.py +96 -0
  205. acceldata/models/api/catalog/standard_response_map.py +88 -0
  206. acceldata/models/api/catalog/standard_response_meta_data.py +92 -0
  207. acceldata/models/api/catalog/standard_response_mini_profile_request.py +92 -0
  208. acceldata/models/api/catalog/standard_response_profile_request.py +92 -0
  209. acceldata/models/api/catalog/start_profiling_request.py +92 -0
  210. acceldata/models/api/catalog/tag_domain.py +116 -0
  211. acceldata/models/api/catalog/threshold_breach_details.py +101 -0
  212. acceldata/models/api/catalog/time_based_config.py +92 -0
  213. acceldata/models/api/catalog/time_based_threshold_config.py +105 -0
  214. acceldata/models/api/catalog/timestamp_based_marker_config.py +115 -0
  215. acceldata/models/api/catalog/udf_variable.py +97 -0
  216. acceldata/models/api/catalog/yunikorn_compute_config.py +133 -0
  217. acceldata/models/api/catalog/yunikorn_spark_resource_config.py +154 -0
  218. acceldata/models/api/pipeline/big_decimal.py +100 -0
  219. acceldata/models/api/pipeline/big_integer.py +98 -0
  220. acceldata/models/api/pipeline/child_span_response.py +96 -0
  221. acceldata/models/api/pipeline/create_span_event.py +109 -0
  222. acceldata/models/api/pipeline/edge.py +108 -0
  223. acceldata/models/api/pipeline/event_alert_object.py +95 -0
  224. acceldata/models/api/pipeline/generic_config_fallback.py +101 -0
  225. acceldata/models/api/pipeline/identifier.py +146 -0
  226. acceldata/models/api/pipeline/job_request.py +130 -0
  227. acceldata/models/api/pipeline/meta.py +107 -0
  228. acceldata/models/api/pipeline/meta_data.py +92 -0
  229. acceldata/models/api/pipeline/metric.py +103 -0
  230. acceldata/models/api/pipeline/node.py +201 -0
  231. acceldata/models/api/pipeline/node_response.py +92 -0
  232. acceldata/models/api/pipeline/notification_payload.py +114 -0
  233. acceldata/models/api/pipeline/pipeline.py +152 -0
  234. acceldata/models/api/pipeline/pipeline_baseline_metric.py +92 -0
  235. acceldata/models/api/pipeline/pipeline_details.py +118 -0
  236. acceldata/models/api/pipeline/pipeline_details_response.py +102 -0
  237. acceldata/models/api/pipeline/pipeline_input_request.py +92 -0
  238. acceldata/models/api/pipeline/pipeline_listing_info.py +118 -0
  239. acceldata/models/api/pipeline/pipeline_response.py +92 -0
  240. acceldata/models/api/pipeline/pipeline_run.py +136 -0
  241. acceldata/models/api/pipeline/pipeline_run_request.py +92 -0
  242. acceldata/models/api/pipeline/pipeline_runs_response.py +102 -0
  243. acceldata/models/api/pipeline/pipeline_summary.py +98 -0
  244. acceldata/models/api/pipeline/pipelines_listing_response.py +102 -0
  245. acceldata/models/api/pipeline/policy_summary.py +102 -0
  246. acceldata/models/api/pipeline/span.py +115 -0
  247. acceldata/models/api/pipeline/span_event.py +114 -0
  248. acceldata/models/api/pipeline/span_event_request.py +92 -0
  249. acceldata/models/api/pipeline/span_event_response.py +92 -0
  250. acceldata/models/api/pipeline/span_request.py +94 -0
  251. acceldata/models/api/pipeline/spans_response.py +96 -0
  252. acceldata/models/api/pipeline/tag.py +97 -0
  253. acceldata/models/sdk/__init__.py +0 -0
  254. acceldata/models/sdk/catalog/__init__.py +105 -0
  255. acceldata/models/sdk/catalog/asset_resource.py +112 -0
  256. acceldata/models/sdk/catalog/asset_source_type.py +59 -0
  257. acceldata/models/sdk/catalog/custom_asset_metadata.py +11 -0
  258. acceldata/models/sdk/catalog/datasource_resource.py +88 -0
  259. acceldata/models/sdk/catalog/executor.py +524 -0
  260. acceldata/models/sdk/catalog/policy_execution_request.py +114 -0
  261. acceldata/models/sdk/catalog/policy_execution_type.py +16 -0
  262. acceldata/models/sdk/catalog/policy_filter.py +94 -0
  263. acceldata/models/sdk/catalog/policy_rule_resources.py +388 -0
  264. acceldata/models/sdk/catalog/profile_request_resource.py +77 -0
  265. acceldata/models/sdk/catalog/profiling.py +82 -0
  266. acceldata/models/sdk/catalog/profiling_configuration_error.py +5 -0
  267. acceldata/models/sdk/pipeline/__init__.py +62 -0
  268. acceldata/models/sdk/pipeline/create_job_input.py +108 -0
  269. acceldata/models/sdk/pipeline/create_pipeline_input_request.py +72 -0
  270. acceldata/models/sdk/pipeline/events/__init__.py +5 -0
  271. acceldata/models/sdk/pipeline/events/generic_event.py +31 -0
  272. acceldata/models/sdk/pipeline/events/log_event.py +34 -0
  273. acceldata/models/sdk/pipeline/events/span_event.py +8 -0
  274. acceldata/models/sdk/pipeline/pipeline_resource.py +171 -0
  275. acceldata/models/sdk/pipeline/pipeline_run_input.py +84 -0
  276. acceldata/models/sdk/pipeline/pipeline_run_resource.py +208 -0
  277. acceldata/models/sdk/pipeline/pipeline_source_type.py +20 -0
  278. acceldata/models/sdk/pipeline/span_resource.py +327 -0
  279. acceldata/openapi_deserialization_patches.py +161 -0
  280. acceldata/openapi_repr_patches.py +62 -0
  281. acceldata/services/__init__.py +0 -0
  282. acceldata/services/api_timestamp.py +31 -0
  283. acceldata/services/asset_service.py +651 -0
  284. acceldata/services/datasource_service.py +120 -0
  285. acceldata/services/generic_service.py +132 -0
  286. acceldata/services/marker_config.py +232 -0
  287. acceldata/services/pipeline_big_decimal_api.py +102 -0
  288. acceldata/services/pipeline_response_parse.py +209 -0
  289. acceldata/services/pipeline_service.py +494 -0
  290. acceldata/services/rule_service.py +620 -0
  291. acceldata/urls/__init__.py +1 -0
  292. acceldata/urls/catalog_urls.py +137 -0
  293. acceldata/urls/pipeline_urls.py +55 -0
  294. acceldata/utils/__init__.py +6 -0
  295. acceldata/utils/datetime_utils.py +16 -0
  296. acceldata/utils/operation_ack.py +22 -0
  297. acceldata/utils/span_helpers.py +95 -0
  298. acceldata/utils/time_range_utils.py +90 -0
  299. acceldata_sdk_python-26.7.0.dist-info/METADATA +26 -0
  300. acceldata_sdk_python-26.7.0.dist-info/RECORD +303 -0
  301. acceldata_sdk_python-26.7.0.dist-info/WHEEL +5 -0
  302. acceldata_sdk_python-26.7.0.dist-info/licenses/LICENSE +22 -0
  303. acceldata_sdk_python-26.7.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,208 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ from dataclasses import replace
5
+ from datetime import datetime
6
+ from typing import Any, Dict, Optional
7
+
8
+ from acceldata.models.api.pipeline.pipeline_details_response import PipelineDetailsResponse
9
+ from acceldata.models.api.pipeline.node import Node
10
+ from acceldata.models.api.pipeline.pipeline_run import PipelineRun
11
+ from acceldata.models.api.pipeline.spans_response import SpansResponse
12
+ from acceldata.models.sdk.pipeline.create_job_input import CreateJobInput, build_create_job_payload
13
+ from acceldata.models.sdk.pipeline.pipeline_run_input import (
14
+ PipelineRunInput,
15
+ PipelineRunResult,
16
+ PipelineRunStatus,
17
+ )
18
+ from acceldata.utils.span_helpers import ensure_span_for_job, span_create_payload
19
+ from acceldata.models.sdk.pipeline.span_resource import SpanResource, wrap_fetched_span
20
+ from acceldata.services.pipeline_service import PipelineService
21
+
22
+ logger = logging.getLogger("pipeline_run_resource")
23
+
24
+
25
+ class PipelineRunResource:
26
+ """
27
+ Customer-facing pipeline run operations that wrap :class:`PipelineRun` without modifying it.
28
+
29
+ The wrapped :class:`PipelineRun` is :attr:`pipeline_run`; use :meth:`to_dict` for a wire view.
30
+ """
31
+
32
+ def __init__(self, model: PipelineRun, service: PipelineService) -> None:
33
+ self._model = model
34
+ self._service = service
35
+
36
+ @property
37
+ def pipeline_run(self) -> PipelineRun:
38
+ return self._model
39
+
40
+ def to_dict(self) -> Dict[str, Any]:
41
+ return self._model.to_dict()
42
+
43
+ @property
44
+ def id(self) -> Optional[int]:
45
+ return self._model.id
46
+
47
+ def __repr__(self) -> str:
48
+ return f"PipelineRunResource(model={self._model!r})"
49
+
50
+ def _require_pipeline_id(self) -> int:
51
+ if self._model.pipeline_id is None:
52
+ raise ValueError("Pipeline id is required for this operation")
53
+ return int(self._model.pipeline_id)
54
+
55
+ def _require_pipeline_run_id(self) -> int:
56
+ if self._model.id is None:
57
+ raise ValueError("Pipeline run id is required for this operation")
58
+ return int(self._model.id)
59
+
60
+ def _require_version_id(self) -> int:
61
+ if self._model.version_id is None:
62
+ raise ValueError("Pipeline run version id is required for this operation")
63
+ return int(self._model.version_id)
64
+
65
+ def update_pipeline_run(
66
+ self,
67
+ request: PipelineRunInput | None = None,
68
+ *,
69
+ context_data: Optional[dict[str, Any]] = None,
70
+ continuation_id: Optional[str] = None,
71
+ started_at: Optional[datetime] = None,
72
+ finished_at: Optional[datetime] = None,
73
+ result: Optional[PipelineRunResult] = None,
74
+ status: Optional[PipelineRunStatus] = None,
75
+ ) -> PipelineRunResource:
76
+ base = request or PipelineRunInput()
77
+ eff_context = context_data if context_data is not None else base.context_data
78
+ eff_continuation = continuation_id if continuation_id is not None else base.continuation_id
79
+ eff_started = started_at if started_at is not None else base.started_at
80
+ eff_finished = finished_at if finished_at is not None else base.finished_at
81
+ eff_result = (
82
+ result
83
+ if result is not None
84
+ else (base.result if base.result is not None else PipelineRunResult.SUCCESS)
85
+ )
86
+ eff_status = (
87
+ status
88
+ if status is not None
89
+ else (base.status if base.status is not None else PipelineRunStatus.COMPLETED)
90
+ )
91
+ vid = self._model.version_id
92
+ run = self._service.update_pipeline_run(
93
+ self._require_pipeline_run_id(),
94
+ pipeline_id=self._require_pipeline_id(),
95
+ result=eff_result,
96
+ status=eff_status,
97
+ version_id=int(vid) if vid is not None else None,
98
+ context_data=eff_context,
99
+ continuation_id=eff_continuation,
100
+ started_at=eff_started,
101
+ finished_at=eff_finished,
102
+ )
103
+ self._model = run
104
+ return self
105
+
106
+ def create_job(self, job: CreateJobInput) -> Node:
107
+ if not job.uid or not job.name:
108
+ raise ValueError(
109
+ "To create a job, uid and name are required"
110
+ )
111
+ effective_run_id = job.pipeline_run_id
112
+ if effective_run_id is None:
113
+ effective_run_id = self._require_pipeline_run_id()
114
+ elif effective_run_id != self._require_pipeline_run_id():
115
+ raise ValueError(
116
+ "job.pipeline_run_id must match this pipeline run when set"
117
+ )
118
+ job_for_payload = replace(job, pipeline_run_id=effective_run_id)
119
+ pipeline_id = self._require_pipeline_id()
120
+ vid = self._model.version_id
121
+ if vid is None:
122
+ resolved = self._service.get_pipeline_run(pipeline_run_id=effective_run_id)
123
+ vid = resolved.version_id
124
+ payload = build_create_job_payload(
125
+ job_for_payload,
126
+ version_id=int(vid) if vid is not None else None,
127
+ )
128
+ node_response = self._service.create_job(payload, pipeline_id)
129
+
130
+ if job.bounded_by_span:
131
+ if job.span_uid is None:
132
+ raise ValueError(
133
+ "When bounded_by_span is True, span_uid is required"
134
+ )
135
+ ensure_span_for_job(
136
+ self._service,
137
+ pipeline_run_id=effective_run_id,
138
+ span_uid=job.span_uid,
139
+ job_uid=job.uid,
140
+ created_at=job.span_created_at,
141
+ updated_at=job.span_updated_at,
142
+ )
143
+ return node_response.node
144
+
145
+ # Creates the root span which belongs to the whole pipeline run tracking.
146
+ def create_root_span(
147
+ self,
148
+ uid: str,
149
+ *,
150
+ associated_job_uids: Optional[list[str]] = None,
151
+ with_explicit_time: bool = False,
152
+ created_at: Optional[datetime] = None,
153
+ updated_at: Optional[datetime] = None,
154
+ ) -> SpanResource:
155
+ """
156
+ Create a span for this pipeline run (root span when ``parent_span_id`` is ``None``).
157
+
158
+ Returns the created :class:`~acceldata.models.sdk.pipeline.span_resource.SpanResource`.
159
+
160
+ ``with_explicit_time`` is accepted for compatibility with the earlier Python SDK; span timing is
161
+ server-defined by the API.
162
+
163
+ Pass ``created_at`` / ``updated_at`` to set span record timestamps on create (earlier SDK
164
+ ``createdAt`` on the span payload); use with explicit-time span lifecycle control.
165
+ """
166
+ if not uid:
167
+ raise ValueError("span uid is required")
168
+ pr_id = self._require_pipeline_run_id()
169
+ jobs = list(associated_job_uids or [])
170
+ res = self._service.create_span(
171
+ pr_id,
172
+ span_create_payload(
173
+ pipeline_run_id=pr_id,
174
+ uid=uid,
175
+ associated_job_uids=jobs,
176
+ created_at=created_at,
177
+ updated_at=updated_at,
178
+ ),
179
+ )
180
+
181
+ return SpanResource(
182
+ pipeline_service=self._service,
183
+ span=res,
184
+ new_span=True,
185
+ with_explicit_time=with_explicit_time,
186
+ )
187
+
188
+ def get_root_span(self) -> Optional[SpanResource]:
189
+ """Return the root :class:`~acceldata.models.sdk.pipeline.span_resource.SpanResource`, if any."""
190
+ return self._service.get_root_span(self._require_pipeline_run_id())
191
+
192
+ def get_details(self) -> PipelineDetailsResponse:
193
+ """
194
+ Description:
195
+ Get pipeline graph details for this run (nodes, edges).
196
+ :return: :class:`~acceldata.models.api.pipeline.pipeline_details_response.PipelineDetailsResponse`
197
+ """
198
+ response = self._service.get_run_details(pipeline_id=self._require_pipeline_id(),
199
+ version_id=self._require_version_id())
200
+ return response
201
+
202
+ def get_spans(self) -> SpansResponse:
203
+ response = self._service.get_spans(self._require_pipeline_run_id())
204
+ return response
205
+
206
+ def get_span(self, span_identity: str) -> SpanResource:
207
+ s = self._service.get_span(self._require_pipeline_run_id(), span_identity=span_identity)
208
+ return wrap_fetched_span(self._service, s)
@@ -0,0 +1,20 @@
1
+ # coding: utf-8
2
+ """``Pipeline.sourceType`` values (aligned with the generated :class:`~acceldata.models.api.pipeline.pipeline.Pipeline` schema)."""
3
+
4
+ from __future__ import annotations
5
+
6
+ from enum import Enum
7
+
8
+
9
+ class PipelineSourceType(str, Enum):
10
+ """How the pipeline is orchestrated in the data plane (API wire values)."""
11
+
12
+ AIRFLOW = "AIRFLOW"
13
+ AZURE_DATA_FACTORY = "AZURE_DATA_FACTORY"
14
+ TRINO = "TRINO"
15
+ OTHERS = "OTHERS"
16
+ AUTOSYS = "AUTOSYS"
17
+ SPARK = "SPARK"
18
+ DBT = "DBT"
19
+ FIVETRAN = "FIVETRAN"
20
+ SNAPLOGIC = "SNAPLOGIC"
@@ -0,0 +1,327 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ from datetime import datetime
5
+ from enum import Enum
6
+ from typing import TYPE_CHECKING, Any, List, Optional
7
+
8
+ from acceldata.models.api.pipeline.create_span_event import CreateSpanEvent
9
+ from acceldata.models.api.pipeline.span import Span
10
+ from acceldata.models.api.pipeline.span_event import SpanEvent
11
+ from acceldata.models.api.pipeline.span_event_request import SpanEventRequest
12
+ from acceldata.utils.span_helpers import (
13
+ normalize_span_event_created_at,
14
+ span_create_payload,
15
+ )
16
+ from acceldata.utils.operation_ack import ack_failure
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+ if TYPE_CHECKING:
21
+ from acceldata.services.pipeline_service import PipelineService
22
+
23
+
24
+ class SpanEventType(str, Enum):
25
+ """Pipeline span event ``eventUid`` values (control plane)."""
26
+
27
+ SPAN_START = "SPAN.START"
28
+ SPAN_END = "SPAN.END"
29
+ SPAN_ABORTED = "SPAN.ABORTED"
30
+ SPAN_FAILED = "SPAN.FAILED"
31
+ LOG = "LOG"
32
+
33
+
34
+ class SpanContextStatus(str, Enum):
35
+ """Lifecycle state strings on :class:`~acceldata.models.api.pipeline.span.Span`."""
36
+
37
+ INITIALIZED = "INITIALIZED"
38
+ STARTED = "STARTED"
39
+ ABORTED = "ABORTED"
40
+ FINISHED = "FINISHED"
41
+ FAILED = "FAILED"
42
+
43
+
44
+ _TERMINAL_SPAN_STATUSES = frozenset(
45
+ {
46
+ "ABORTED",
47
+ "FINISHED",
48
+ "SKIPPED",
49
+ "ERRORED",
50
+ }
51
+ )
52
+
53
+
54
+ class SpanResource:
55
+ """
56
+ Resource wrapper for pipeline span lifecycle.
57
+
58
+ Emits span lifecycle events and creates child spans for a pipeline run. Uses generated API models
59
+ (:class:`~acceldata.models.api.pipeline.span.Span`,
60
+ :class:`~acceldata.models.api.pipeline.span_event.SpanEvent`) and delegates HTTP
61
+ to :class:`~acceldata.services.pipeline_service.PipelineService`.
62
+
63
+ Construction is side-effect free: creating this resource does not emit ``SPAN.START``.
64
+ Call :meth:`start` explicitly when the span should begin.
65
+ """
66
+
67
+ def __init__(
68
+ self,
69
+ *,
70
+ pipeline_service: PipelineService,
71
+ span: Span,
72
+ parent: Optional[SpanResource] = None,
73
+ new_span: Optional[bool] = None,
74
+ with_explicit_time: bool = False,
75
+ ) -> None:
76
+ if span is None:
77
+ raise ValueError("span is required")
78
+ self._pipeline_service = pipeline_service
79
+ self._model = span
80
+ self.parent = parent
81
+ self.children: list[SpanResource] = []
82
+
83
+ if new_span is None:
84
+ new_span = False
85
+ self.new_span = new_span
86
+
87
+ logger.debug(
88
+ "SpanResource init with_explicit_time=%s (no implicit start)",
89
+ with_explicit_time,
90
+ )
91
+
92
+ @property
93
+ def span(self) -> Span:
94
+ return self._model
95
+
96
+ def __repr__(self) -> str:
97
+ return f"SpanResource(model={self._model!r})"
98
+
99
+ def to_dict(self) -> dict[str, Any]:
100
+ return self._model.to_dict()
101
+
102
+ @property
103
+ def uid(self) -> str:
104
+ return self._model.uid
105
+
106
+ @property
107
+ def id(self) -> Optional[int]:
108
+ return self._model.id
109
+
110
+ def _status_upper(self) -> str:
111
+ return (self._model.status or "").upper()
112
+
113
+ def _require_span_id(self) -> int:
114
+ if self._model.id is None:
115
+ raise ValueError("span id is required for this operation")
116
+ return int(self._model.id)
117
+
118
+ def _require_pipeline_run_id(self) -> int:
119
+ if self._model.pipeline_run_id is None:
120
+ raise ValueError("pipelineRunId is required for this operation")
121
+ return int(self._model.pipeline_run_id)
122
+
123
+ def is_span_finished(self) -> bool:
124
+ st = self._status_upper()
125
+ if st in _TERMINAL_SPAN_STATUSES:
126
+ ack_failure(
127
+ logger,
128
+ "span_event",
129
+ "span_already_terminal",
130
+ status=st,
131
+ span_uid=self._model.uid,
132
+ )
133
+ return True
134
+ return False
135
+
136
+ def _emit(
137
+ self,
138
+ event_uid: str,
139
+ *,
140
+ context_data: Optional[dict[str, Any]] = None,
141
+ created_at: Optional[datetime] = None,
142
+ log_data: Optional[str] = None,
143
+ ) -> SpanEvent:
144
+ """
145
+ Emit a span lifecycle or custom event through the pipeline service.
146
+
147
+ :param event_uid: Event uid, similar to event type (normalized for the API).
148
+ :param log_data: Log data for the event.
149
+ :param context_data: Optional context data map.
150
+ :param created_at: Optional explicit wall-clock time for the span event. If not set,
151
+ the server applies its default (typically the receive time).
152
+ :return: :class:`~acceldata.models.api.pipeline.span_event.SpanEvent`
153
+ for the created event.
154
+
155
+ ``span_id`` is taken from the wrapped model; requests use :attr:`_pipeline_service`.
156
+ """
157
+ created_at = normalize_span_event_created_at(created_at)
158
+ svc = self._pipeline_service
159
+ req = SpanEventRequest(
160
+ # Use API aliases for compatibility with generated models that may
161
+ # not allow population by field name (snake_case).
162
+ event=CreateSpanEvent(
163
+ eventUid=event_uid,
164
+ spanId=self._require_span_id(),
165
+ contextData=context_data,
166
+ createdAt=created_at,
167
+ logData=log_data,
168
+ )
169
+ )
170
+ return svc.create_span_event(req)
171
+
172
+ def start(
173
+ self,
174
+ context_data: Optional[dict[str, Any]] = None,
175
+ created_at: Optional[datetime] = None,
176
+ ) -> Optional[SpanEvent]:
177
+ if self.is_span_finished():
178
+ return None
179
+
180
+ if self._status_upper() == SpanContextStatus.STARTED.value and created_at is None:
181
+ ack_failure(logger, "span_start", "already_started", span_uid=self._model.uid)
182
+ return None
183
+ event_res = self._emit(
184
+ SpanEventType.SPAN_START.value,
185
+ context_data=context_data,
186
+ created_at=created_at,
187
+ )
188
+ self._model = self._model.model_copy(update={"status": SpanContextStatus.STARTED.value})
189
+ return event_res
190
+
191
+ def end(
192
+ self,
193
+ context_data: Optional[dict[str, Any]] = None,
194
+ created_at: Optional[datetime] = None,
195
+ ) -> Optional[SpanEvent]:
196
+ if self.is_span_finished():
197
+ return None
198
+ if self._status_upper() != SpanContextStatus.STARTED.value:
199
+ ack_failure(logger, "span_end", "not_started", span_uid=self._model.uid)
200
+ return None
201
+ event_res = self._emit(
202
+ SpanEventType.SPAN_END.value,
203
+ context_data=context_data,
204
+ created_at=created_at,
205
+ )
206
+ self._model = self._model.model_copy(update={"status": SpanContextStatus.FINISHED.value})
207
+ return event_res
208
+
209
+ def abort(
210
+ self,
211
+ context_data: Optional[dict[str, Any]] = None,
212
+ created_at: Optional[datetime] = None,
213
+ ) -> Optional[SpanEvent]:
214
+ if self.is_span_finished():
215
+ return None
216
+ if self._status_upper() != SpanContextStatus.STARTED.value:
217
+ ack_failure(logger, "span_abort", "not_started", span_uid=self._model.uid)
218
+ return None
219
+ event_res = self._emit(
220
+ SpanEventType.SPAN_ABORTED.value,
221
+ context_data=context_data,
222
+ created_at=created_at,
223
+ )
224
+ self._model = self._model.model_copy(update={"status": SpanContextStatus.ABORTED.value})
225
+ return event_res
226
+
227
+ def failed(
228
+ self,
229
+ context_data: Optional[dict[str, Any]] = None,
230
+ created_at: Optional[datetime] = None,
231
+ ) -> Optional[SpanEvent]:
232
+ if self.is_span_finished():
233
+ return None
234
+ if self._status_upper() != SpanContextStatus.STARTED.value:
235
+ ack_failure(logger, "span_failed", "not_started", span_uid=self._model.uid)
236
+ return None
237
+ event_res = self._emit(
238
+ SpanEventType.SPAN_FAILED.value,
239
+ context_data=context_data,
240
+ created_at=created_at,
241
+ )
242
+ # Span status for a failed run uses ERRORED (see Span.status description).
243
+ self._model = self._model.model_copy(update={"status": "ERRORED"})
244
+ return event_res
245
+
246
+ def send_event(self, span_event: Any) -> Optional[SpanEvent]:
247
+ """Send a custom event; ``span_event`` must expose ``event_uid`` and optional context/log fields."""
248
+ if self.is_span_finished():
249
+ return None
250
+ if self._status_upper() != SpanContextStatus.STARTED.value:
251
+ ack_failure(logger, "span_send_event", "not_started", span_uid=self._model.uid)
252
+ return None
253
+ event_uid = getattr(span_event, "event_uid", None)
254
+ if not event_uid:
255
+ raise ValueError("span_event.event_uid is required")
256
+ log_data = getattr(span_event, "log_data", None)
257
+ return self._emit(
258
+ str(event_uid),
259
+ context_data=getattr(span_event, "context_data", None),
260
+ created_at=getattr(span_event, "created_at", None),
261
+ log_data=log_data,
262
+ )
263
+
264
+ def create_child_span(
265
+ self,
266
+ uid: str,
267
+ associated_job_uids: Optional[List[str]] = None,
268
+ with_explicit_time: bool = False,
269
+ created_at: Optional[datetime] = None,
270
+ updated_at: Optional[datetime] = None,
271
+ ) -> SpanResource:
272
+ if not uid:
273
+ raise ValueError("To create a child span, uid is required")
274
+ if associated_job_uids is not None and not isinstance(associated_job_uids, list):
275
+ raise TypeError("associated_job_uids must be a list")
276
+ jobs = list(associated_job_uids or [])
277
+ svc = self._pipeline_service
278
+ pr_id = self._require_pipeline_run_id()
279
+ parent_id = self._require_span_id()
280
+ payload = span_create_payload(
281
+ pipeline_run_id=pr_id,
282
+ uid=uid,
283
+ associated_job_uids=jobs,
284
+ parent_span_id=parent_id,
285
+ created_at=created_at,
286
+ updated_at=updated_at,
287
+ )
288
+ res = svc.create_span(pr_id, payload)
289
+ child = SpanResource(
290
+ pipeline_service=svc,
291
+ span=res,
292
+ parent=self,
293
+ new_span=True,
294
+ )
295
+ logger.debug("create_child_span with_explicit_time=%s", with_explicit_time)
296
+ self.children.append(child)
297
+ return child
298
+
299
+ def has_children(self) -> bool:
300
+ return len(self.get_child_spans()) > 0
301
+
302
+ def get_child_spans(self) -> list[SpanResource]:
303
+ raw = self._pipeline_service.get_child_spans(self._require_span_id())
304
+ return [wrap_fetched_span(self._pipeline_service, s, parent=self) for s in raw]
305
+
306
+ def is_root(self) -> bool:
307
+ return self.parent is None
308
+
309
+
310
+ def wrap_fetched_span(
311
+ pipeline_service: PipelineService,
312
+ span: Span,
313
+ *,
314
+ parent: Optional[SpanResource] = None,
315
+ ) -> SpanResource:
316
+ """
317
+ Build a :class:`SpanResource` for a span returned from GET APIs (root / by uid).
318
+
319
+ Does not emit lifecycle events on construction; use :meth:`~SpanResource.start` /
320
+ :meth:`~SpanResource.end` as needed.
321
+ """
322
+ return SpanResource(
323
+ pipeline_service=pipeline_service,
324
+ span=span,
325
+ parent=parent,
326
+ new_span=False,
327
+ )