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,120 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ from typing import Any
5
+
6
+ from acceldata.client.http_client import BaseHttpClient
7
+ from acceldata.client.transient_retry import (
8
+ RetryConfig,
9
+ effective_transient_retry,
10
+ transient_retry_call,
11
+ )
12
+ from acceldata.models.api.catalog.assembly import Assembly
13
+ from acceldata.models.api.catalog.crawler_action_response import CrawlerActionResponse
14
+ from acceldata.models.api.catalog.crawler_status_response import CrawlerStatusResponse
15
+ from acceldata.models.sdk.catalog.asset_source_type import AssetSourceType
16
+ from acceldata.models.sdk.catalog.datasource_resource import DatasourceResource
17
+
18
+ logger = logging.getLogger("sdk")
19
+
20
+
21
+ class DataSourceService:
22
+ def __init__(self, http_client: BaseHttpClient) -> None:
23
+ self._client = http_client
24
+
25
+ def start_crawler(
26
+ self,
27
+ datasource_name: str,
28
+ *,
29
+ transient_retry: RetryConfig | None = None,
30
+ ) -> CrawlerActionResponse:
31
+ """POST to start a crawler run (single request)."""
32
+ cfg = effective_transient_retry(transient_retry, None)
33
+
34
+ def _do() -> CrawlerActionResponse:
35
+ if datasource_name is None or datasource_name == "":
36
+ raise ValueError("datasource name is required")
37
+ url = self._client.catalog_urls.crawl_datasource(datasource_name=datasource_name)
38
+ response = self._client._post(url=url, payload={})
39
+ if isinstance(response, dict):
40
+ data = response.get("data")
41
+ if isinstance(data, dict):
42
+ started = CrawlerActionResponse.from_dict(data)
43
+ if started is None:
44
+ raise TypeError("crawler start returned empty data")
45
+ return started
46
+ raise TypeError(f"Expected dict from crawler start, got {type(response).__name__}")
47
+
48
+ return transient_retry_call(_do, cfg, logger=logger, operation_name="start_crawler")
49
+
50
+ def get_crawler_status(
51
+ self,
52
+ datasource_name: str,
53
+ *,
54
+ transient_retry: RetryConfig | None = None,
55
+ ) -> CrawlerStatusResponse:
56
+ cfg = effective_transient_retry(transient_retry, None)
57
+
58
+ def _do() -> CrawlerStatusResponse:
59
+ if datasource_name is None or datasource_name == "":
60
+ raise ValueError("datasource name is required")
61
+ url = self._client.catalog_urls.crawl_datasource(datasource_name=datasource_name)
62
+ response = self._client._get(url=url)
63
+ logger.debug("Crawler response: %s", response)
64
+ if isinstance(response, dict):
65
+ data = response.get("data")
66
+ if isinstance(data, dict):
67
+ return CrawlerStatusResponse.from_dict(data)
68
+ raise TypeError(f"Expected dict from crawler status, got {type(response).__name__}")
69
+
70
+ return transient_retry_call(_do, cfg, logger=logger, operation_name="get_crawler_status")
71
+
72
+ def get_datasource(
73
+ self,
74
+ assembly_identifier: Any,
75
+ properties: bool = False,
76
+ ) -> DatasourceResource:
77
+ """
78
+ Find a datasource by name or numeric id in the catalog.
79
+
80
+ :param assembly_identifier: Datasource name or id in the catalog.
81
+ :param properties: When True, include assembly property templates in the response.
82
+ """
83
+ url = self._client.catalog_urls.assembly(assembly_identifier, properties=properties)
84
+ response = self._client._get(url=url)
85
+ if not isinstance(response, dict):
86
+ raise TypeError(f"Expected dict from assemblies GET, got {type(response).__name__}")
87
+ raw = response.get("data")
88
+ logger.debug("assemblies response: %s", raw)
89
+ if raw is None:
90
+ raise ValueError("Datasource not found.")
91
+ model = Assembly.from_dict(raw)
92
+ return DatasourceResource(self, model)
93
+
94
+ def get_datasources(
95
+ self,
96
+ source_type: AssetSourceType | None = None,
97
+ ) -> list[DatasourceResource]:
98
+ """
99
+ Find datasources by type in the catalog.
100
+
101
+ :param source_type: Catalog source type filter (optional). Passed as ``sourceType`` query parameter.
102
+ :return: List of datasource resources.
103
+ """
104
+ url = self._client.catalog_urls.datasources()
105
+ params: dict[str, str] | None = None
106
+ if source_type is not None:
107
+ params = {"sourceType": source_type.name}
108
+ response = self._client._get(url=url, params=params)
109
+ if not isinstance(response, dict):
110
+ raise TypeError(f"Expected dict from assemblies list, got {type(response).__name__}")
111
+ raw = response.get("data")
112
+ if raw is None:
113
+ raw = []
114
+ if not isinstance(raw, list):
115
+ raise TypeError(f"Expected list in data, got {type(raw).__name__}")
116
+ return [
117
+ DatasourceResource(self, Assembly.from_dict(item))
118
+ for item in raw
119
+ if isinstance(item, dict)
120
+ ]
@@ -0,0 +1,132 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ from typing import Any
5
+
6
+ from acceldata.client.http_client import BaseHttpClient
7
+ from acceldata.models.api.catalog.analytics_pipeline import AnalyticsPipeline
8
+ from acceldata.models.api.catalog.asset_type import AssetType
9
+ from acceldata.models.api.catalog.connection_type import ConnectionType
10
+ from acceldata.models.api.catalog.source_type import SourceType
11
+
12
+ logger = logging.getLogger("generic_service")
13
+
14
+
15
+ def _asset_types_list_from_response(response: dict[str, Any]) -> list[Any]:
16
+ for key in ("data", "assetTypes"):
17
+ raw = response.get(key)
18
+ if raw is None:
19
+ continue
20
+ if isinstance(raw, (list, tuple)):
21
+ return list(raw)
22
+ raise KeyError(
23
+ "asset-types response must include 'data' or 'assetTypes' with a list"
24
+ )
25
+
26
+
27
+ def _connection_types_list_from_response(response: dict[str, Any]) -> list[Any]:
28
+ for key in ("data", "connectionTypes"):
29
+ raw = response.get(key)
30
+ if raw is None:
31
+ continue
32
+ if isinstance(raw, (list, tuple)):
33
+ return list(raw)
34
+ raise KeyError(
35
+ "connection-types response must include 'data' or 'connectionTypes' with a list"
36
+ )
37
+
38
+
39
+ def _source_types_list_from_response(response: dict[str, Any]) -> list[Any]:
40
+ for key in ("data", "sourceTypes"):
41
+ raw = response.get(key)
42
+ if raw is None:
43
+ continue
44
+ if isinstance(raw, (list, tuple)):
45
+ return list(raw)
46
+ raise KeyError(
47
+ "source-types response must include 'data' or 'sourceTypes' with a list"
48
+ )
49
+
50
+
51
+ class GenericService:
52
+ def __init__(self, http_client: BaseHttpClient) -> None:
53
+ self._client = http_client
54
+
55
+ def get_asset_types(self) -> list[AssetType]:
56
+ url = self._client.catalog_urls.asset_types()
57
+ response = self._client._get(url=url)
58
+ logger.debug("get_asset_types response: %s", response)
59
+ if not isinstance(response, dict):
60
+ raise TypeError(
61
+ "asset-types response must be a JSON object, "
62
+ f"got {type(response).__name__}"
63
+ )
64
+ raw = _asset_types_list_from_response(response)
65
+ result: list[AssetType] = []
66
+ for item in raw:
67
+ if not isinstance(item, dict):
68
+ raise TypeError(
69
+ "each asset type must be a JSON object, "
70
+ f"got {type(item).__name__}"
71
+ )
72
+ result.append(AssetType.from_dict(item))
73
+ return result
74
+
75
+ def get_connection_types(self) -> list[ConnectionType]:
76
+ url = self._client.catalog_urls.connection_types()
77
+ response = self._client._get(url=url)
78
+ if not isinstance(response, dict):
79
+ raise TypeError(
80
+ "connection-types response must be a JSON object, "
81
+ f"got {type(response).__name__}"
82
+ )
83
+ raw = _connection_types_list_from_response(response)
84
+ result: list[ConnectionType] = []
85
+ for item in raw:
86
+ if not isinstance(item, dict):
87
+ raise TypeError(
88
+ "each connection type must be a JSON object, "
89
+ f"got {type(item).__name__}"
90
+ )
91
+ result.append(ConnectionType.from_dict(item))
92
+ return result
93
+
94
+ def get_source_types(self) -> list[SourceType]:
95
+ """
96
+ Description:
97
+ list all sourcetypes in ADOC catalog
98
+ :return: (SourceType) list of sourcetype
99
+ """
100
+ url = self._client.catalog_urls.source_types()
101
+ response = self._client._get(url=url)
102
+ raw = _source_types_list_from_response(response)
103
+ result: list[SourceType] = []
104
+ for item in raw:
105
+ if not isinstance(item, dict):
106
+ raise TypeError(
107
+ "each source type must be a JSON object, "
108
+ f"got {type(item).__name__}"
109
+ )
110
+ result.append(SourceType.from_dict(item))
111
+ return result
112
+
113
+ def get_analysis_pipeline(self, pipeline_identifier: str | int) -> AnalyticsPipeline:
114
+ """GET catalog ``/analytics-pipelines/{id|name}`` and parse the ``pipeline`` object."""
115
+ url = self._client.catalog_urls.analytics_pipeline(pipeline_identifier)
116
+ response = self._client._get(url=url)
117
+ if not isinstance(response, dict):
118
+ raise TypeError(
119
+ "analytics-pipelines response must be a JSON object, "
120
+ f"got {type(response).__name__}"
121
+ )
122
+ inner = response.get("pipeline")
123
+ if inner is None:
124
+ raise KeyError(
125
+ "analytics-pipelines response must include a 'pipeline' object"
126
+ )
127
+ if not isinstance(inner, dict):
128
+ raise TypeError(
129
+ "pipeline must be a JSON object, "
130
+ f"got {type(inner).__name__}"
131
+ )
132
+ return AnalyticsPipeline.from_dict(inner)
@@ -0,0 +1,232 @@
1
+ """Catalog ``markerConfig`` wire ``type`` values and helpers (service / SDK layer).
2
+
3
+ The OpenAPI ``MarkerConfig`` schema is a discriminated union. Each branch payload
4
+ must include a ``type`` string matching
5
+ ``#/components/schemas/MarkerConfig`` discriminator mapping. Use the
6
+ ``*_marker_config`` functions (names mirror the generated classes, e.g.
7
+ :func:`bounds_date_time_marker_config` for :class:`BoundsDateTimeMarkerConfig`) so
8
+ callers do not set that field by hand; for low-level access see
9
+ :func:`marker_type_for` and :data:`API_TYPE_BY_MARKER_CLASS`, and
10
+ :func:`as_marker_config` to normalize values before they are sent on API requests.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from types import MappingProxyType
16
+ from typing import Any, Optional, Type, TypeVar, Union, cast
17
+
18
+ from acceldata.models.api.catalog.bounds_date_time_marker_config import (
19
+ BoundsDateTimeMarkerConfig,
20
+ )
21
+ from acceldata.models.api.catalog.bounds_file_event_marker_config import (
22
+ BoundsFileEventMarkerConfig,
23
+ )
24
+ from acceldata.models.api.catalog.bounds_id_marker_config import BoundsIdMarkerConfig
25
+ from acceldata.models.api.catalog.date_partitioning_marker_config import (
26
+ DatePartitioningMarkerConfig,
27
+ )
28
+ from acceldata.models.api.catalog.date_time_marker_config import DateTimeMarkerConfig
29
+ from acceldata.models.api.catalog.file_marker_config import FileMarkerConfig
30
+ from acceldata.models.api.catalog.id_marker_config import IdMarkerConfig
31
+ from acceldata.models.api.catalog.marker_config import MarkerConfig
32
+ from acceldata.models.api.catalog.marker_config_fallback import MarkerConfigFallback
33
+ from acceldata.models.api.catalog.offset_based_marker_config import (
34
+ OffsetBasedMarkerConfig,
35
+ )
36
+ from acceldata.models.api.catalog.pub_sub_lookback_marker_config import (
37
+ PubSubLookbackMarkerConfig,
38
+ )
39
+ from acceldata.models.api.catalog.pub_sub_timestamp_marker_config import (
40
+ PubSubTimestampMarkerConfig,
41
+ )
42
+ from acceldata.models.api.catalog.timestamp_based_marker_config import (
43
+ TimestampBasedMarkerConfig,
44
+ )
45
+
46
+ # Catalog MarkerConfig oneOf: discriminator propertyName "type" -> $ref
47
+ # (see components/schemas/MarkerConfig in the cleaned spec).
48
+ _WIRE: dict[Type[object], str] = {
49
+ BoundsDateTimeMarkerConfig: "boundDateTime",
50
+ BoundsFileEventMarkerConfig: "boundFileEvent",
51
+ BoundsIdMarkerConfig: "bound",
52
+ DatePartitioningMarkerConfig: "date_partitioned",
53
+ DateTimeMarkerConfig: "datetime",
54
+ FileMarkerConfig: "file",
55
+ IdMarkerConfig: "id",
56
+ OffsetBasedMarkerConfig: "offset",
57
+ PubSubLookbackMarkerConfig: "pubsub_lookback",
58
+ PubSubTimestampMarkerConfig: "pubsub_timestamp",
59
+ TimestampBasedMarkerConfig: "timestamp",
60
+ MarkerConfigFallback: "MarkerConfigFallback",
61
+ }
62
+
63
+ # Read-only: generated class -> wire ``type`` (discriminator) string
64
+ API_TYPE_BY_MARKER_CLASS: Any = MappingProxyType(_WIRE)
65
+
66
+ MMarker = TypeVar("MMarker", bound=object)
67
+
68
+ # Union of all branch models + wrapper for inputs (profiling, and other call sites).
69
+ MarkerConfigInput = Union[
70
+ MarkerConfig,
71
+ BoundsDateTimeMarkerConfig,
72
+ BoundsFileEventMarkerConfig,
73
+ BoundsIdMarkerConfig,
74
+ DatePartitioningMarkerConfig,
75
+ DateTimeMarkerConfig,
76
+ FileMarkerConfig,
77
+ IdMarkerConfig,
78
+ OffsetBasedMarkerConfig,
79
+ PubSubLookbackMarkerConfig,
80
+ PubSubTimestampMarkerConfig,
81
+ TimestampBasedMarkerConfig,
82
+ MarkerConfigFallback,
83
+ ]
84
+
85
+
86
+ def marker_type_for(model_type: type) -> str:
87
+ """Return the API ``type`` string for a given generated *MarkerConfig* class."""
88
+ try:
89
+ return _WIRE[model_type]
90
+ except KeyError as e: # pragma: no cover - guard for SDK misuse
91
+ raise TypeError(
92
+ f"Not a known MarkerConfig branch class: {model_type!r}"
93
+ ) from e
94
+
95
+
96
+ def _build_marker(model_cls: type[MMarker], /, **kwargs: Any) -> MMarker:
97
+ if model_cls not in _WIRE:
98
+ raise TypeError(
99
+ f"Unknown marker model class: {model_cls!r}. "
100
+ "Use a known *MarkerConfig* branch (see API_TYPE_BY_MARKER_CLASS keys)."
101
+ )
102
+ if model_cls is MarkerConfigFallback:
103
+ if "type" not in kwargs:
104
+ raise TypeError(
105
+ "MarkerConfigFallback requires an explicit 'type' "
106
+ "(unknown backend name or the mapping key \"MarkerConfigFallback\")."
107
+ )
108
+ return model_cls(**kwargs) # type: ignore[call-arg, no-any-return]
109
+ wire = _WIRE[cast(Type[object], model_cls)]
110
+ return model_cls(**{**kwargs, "type": wire}) # type: ignore[call-arg, no-any-return]
111
+
112
+
113
+ def date_time_marker_config(**kwargs: Any) -> DateTimeMarkerConfig:
114
+ """Build a :class:`DateTimeMarkerConfig` with the correct API ``type``."""
115
+ return _build_marker(DateTimeMarkerConfig, **kwargs)
116
+
117
+
118
+ def bounds_date_time_marker_config(**kwargs: Any) -> BoundsDateTimeMarkerConfig:
119
+ """Build a :class:`BoundsDateTimeMarkerConfig` with the correct API ``type``."""
120
+ return _build_marker(BoundsDateTimeMarkerConfig, **kwargs)
121
+
122
+
123
+ def bounds_file_event_marker_config(**kwargs: Any) -> BoundsFileEventMarkerConfig:
124
+ """Build a :class:`BoundsFileEventMarkerConfig` with the correct API ``type``."""
125
+ return _build_marker(BoundsFileEventMarkerConfig, **kwargs)
126
+
127
+
128
+ def date_partitioning_marker_config(**kwargs: Any) -> DatePartitioningMarkerConfig:
129
+ """Build a :class:`DatePartitioningMarkerConfig` with the correct API ``type``."""
130
+ return _build_marker(DatePartitioningMarkerConfig, **kwargs)
131
+
132
+
133
+ def file_marker_config(**kwargs: Any) -> FileMarkerConfig:
134
+ """Build a :class:`FileMarkerConfig` with the correct API ``type``."""
135
+ return _build_marker(FileMarkerConfig, **kwargs)
136
+
137
+
138
+ def offset_based_marker_config(**kwargs: Any) -> OffsetBasedMarkerConfig:
139
+ """Build an :class:`OffsetBasedMarkerConfig` with the correct API ``type``."""
140
+ return _build_marker(OffsetBasedMarkerConfig, **kwargs)
141
+
142
+
143
+ def pub_sub_lookback_marker_config(**kwargs: Any) -> PubSubLookbackMarkerConfig:
144
+ """Build a :class:`PubSubLookbackMarkerConfig` with the correct API ``type``."""
145
+ return _build_marker(PubSubLookbackMarkerConfig, **kwargs)
146
+
147
+
148
+ def pub_sub_timestamp_marker_config(**kwargs: Any) -> PubSubTimestampMarkerConfig:
149
+ """Build a :class:`PubSubTimestampMarkerConfig` with the correct API ``type``."""
150
+ return _build_marker(PubSubTimestampMarkerConfig, **kwargs)
151
+
152
+
153
+ def timestamp_based_marker_config(**kwargs: Any) -> TimestampBasedMarkerConfig:
154
+ """Build a :class:`TimestampBasedMarkerConfig` with the correct API ``type``."""
155
+ return _build_marker(TimestampBasedMarkerConfig, **kwargs)
156
+
157
+
158
+ def marker_config_fallback(**kwargs: Any) -> MarkerConfigFallback:
159
+ """Build a :class:`MarkerConfigFallback`; you must pass ``type=`` in ``kwargs``."""
160
+ return _build_marker(MarkerConfigFallback, **kwargs)
161
+
162
+
163
+ def id_marker_config(
164
+ *,
165
+ id_column_name: str,
166
+ base_asset_id: int | None = None,
167
+ initial_offset: int | None = None,
168
+ ) -> IdMarkerConfig:
169
+ """Build an :class:`IdMarkerConfig` with the correct API ``type`` (``"id"``)."""
170
+ mk: dict[str, Any] = {"id_column_name": id_column_name}
171
+ if base_asset_id is not None:
172
+ mk["base_asset_id"] = base_asset_id
173
+ if initial_offset is not None:
174
+ mk["initial_offset"] = initial_offset
175
+ return _build_marker(IdMarkerConfig, **mk)
176
+
177
+
178
+ def bounds_id_marker_config(
179
+ *,
180
+ id_column_name: str,
181
+ from_id: int | None = None,
182
+ to_id: int | None = None,
183
+ base_asset_id: int | None = None,
184
+ ) -> BoundsIdMarkerConfig:
185
+ """Build a :class:`BoundsIdMarkerConfig` with the correct API ``type`` (``"bound"``).
186
+
187
+ For **incremental** profiling on an id column, use :func:`id_marker_config` instead.
188
+ """
189
+ mk: dict[str, Any] = {"id_column_name": id_column_name}
190
+ if base_asset_id is not None:
191
+ mk["base_asset_id"] = base_asset_id
192
+ if from_id is not None:
193
+ mk["from_id"] = from_id
194
+ if to_id is not None:
195
+ mk["to_id"] = to_id
196
+ return _build_marker(BoundsIdMarkerConfig, **mk)
197
+
198
+
199
+ def _apply_canonical_type_if_known(instance: object) -> object:
200
+ t = type(instance)
201
+ if t is MarkerConfigFallback:
202
+ return instance
203
+ wire = _WIRE.get(t)
204
+ if wire is None or getattr(instance, "type", None) == wire:
205
+ return instance
206
+ m = instance
207
+ return m.model_copy(update={"type": wire})
208
+
209
+
210
+ def as_marker_config(value: MarkerConfigInput, /) -> MarkerConfig:
211
+ """Normalize a payload and wrap in :class:`MarkerConfig` (public catalog union type)."""
212
+ if isinstance(value, MarkerConfig):
213
+ inner = value.actual_instance
214
+ if inner is None:
215
+ return value
216
+ updated = _apply_canonical_type_if_known(inner)
217
+ if updated is inner:
218
+ return value
219
+ return MarkerConfig(actual_instance=updated)
220
+ if type(value) in _WIRE and value is not None:
221
+ updated = _apply_canonical_type_if_known(value)
222
+ return MarkerConfig(actual_instance=updated) # type: ignore[arg-type]
223
+ raise TypeError(f"Unsupported marker config value type: {type(value)!r}")
224
+
225
+
226
+ def prepare_marker_config_for_request(
227
+ value: Optional[MarkerConfigInput],
228
+ ) -> Optional[MarkerConfig]:
229
+ """Apply discriminator defaults and return the catalog :class:`MarkerConfig` for HTTP bodies."""
230
+ if value is None:
231
+ return None
232
+ return as_marker_config(value)
@@ -0,0 +1,102 @@
1
+ """Parse pipeline API BigDecimal payloads: structured dicts or plain JSON numbers (non-generated helper)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from decimal import Decimal, InvalidOperation
6
+ from typing import TYPE_CHECKING, Any, Optional
7
+
8
+ from acceldata.models.api.pipeline.big_integer import BigInteger
9
+
10
+ if TYPE_CHECKING:
11
+ from acceldata.models.api.pipeline.big_decimal import BigDecimal
12
+
13
+
14
+ def _decimal_to_unscaled_scale_unsigned(abs_d: Decimal) -> tuple[int, int]:
15
+ if abs_d == 0:
16
+ return 0, 0
17
+ t = abs_d.as_tuple()
18
+ digits_int = int("".join(str(x) for x in t.digits) or "0")
19
+ exp = t.exponent
20
+ if exp >= 0:
21
+ return digits_int * (10**exp), 0
22
+ return digits_int, -exp
23
+
24
+
25
+ def big_decimal_from_json_scalar(val: Any) -> BigDecimal:
26
+ """Build pipeline BigDecimal when the API returns a JSON number or decimal string."""
27
+ from acceldata.models.api.pipeline.big_decimal import BigDecimal
28
+
29
+ if isinstance(val, str):
30
+ try:
31
+ d = Decimal(val.strip())
32
+ except InvalidOperation as exc:
33
+ raise TypeError(f"BigDecimal value is not a valid decimal string: {val!r}") from exc
34
+ elif isinstance(val, bool):
35
+ raise TypeError("BigDecimal value must be a number, not bool")
36
+ elif isinstance(val, int):
37
+ d = Decimal(val)
38
+ elif isinstance(val, float):
39
+ d = Decimal(str(val))
40
+ else:
41
+ raise TypeError(f"BigDecimal value has unsupported type {type(val).__name__}")
42
+
43
+ if not d.is_finite():
44
+ raise TypeError("BigDecimal value must be a finite decimal")
45
+
46
+ sign = -1 if d < 0 else (0 if d == 0 else 1)
47
+ d_abs = abs(d)
48
+ unscaled_mag, scale = _decimal_to_unscaled_scale_unsigned(d_abs)
49
+ int_compact = sign * unscaled_mag
50
+
51
+ if sign == 0:
52
+ bi = BigInteger.model_validate(
53
+ {
54
+ "signum": 0,
55
+ "mag": [],
56
+ "bitCountPlusOne": 1,
57
+ "bitLengthPlusOne": 1,
58
+ "lowestSetBitPlusTwo": 2,
59
+ "firstNonzeroIntNumPlusTwo": 2,
60
+ }
61
+ )
62
+ prec = 1
63
+ s_cache = "0"
64
+ else:
65
+ bl = max(abs(unscaled_mag).bit_length(), 1)
66
+ bi = BigInteger.model_validate(
67
+ {
68
+ "signum": sign,
69
+ "mag": [{"value": unscaled_mag}],
70
+ "bitCountPlusOne": bl + 1,
71
+ "bitLengthPlusOne": bl + 1,
72
+ "lowestSetBitPlusTwo": 2,
73
+ "firstNonzeroIntNumPlusTwo": 2,
74
+ }
75
+ )
76
+ prec = max(len(str(abs(int_compact))), scale + 1 if scale else 1)
77
+ s_cache = format(d, "f")
78
+
79
+ return BigDecimal.model_validate(
80
+ {
81
+ "intVal": bi,
82
+ "scale": scale,
83
+ "precision": prec,
84
+ "stringCache": s_cache,
85
+ "intCompact": int_compact,
86
+ }
87
+ )
88
+
89
+
90
+ def parse_optional_big_decimal_from_api(raw: Any) -> Optional[BigDecimal]:
91
+ """Accept structured BigDecimal JSON, or a plain number/string from the API."""
92
+ from acceldata.models.api.pipeline.big_decimal import BigDecimal
93
+
94
+ if raw is None:
95
+ return None
96
+ if isinstance(raw, BigDecimal):
97
+ return raw
98
+ if isinstance(raw, dict):
99
+ return BigDecimal.from_dict(raw)
100
+ if isinstance(raw, (int, float, str)):
101
+ return big_decimal_from_json_scalar(raw)
102
+ return BigDecimal.from_dict(raw)