hatchet-sdk 0.46.1__py3-none-any.whl → 1.0.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. hatchet_sdk/__init__.py +25 -16
  2. hatchet_sdk/client.py +14 -39
  3. hatchet_sdk/clients/admin.py +203 -362
  4. hatchet_sdk/clients/dispatcher/action_listener.py +106 -84
  5. hatchet_sdk/clients/dispatcher/dispatcher.py +21 -21
  6. hatchet_sdk/clients/event_ts.py +23 -10
  7. hatchet_sdk/clients/events.py +96 -99
  8. hatchet_sdk/clients/rest/__init__.py +24 -0
  9. hatchet_sdk/clients/rest/api/__init__.py +2 -0
  10. hatchet_sdk/clients/rest/api/task_api.py +2174 -0
  11. hatchet_sdk/clients/rest/api/workflow_runs_api.py +638 -106
  12. hatchet_sdk/clients/rest/api_client.py +1 -1
  13. hatchet_sdk/clients/rest/configuration.py +8 -1
  14. hatchet_sdk/clients/rest/exceptions.py +21 -0
  15. hatchet_sdk/clients/rest/models/__init__.py +22 -0
  16. hatchet_sdk/clients/rest/models/tenant.py +4 -0
  17. hatchet_sdk/clients/rest/models/tenant_version.py +37 -0
  18. hatchet_sdk/clients/rest/models/update_tenant_request.py +7 -0
  19. hatchet_sdk/clients/rest/models/v1_cancel_task_request.py +104 -0
  20. hatchet_sdk/clients/rest/models/v1_dag_children.py +102 -0
  21. hatchet_sdk/clients/rest/models/v1_replay_task_request.py +104 -0
  22. hatchet_sdk/clients/rest/models/v1_task.py +174 -0
  23. hatchet_sdk/clients/rest/models/v1_task_event.py +118 -0
  24. hatchet_sdk/clients/rest/models/v1_task_event_list.py +110 -0
  25. hatchet_sdk/clients/rest/models/v1_task_event_type.py +55 -0
  26. hatchet_sdk/clients/rest/models/v1_task_filter.py +106 -0
  27. hatchet_sdk/clients/rest/models/v1_task_point_metric.py +92 -0
  28. hatchet_sdk/clients/rest/models/v1_task_point_metrics.py +100 -0
  29. hatchet_sdk/clients/rest/models/v1_task_run_metric.py +88 -0
  30. hatchet_sdk/clients/rest/models/v1_task_run_status.py +40 -0
  31. hatchet_sdk/clients/rest/models/v1_task_status.py +40 -0
  32. hatchet_sdk/clients/rest/models/v1_task_summary.py +212 -0
  33. hatchet_sdk/clients/rest/models/v1_task_summary_list.py +110 -0
  34. hatchet_sdk/clients/rest/models/v1_workflow_run.py +171 -0
  35. hatchet_sdk/clients/rest/models/v1_workflow_run_details.py +145 -0
  36. hatchet_sdk/clients/rest/models/v1_workflow_type.py +37 -0
  37. hatchet_sdk/clients/rest/models/workflow_run_shape_item_for_workflow_run_details.py +99 -0
  38. hatchet_sdk/clients/rest/rest.py +37 -26
  39. hatchet_sdk/clients/rest/tenacity_utils.py +1 -1
  40. hatchet_sdk/clients/rest_client.py +141 -116
  41. hatchet_sdk/clients/run_event_listener.py +66 -60
  42. hatchet_sdk/clients/workflow_listener.py +77 -64
  43. hatchet_sdk/config.py +117 -0
  44. hatchet_sdk/connection.py +27 -13
  45. hatchet_sdk/context/__init__.py +0 -1
  46. hatchet_sdk/context/context.py +143 -202
  47. hatchet_sdk/features/cron.py +43 -57
  48. hatchet_sdk/features/scheduled.py +60 -74
  49. hatchet_sdk/hatchet.py +192 -195
  50. hatchet_sdk/labels.py +4 -6
  51. hatchet_sdk/metadata.py +1 -1
  52. hatchet_sdk/opentelemetry/instrumentor.py +112 -35
  53. hatchet_sdk/rate_limit.py +9 -18
  54. hatchet_sdk/token.py +13 -9
  55. hatchet_sdk/utils/aio_utils.py +0 -40
  56. hatchet_sdk/utils/proto_enums.py +54 -0
  57. hatchet_sdk/utils/typing.py +9 -1
  58. hatchet_sdk/v0/__init__.py +251 -0
  59. hatchet_sdk/v0/client.py +119 -0
  60. hatchet_sdk/v0/clients/admin.py +541 -0
  61. hatchet_sdk/v0/clients/dispatcher/action_listener.py +422 -0
  62. hatchet_sdk/v0/clients/dispatcher/dispatcher.py +204 -0
  63. hatchet_sdk/v0/clients/event_ts.py +28 -0
  64. hatchet_sdk/v0/clients/events.py +182 -0
  65. hatchet_sdk/v0/clients/rest/__init__.py +307 -0
  66. hatchet_sdk/v0/clients/rest/api/__init__.py +19 -0
  67. hatchet_sdk/v0/clients/rest/api/api_token_api.py +858 -0
  68. hatchet_sdk/v0/clients/rest/api/default_api.py +2259 -0
  69. hatchet_sdk/v0/clients/rest/api/event_api.py +2548 -0
  70. hatchet_sdk/v0/clients/rest/api/github_api.py +331 -0
  71. hatchet_sdk/v0/clients/rest/api/healthcheck_api.py +483 -0
  72. hatchet_sdk/v0/clients/rest/api/log_api.py +449 -0
  73. hatchet_sdk/v0/clients/rest/api/metadata_api.py +728 -0
  74. hatchet_sdk/v0/clients/rest/api/rate_limits_api.py +423 -0
  75. hatchet_sdk/v0/clients/rest/api/slack_api.py +577 -0
  76. hatchet_sdk/v0/clients/rest/api/sns_api.py +872 -0
  77. hatchet_sdk/v0/clients/rest/api/step_run_api.py +2202 -0
  78. hatchet_sdk/v0/clients/rest/api/tenant_api.py +4430 -0
  79. hatchet_sdk/v0/clients/rest/api/user_api.py +2888 -0
  80. hatchet_sdk/v0/clients/rest/api/worker_api.py +858 -0
  81. hatchet_sdk/v0/clients/rest/api/workflow_api.py +6312 -0
  82. hatchet_sdk/v0/clients/rest/api/workflow_run_api.py +1932 -0
  83. hatchet_sdk/v0/clients/rest/api/workflow_runs_api.py +610 -0
  84. hatchet_sdk/v0/clients/rest/api_client.py +759 -0
  85. hatchet_sdk/v0/clients/rest/api_response.py +22 -0
  86. hatchet_sdk/v0/clients/rest/configuration.py +611 -0
  87. hatchet_sdk/v0/clients/rest/exceptions.py +200 -0
  88. hatchet_sdk/v0/clients/rest/models/__init__.py +274 -0
  89. hatchet_sdk/v0/clients/rest/models/accept_invite_request.py +83 -0
  90. hatchet_sdk/v0/clients/rest/models/api_error.py +102 -0
  91. hatchet_sdk/v0/clients/rest/models/api_errors.py +100 -0
  92. hatchet_sdk/v0/clients/rest/models/api_meta.py +144 -0
  93. hatchet_sdk/v0/clients/rest/models/api_meta_auth.py +85 -0
  94. hatchet_sdk/v0/clients/rest/models/api_meta_integration.py +88 -0
  95. hatchet_sdk/v0/clients/rest/models/api_meta_posthog.py +90 -0
  96. hatchet_sdk/v0/clients/rest/models/api_resource_meta.py +98 -0
  97. hatchet_sdk/v0/clients/rest/models/api_token.py +105 -0
  98. hatchet_sdk/v0/clients/rest/models/bulk_create_event_request.py +100 -0
  99. hatchet_sdk/v0/clients/rest/models/bulk_create_event_response.py +110 -0
  100. hatchet_sdk/v0/clients/rest/models/cancel_event_request.py +85 -0
  101. hatchet_sdk/v0/clients/rest/models/cancel_step_run_request.py +83 -0
  102. hatchet_sdk/v0/clients/rest/models/concurrency_limit_strategy.py +39 -0
  103. hatchet_sdk/v0/clients/rest/models/create_api_token_request.py +92 -0
  104. hatchet_sdk/v0/clients/rest/models/create_api_token_response.py +83 -0
  105. hatchet_sdk/v0/clients/rest/models/create_cron_workflow_trigger_request.py +98 -0
  106. hatchet_sdk/v0/clients/rest/models/create_event_request.py +95 -0
  107. hatchet_sdk/v0/clients/rest/models/create_pull_request_from_step_run.py +83 -0
  108. hatchet_sdk/v0/clients/rest/models/create_sns_integration_request.py +85 -0
  109. hatchet_sdk/v0/clients/rest/models/create_tenant_alert_email_group_request.py +83 -0
  110. hatchet_sdk/v0/clients/rest/models/create_tenant_invite_request.py +86 -0
  111. hatchet_sdk/v0/clients/rest/models/create_tenant_request.py +84 -0
  112. hatchet_sdk/v0/clients/rest/models/cron_workflows.py +131 -0
  113. hatchet_sdk/v0/clients/rest/models/cron_workflows_list.py +110 -0
  114. hatchet_sdk/v0/clients/rest/models/cron_workflows_method.py +37 -0
  115. hatchet_sdk/v0/clients/rest/models/cron_workflows_order_by_field.py +37 -0
  116. hatchet_sdk/v0/clients/rest/models/event.py +143 -0
  117. hatchet_sdk/v0/clients/rest/models/event_data.py +83 -0
  118. hatchet_sdk/v0/clients/rest/models/event_key_list.py +98 -0
  119. hatchet_sdk/v0/clients/rest/models/event_list.py +110 -0
  120. hatchet_sdk/v0/clients/rest/models/event_order_by_direction.py +37 -0
  121. hatchet_sdk/v0/clients/rest/models/event_order_by_field.py +36 -0
  122. hatchet_sdk/v0/clients/rest/models/event_update_cancel200_response.py +85 -0
  123. hatchet_sdk/v0/clients/rest/models/event_workflow_run_summary.py +116 -0
  124. hatchet_sdk/v0/clients/rest/models/events.py +110 -0
  125. hatchet_sdk/v0/clients/rest/models/get_step_run_diff_response.py +100 -0
  126. hatchet_sdk/v0/clients/rest/models/github_app_installation.py +107 -0
  127. hatchet_sdk/v0/clients/rest/models/github_branch.py +86 -0
  128. hatchet_sdk/v0/clients/rest/models/github_repo.py +86 -0
  129. hatchet_sdk/v0/clients/rest/models/info_get_version200_response.py +83 -0
  130. hatchet_sdk/v0/clients/rest/models/job.py +132 -0
  131. hatchet_sdk/v0/clients/rest/models/job_run.py +176 -0
  132. hatchet_sdk/v0/clients/rest/models/job_run_status.py +41 -0
  133. hatchet_sdk/v0/clients/rest/models/link_github_repository_request.py +106 -0
  134. hatchet_sdk/v0/clients/rest/models/list_api_tokens_response.py +110 -0
  135. hatchet_sdk/v0/clients/rest/models/list_github_app_installations_response.py +112 -0
  136. hatchet_sdk/v0/clients/rest/models/list_pull_requests_response.py +100 -0
  137. hatchet_sdk/v0/clients/rest/models/list_slack_webhooks.py +110 -0
  138. hatchet_sdk/v0/clients/rest/models/list_sns_integrations.py +110 -0
  139. hatchet_sdk/v0/clients/rest/models/log_line.py +94 -0
  140. hatchet_sdk/v0/clients/rest/models/log_line_level.py +39 -0
  141. hatchet_sdk/v0/clients/rest/models/log_line_list.py +110 -0
  142. hatchet_sdk/v0/clients/rest/models/log_line_order_by_direction.py +37 -0
  143. hatchet_sdk/v0/clients/rest/models/log_line_order_by_field.py +36 -0
  144. hatchet_sdk/v0/clients/rest/models/pagination_response.py +95 -0
  145. hatchet_sdk/v0/clients/rest/models/pull_request.py +112 -0
  146. hatchet_sdk/v0/clients/rest/models/pull_request_state.py +37 -0
  147. hatchet_sdk/v0/clients/rest/models/queue_metrics.py +97 -0
  148. hatchet_sdk/v0/clients/rest/models/rate_limit.py +117 -0
  149. hatchet_sdk/v0/clients/rest/models/rate_limit_list.py +110 -0
  150. hatchet_sdk/v0/clients/rest/models/rate_limit_order_by_direction.py +37 -0
  151. hatchet_sdk/v0/clients/rest/models/rate_limit_order_by_field.py +38 -0
  152. hatchet_sdk/v0/clients/rest/models/recent_step_runs.py +118 -0
  153. hatchet_sdk/v0/clients/rest/models/reject_invite_request.py +83 -0
  154. hatchet_sdk/v0/clients/rest/models/replay_event_request.py +85 -0
  155. hatchet_sdk/v0/clients/rest/models/replay_workflow_runs_request.py +85 -0
  156. hatchet_sdk/v0/clients/rest/models/replay_workflow_runs_response.py +100 -0
  157. hatchet_sdk/v0/clients/rest/models/rerun_step_run_request.py +83 -0
  158. hatchet_sdk/v0/clients/rest/models/schedule_workflow_run_request.py +92 -0
  159. hatchet_sdk/v0/clients/rest/models/scheduled_run_status.py +42 -0
  160. hatchet_sdk/v0/clients/rest/models/scheduled_workflows.py +149 -0
  161. hatchet_sdk/v0/clients/rest/models/scheduled_workflows_list.py +110 -0
  162. hatchet_sdk/v0/clients/rest/models/scheduled_workflows_method.py +37 -0
  163. hatchet_sdk/v0/clients/rest/models/scheduled_workflows_order_by_field.py +37 -0
  164. hatchet_sdk/v0/clients/rest/models/semaphore_slots.py +113 -0
  165. hatchet_sdk/v0/clients/rest/models/slack_webhook.py +127 -0
  166. hatchet_sdk/v0/clients/rest/models/sns_integration.py +114 -0
  167. hatchet_sdk/v0/clients/rest/models/step.py +123 -0
  168. hatchet_sdk/v0/clients/rest/models/step_run.py +202 -0
  169. hatchet_sdk/v0/clients/rest/models/step_run_archive.py +142 -0
  170. hatchet_sdk/v0/clients/rest/models/step_run_archive_list.py +110 -0
  171. hatchet_sdk/v0/clients/rest/models/step_run_diff.py +91 -0
  172. hatchet_sdk/v0/clients/rest/models/step_run_event.py +122 -0
  173. hatchet_sdk/v0/clients/rest/models/step_run_event_list.py +110 -0
  174. hatchet_sdk/v0/clients/rest/models/step_run_event_reason.py +52 -0
  175. hatchet_sdk/v0/clients/rest/models/step_run_event_severity.py +38 -0
  176. hatchet_sdk/v0/clients/rest/models/step_run_status.py +44 -0
  177. hatchet_sdk/v0/clients/rest/models/tenant.py +118 -0
  178. hatchet_sdk/v0/clients/rest/models/tenant_alert_email_group.py +98 -0
  179. hatchet_sdk/v0/clients/rest/models/tenant_alert_email_group_list.py +112 -0
  180. hatchet_sdk/v0/clients/rest/models/tenant_alerting_settings.py +143 -0
  181. hatchet_sdk/v0/clients/rest/models/tenant_invite.py +120 -0
  182. hatchet_sdk/v0/clients/rest/models/tenant_invite_list.py +110 -0
  183. hatchet_sdk/v0/clients/rest/models/tenant_list.py +110 -0
  184. hatchet_sdk/v0/clients/rest/models/tenant_member.py +123 -0
  185. hatchet_sdk/v0/clients/rest/models/tenant_member_list.py +110 -0
  186. hatchet_sdk/v0/clients/rest/models/tenant_member_role.py +38 -0
  187. hatchet_sdk/v0/clients/rest/models/tenant_queue_metrics.py +116 -0
  188. hatchet_sdk/v0/clients/rest/models/tenant_resource.py +40 -0
  189. hatchet_sdk/v0/clients/rest/models/tenant_resource_limit.py +135 -0
  190. hatchet_sdk/v0/clients/rest/models/tenant_resource_policy.py +102 -0
  191. hatchet_sdk/v0/clients/rest/models/tenant_step_run_queue_metrics.py +83 -0
  192. hatchet_sdk/v0/clients/rest/models/trigger_workflow_run_request.py +91 -0
  193. hatchet_sdk/v0/clients/rest/models/update_tenant_alert_email_group_request.py +83 -0
  194. hatchet_sdk/v0/clients/rest/models/update_tenant_invite_request.py +85 -0
  195. hatchet_sdk/v0/clients/rest/models/update_tenant_request.py +137 -0
  196. hatchet_sdk/v0/clients/rest/models/update_worker_request.py +87 -0
  197. hatchet_sdk/v0/clients/rest/models/user.py +126 -0
  198. hatchet_sdk/v0/clients/rest/models/user_change_password_request.py +88 -0
  199. hatchet_sdk/v0/clients/rest/models/user_login_request.py +86 -0
  200. hatchet_sdk/v0/clients/rest/models/user_register_request.py +91 -0
  201. hatchet_sdk/v0/clients/rest/models/user_tenant_memberships_list.py +110 -0
  202. hatchet_sdk/v0/clients/rest/models/user_tenant_public.py +86 -0
  203. hatchet_sdk/v0/clients/rest/models/webhook_worker.py +100 -0
  204. hatchet_sdk/v0/clients/rest/models/webhook_worker_create_request.py +94 -0
  205. hatchet_sdk/v0/clients/rest/models/webhook_worker_create_response.py +98 -0
  206. hatchet_sdk/v0/clients/rest/models/webhook_worker_created.py +102 -0
  207. hatchet_sdk/v0/clients/rest/models/webhook_worker_list_response.py +110 -0
  208. hatchet_sdk/v0/clients/rest/models/webhook_worker_request.py +102 -0
  209. hatchet_sdk/v0/clients/rest/models/webhook_worker_request_list_response.py +104 -0
  210. hatchet_sdk/v0/clients/rest/models/webhook_worker_request_method.py +38 -0
  211. hatchet_sdk/v0/clients/rest/models/worker.py +239 -0
  212. hatchet_sdk/v0/clients/rest/models/worker_label.py +102 -0
  213. hatchet_sdk/v0/clients/rest/models/worker_list.py +110 -0
  214. hatchet_sdk/v0/clients/rest/models/worker_runtime_info.py +103 -0
  215. hatchet_sdk/v0/clients/rest/models/worker_runtime_sdks.py +38 -0
  216. hatchet_sdk/v0/clients/rest/models/worker_type.py +38 -0
  217. hatchet_sdk/v0/clients/rest/models/workflow.py +165 -0
  218. hatchet_sdk/v0/clients/rest/models/workflow_concurrency.py +107 -0
  219. hatchet_sdk/v0/clients/rest/models/workflow_deployment_config.py +136 -0
  220. hatchet_sdk/v0/clients/rest/models/workflow_kind.py +38 -0
  221. hatchet_sdk/v0/clients/rest/models/workflow_list.py +120 -0
  222. hatchet_sdk/v0/clients/rest/models/workflow_metrics.py +97 -0
  223. hatchet_sdk/v0/clients/rest/models/workflow_run.py +188 -0
  224. hatchet_sdk/v0/clients/rest/models/workflow_run_cancel200_response.py +85 -0
  225. hatchet_sdk/v0/clients/rest/models/workflow_run_list.py +110 -0
  226. hatchet_sdk/v0/clients/rest/models/workflow_run_order_by_direction.py +37 -0
  227. hatchet_sdk/v0/clients/rest/models/workflow_run_order_by_field.py +39 -0
  228. hatchet_sdk/v0/clients/rest/models/workflow_run_shape.py +186 -0
  229. hatchet_sdk/v0/clients/rest/models/workflow_run_status.py +42 -0
  230. hatchet_sdk/v0/clients/rest/models/workflow_run_triggered_by.py +112 -0
  231. hatchet_sdk/v0/clients/rest/models/workflow_runs_cancel_request.py +85 -0
  232. hatchet_sdk/v0/clients/rest/models/workflow_runs_metrics.py +94 -0
  233. hatchet_sdk/v0/clients/rest/models/workflow_runs_metrics_counts.py +104 -0
  234. hatchet_sdk/v0/clients/rest/models/workflow_tag.py +84 -0
  235. hatchet_sdk/v0/clients/rest/models/workflow_trigger_cron_ref.py +86 -0
  236. hatchet_sdk/v0/clients/rest/models/workflow_trigger_event_ref.py +86 -0
  237. hatchet_sdk/v0/clients/rest/models/workflow_triggers.py +141 -0
  238. hatchet_sdk/v0/clients/rest/models/workflow_update_request.py +85 -0
  239. hatchet_sdk/v0/clients/rest/models/workflow_version.py +170 -0
  240. hatchet_sdk/v0/clients/rest/models/workflow_version_concurrency.py +114 -0
  241. hatchet_sdk/v0/clients/rest/models/workflow_version_definition.py +85 -0
  242. hatchet_sdk/v0/clients/rest/models/workflow_version_meta.py +123 -0
  243. hatchet_sdk/v0/clients/rest/models/workflow_workers_count.py +95 -0
  244. hatchet_sdk/v0/clients/rest/rest.py +187 -0
  245. hatchet_sdk/v0/clients/rest/tenacity_utils.py +39 -0
  246. hatchet_sdk/v0/clients/rest_client.py +613 -0
  247. hatchet_sdk/v0/clients/run_event_listener.py +260 -0
  248. hatchet_sdk/v0/clients/workflow_listener.py +277 -0
  249. hatchet_sdk/v0/connection.py +63 -0
  250. hatchet_sdk/v0/context/__init__.py +1 -0
  251. hatchet_sdk/v0/context/context.py +446 -0
  252. hatchet_sdk/v0/context/worker_context.py +28 -0
  253. hatchet_sdk/v0/contracts/dispatcher_pb2.py +102 -0
  254. hatchet_sdk/v0/contracts/dispatcher_pb2.pyi +387 -0
  255. hatchet_sdk/v0/contracts/dispatcher_pb2_grpc.py +621 -0
  256. hatchet_sdk/v0/contracts/events_pb2.py +46 -0
  257. hatchet_sdk/v0/contracts/events_pb2.pyi +87 -0
  258. hatchet_sdk/v0/contracts/events_pb2_grpc.py +274 -0
  259. hatchet_sdk/v0/contracts/workflows_pb2.py +80 -0
  260. hatchet_sdk/v0/contracts/workflows_pb2.pyi +312 -0
  261. hatchet_sdk/v0/contracts/workflows_pb2_grpc.py +277 -0
  262. hatchet_sdk/v0/features/cron.py +286 -0
  263. hatchet_sdk/v0/features/scheduled.py +248 -0
  264. hatchet_sdk/v0/hatchet.py +310 -0
  265. hatchet_sdk/v0/labels.py +10 -0
  266. hatchet_sdk/{loader.py → v0/loader.py} +11 -0
  267. hatchet_sdk/v0/logger.py +13 -0
  268. hatchet_sdk/v0/metadata.py +2 -0
  269. hatchet_sdk/v0/opentelemetry/instrumentor.py +396 -0
  270. hatchet_sdk/v0/rate_limit.py +126 -0
  271. hatchet_sdk/v0/semver.py +30 -0
  272. hatchet_sdk/v0/token.py +27 -0
  273. hatchet_sdk/v0/utils/aio_utils.py +137 -0
  274. hatchet_sdk/v0/utils/backoff.py +9 -0
  275. hatchet_sdk/v0/utils/typing.py +12 -0
  276. hatchet_sdk/{v2 → v0/v2}/callable.py +8 -8
  277. hatchet_sdk/{v2 → v0/v2}/concurrency.py +2 -2
  278. hatchet_sdk/{v2 → v0/v2}/hatchet.py +10 -10
  279. hatchet_sdk/v0/worker/__init__.py +1 -0
  280. hatchet_sdk/v0/worker/action_listener_process.py +278 -0
  281. hatchet_sdk/v0/worker/runner/run_loop_manager.py +112 -0
  282. hatchet_sdk/v0/worker/runner/runner.py +460 -0
  283. hatchet_sdk/v0/worker/runner/utils/capture_logs.py +81 -0
  284. hatchet_sdk/v0/worker/runner/utils/error_with_traceback.py +6 -0
  285. hatchet_sdk/v0/worker/worker.py +391 -0
  286. hatchet_sdk/v0/workflow.py +261 -0
  287. hatchet_sdk/v0/workflow_run.py +59 -0
  288. hatchet_sdk/worker/__init__.py +0 -1
  289. hatchet_sdk/worker/action_listener_process.py +36 -33
  290. hatchet_sdk/worker/runner/run_loop_manager.py +18 -16
  291. hatchet_sdk/worker/runner/runner.py +37 -59
  292. hatchet_sdk/worker/runner/utils/capture_logs.py +25 -14
  293. hatchet_sdk/worker/runner/utils/error_with_traceback.py +1 -1
  294. hatchet_sdk/worker/worker.py +61 -75
  295. hatchet_sdk/workflow.py +473 -207
  296. hatchet_sdk/workflow_run.py +14 -25
  297. {hatchet_sdk-0.46.1.dist-info → hatchet_sdk-1.0.0.dist-info}/METADATA +3 -2
  298. hatchet_sdk-1.0.0.dist-info/RECORD +485 -0
  299. {hatchet_sdk-0.46.1.dist-info → hatchet_sdk-1.0.0.dist-info}/entry_points.txt +1 -0
  300. hatchet_sdk/utils/serialization.py +0 -18
  301. hatchet_sdk-0.46.1.dist-info/RECORD +0 -237
  302. /hatchet_sdk/{utils → v0/utils}/types.py +0 -0
  303. {hatchet_sdk-0.46.1.dist-info → hatchet_sdk-1.0.0.dist-info}/WHEEL +0 -0
@@ -2,18 +2,23 @@ import asyncio
2
2
  import json
3
3
  import time
4
4
  from dataclasses import dataclass, field
5
- from typing import Any, AsyncGenerator, List, Optional
5
+ from enum import Enum
6
+ from typing import Any, AsyncGenerator, Optional, cast
6
7
 
7
8
  import grpc
8
- from grpc._cython import cygrpc
9
+ import grpc.aio
10
+ from grpc._cython import cygrpc # type: ignore[attr-defined]
11
+ from pydantic import BaseModel, ConfigDict, Field, field_validator
9
12
 
10
- from hatchet_sdk.clients.event_ts import Event_ts, read_with_interrupt
13
+ from hatchet_sdk.clients.event_ts import ThreadSafeEvent, read_with_interrupt
14
+ from hatchet_sdk.clients.events import proto_timestamp_now
11
15
  from hatchet_sdk.clients.run_event_listener import (
12
16
  DEFAULT_ACTION_LISTENER_RETRY_INTERVAL,
13
17
  )
18
+ from hatchet_sdk.config import ClientConfig
14
19
  from hatchet_sdk.connection import new_conn
20
+ from hatchet_sdk.contracts.dispatcher_pb2 import ActionType as ActionTypeProto
15
21
  from hatchet_sdk.contracts.dispatcher_pb2 import (
16
- ActionType,
17
22
  AssignedAction,
18
23
  HeartbeatRequest,
19
24
  WorkerLabels,
@@ -22,31 +27,26 @@ from hatchet_sdk.contracts.dispatcher_pb2 import (
22
27
  )
23
28
  from hatchet_sdk.contracts.dispatcher_pb2_grpc import DispatcherStub
24
29
  from hatchet_sdk.logger import logger
30
+ from hatchet_sdk.metadata import get_metadata
25
31
  from hatchet_sdk.utils.backoff import exp_backoff_sleep
26
- from hatchet_sdk.utils.serialization import flatten
27
-
28
- from ...loader import ClientConfig
29
- from ...metadata import get_metadata
30
- from ..events import proto_timestamp_now
32
+ from hatchet_sdk.utils.proto_enums import convert_proto_enum_to_python
33
+ from hatchet_sdk.utils.typing import JSONSerializableMapping
31
34
 
32
35
  DEFAULT_ACTION_TIMEOUT = 600 # seconds
33
-
34
-
35
- DEFAULT_ACTION_LISTENER_RETRY_INTERVAL = 5 # seconds
36
36
  DEFAULT_ACTION_LISTENER_RETRY_COUNT = 15
37
37
 
38
38
 
39
39
  @dataclass
40
40
  class GetActionListenerRequest:
41
41
  worker_name: str
42
- services: List[str]
43
- actions: List[str]
44
- max_runs: Optional[int] = None
42
+ services: list[str]
43
+ actions: list[str]
44
+ max_runs: int | None = None
45
45
  _labels: dict[str, str | int] = field(default_factory=dict)
46
46
 
47
47
  labels: dict[str, WorkerLabels] = field(init=False)
48
48
 
49
- def __post_init__(self):
49
+ def __post_init__(self) -> None:
50
50
  self.labels = {}
51
51
 
52
52
  for key, value in self._labels.items():
@@ -56,8 +56,31 @@ class GetActionListenerRequest:
56
56
  self.labels[key] = WorkerLabels(strValue=str(value))
57
57
 
58
58
 
59
- @dataclass
60
- class Action:
59
+ class ActionPayload(BaseModel):
60
+ model_config = ConfigDict(extra="allow")
61
+
62
+ input: JSONSerializableMapping = Field(default_factory=dict)
63
+ parents: dict[str, JSONSerializableMapping] = Field(default_factory=dict)
64
+ overrides: JSONSerializableMapping = Field(default_factory=dict)
65
+ user_data: JSONSerializableMapping = Field(default_factory=dict)
66
+ step_run_errors: dict[str, str] = Field(default_factory=dict)
67
+ triggered_by: str | None = None
68
+
69
+ @field_validator(
70
+ "input", "parents", "overrides", "user_data", "step_run_errors", mode="before"
71
+ )
72
+ @classmethod
73
+ def validate_fields(cls, v: Any) -> Any:
74
+ return v or {}
75
+
76
+
77
+ class ActionType(str, Enum):
78
+ START_STEP_RUN = "START_STEP_RUN"
79
+ CANCEL_STEP_RUN = "CANCEL_STEP_RUN"
80
+ START_GET_GROUP_KEY = "START_GET_GROUP_KEY"
81
+
82
+
83
+ class Action(BaseModel):
61
84
  worker_id: str
62
85
  tenant_id: str
63
86
  workflow_run_id: str
@@ -68,31 +91,25 @@ class Action:
68
91
  step_id: str
69
92
  step_run_id: str
70
93
  action_id: str
71
- action_payload: str
72
94
  action_type: ActionType
73
95
  retry_count: int
74
- additional_metadata: dict[str, str] | None = None
96
+ action_payload: ActionPayload
97
+ additional_metadata: JSONSerializableMapping = field(default_factory=dict)
75
98
 
76
99
  child_workflow_index: int | None = None
77
100
  child_workflow_key: str | None = None
78
101
  parent_workflow_run_id: str | None = None
79
102
 
80
- def __post_init__(self):
81
- if isinstance(self.additional_metadata, str) and self.additional_metadata != "":
82
- try:
83
- self.additional_metadata = json.loads(self.additional_metadata)
84
- except json.JSONDecodeError:
85
- # If JSON decoding fails, keep the original string
86
- pass
87
-
88
- # Ensure additional_metadata is always a dictionary
89
- if not isinstance(self.additional_metadata, dict):
90
- self.additional_metadata = {}
103
+ def _dump_payload_to_str(self) -> str:
104
+ try:
105
+ return json.dumps(self.action_payload.model_dump(), default=str)
106
+ except Exception:
107
+ return str(self.action_payload)
91
108
 
92
109
  @property
93
110
  def otel_attributes(self) -> dict[str, str | int]:
94
111
  try:
95
- payload_str = json.dumps(self.action_payload, default=str)
112
+ payload_str = json.dumps(self.action_payload.model_dump(), default=str)
96
113
  except Exception:
97
114
  payload_str = str(self.action_payload)
98
115
 
@@ -115,9 +132,14 @@ class Action:
115
132
  return {k: v for k, v in attrs.items() if v}
116
133
 
117
134
 
118
- START_STEP_RUN = 0
119
- CANCEL_STEP_RUN = 1
120
- START_GET_GROUP_KEY = 2
135
+ def parse_additional_metadata(additional_metadata: str) -> JSONSerializableMapping:
136
+ try:
137
+ return cast(
138
+ JSONSerializableMapping,
139
+ json.loads(additional_metadata),
140
+ )
141
+ except json.JSONDecodeError:
142
+ return {}
121
143
 
122
144
 
123
145
  @dataclass
@@ -132,22 +154,22 @@ class ActionListener:
132
154
  last_connection_attempt: float = field(default=0, init=False)
133
155
  last_heartbeat_succeeded: bool = field(default=True, init=False)
134
156
  time_last_hb_succeeded: float = field(default=9999999999999, init=False)
135
- heartbeat_task: Optional[asyncio.Task] = field(default=None, init=False)
157
+ heartbeat_task: Optional[asyncio.Task[None]] = field(default=None, init=False)
136
158
  run_heartbeat: bool = field(default=True, init=False)
137
159
  listen_strategy: str = field(default="v2", init=False)
138
160
  stop_signal: bool = field(default=False, init=False)
139
161
 
140
162
  missed_heartbeats: int = field(default=0, init=False)
141
163
 
142
- def __post_init__(self):
143
- self.client = DispatcherStub(new_conn(self.config))
144
- self.aio_client = DispatcherStub(new_conn(self.config, True))
164
+ def __post_init__(self) -> None:
165
+ self.client = DispatcherStub(new_conn(self.config, False)) # type: ignore[no-untyped-call]
166
+ self.aio_client = DispatcherStub(new_conn(self.config, True)) # type: ignore[no-untyped-call]
145
167
  self.token = self.config.token
146
168
 
147
- def is_healthy(self):
169
+ def is_healthy(self) -> bool:
148
170
  return self.last_heartbeat_succeeded
149
171
 
150
- async def heartbeat(self):
172
+ async def heartbeat(self) -> None:
151
173
  # send a heartbeat every 4 seconds
152
174
  heartbeat_delay = 4
153
175
 
@@ -207,7 +229,7 @@ class ActionListener:
207
229
  break
208
230
  await asyncio.sleep(heartbeat_delay)
209
231
 
210
- async def start_heartbeater(self):
232
+ async def start_heartbeater(self) -> None:
211
233
  if self.heartbeat_task is not None:
212
234
  return
213
235
 
@@ -221,10 +243,10 @@ class ActionListener:
221
243
  raise e
222
244
  self.heartbeat_task = loop.create_task(self.heartbeat())
223
245
 
224
- def __aiter__(self):
246
+ def __aiter__(self) -> AsyncGenerator[Action | None, None]:
225
247
  return self._generator()
226
248
 
227
- async def _generator(self) -> AsyncGenerator[Action, None]:
249
+ async def _generator(self) -> AsyncGenerator[Action | None, None]:
228
250
  listener = None
229
251
 
230
252
  while not self.stop_signal:
@@ -239,7 +261,11 @@ class ActionListener:
239
261
 
240
262
  try:
241
263
  while not self.stop_signal:
242
- self.interrupt = Event_ts()
264
+ self.interrupt = ThreadSafeEvent()
265
+
266
+ if listener is None:
267
+ continue
268
+
243
269
  t = asyncio.create_task(
244
270
  read_with_interrupt(listener, self.interrupt)
245
271
  )
@@ -252,7 +278,10 @@ class ActionListener:
252
278
  )
253
279
 
254
280
  t.cancel()
255
- listener.cancel()
281
+
282
+ if listener:
283
+ listener.cancel()
284
+
256
285
  break
257
286
 
258
287
  assigned_action = t.result()
@@ -262,20 +291,12 @@ class ActionListener:
262
291
  break
263
292
 
264
293
  self.retries = 0
265
- assigned_action: AssignedAction
266
-
267
- # Process the received action
268
- action_type = self.map_action_type(assigned_action.actionType)
269
294
 
270
- if (
271
- assigned_action.actionPayload is None
272
- or assigned_action.actionPayload == ""
273
- ):
274
- action_payload = None
275
- else:
276
- action_payload = self.parse_action_payload(
277
- assigned_action.actionPayload
278
- )
295
+ action_payload = (
296
+ {}
297
+ if not assigned_action.actionPayload
298
+ else self.parse_action_payload(assigned_action.actionPayload)
299
+ )
279
300
 
280
301
  action = Action(
281
302
  tenant_id=assigned_action.tenantId,
@@ -288,10 +309,16 @@ class ActionListener:
288
309
  step_id=assigned_action.stepId,
289
310
  step_run_id=assigned_action.stepRunId,
290
311
  action_id=assigned_action.actionId,
291
- action_payload=action_payload,
292
- action_type=action_type,
312
+ action_payload=ActionPayload.model_validate(action_payload),
313
+ action_type=convert_proto_enum_to_python(
314
+ assigned_action.actionType,
315
+ ActionType,
316
+ ActionTypeProto,
317
+ ),
293
318
  retry_count=assigned_action.retryCount,
294
- additional_metadata=assigned_action.additional_metadata,
319
+ additional_metadata=parse_additional_metadata(
320
+ assigned_action.additional_metadata
321
+ ),
295
322
  child_workflow_index=assigned_action.child_workflow_index,
296
323
  child_workflow_key=assigned_action.child_workflow_key,
297
324
  parent_workflow_run_id=assigned_action.parent_workflow_run_id,
@@ -325,25 +352,15 @@ class ActionListener:
325
352
 
326
353
  self.retries = self.retries + 1
327
354
 
328
- def parse_action_payload(self, payload: str):
355
+ def parse_action_payload(self, payload: str) -> JSONSerializableMapping:
329
356
  try:
330
- payload_data = json.loads(payload)
357
+ return cast(JSONSerializableMapping, json.loads(payload))
331
358
  except json.JSONDecodeError as e:
332
359
  raise ValueError(f"Error decoding payload: {e}")
333
- return payload_data
334
-
335
- def map_action_type(self, action_type):
336
- if action_type == ActionType.START_STEP_RUN:
337
- return START_STEP_RUN
338
- elif action_type == ActionType.CANCEL_STEP_RUN:
339
- return CANCEL_STEP_RUN
340
- elif action_type == ActionType.START_GET_GROUP_KEY:
341
- return START_GET_GROUP_KEY
342
- else:
343
- # logger.error(f"Unknown action type: {action_type}")
344
- return None
345
360
 
346
- async def get_listen_client(self):
361
+ async def get_listen_client(
362
+ self,
363
+ ) -> grpc.aio.UnaryStreamCall[WorkerListenRequest, AssignedAction]:
347
364
  current_time = int(time.time())
348
365
 
349
366
  if (
@@ -371,7 +388,7 @@ class ActionListener:
371
388
  f"action listener connection interrupted, retrying... ({self.retries}/{DEFAULT_ACTION_LISTENER_RETRY_COUNT})"
372
389
  )
373
390
 
374
- self.aio_client = DispatcherStub(new_conn(self.config, True))
391
+ self.aio_client = DispatcherStub(new_conn(self.config, True)) # type: ignore[no-untyped-call]
375
392
 
376
393
  if self.listen_strategy == "v2":
377
394
  # we should await for the listener to be established before
@@ -392,11 +409,14 @@ class ActionListener:
392
409
 
393
410
  self.last_connection_attempt = current_time
394
411
 
395
- return listener
412
+ return cast(
413
+ grpc.aio.UnaryStreamCall[WorkerListenRequest, AssignedAction], listener
414
+ )
396
415
 
397
- def cleanup(self):
416
+ def cleanup(self) -> None:
398
417
  self.run_heartbeat = False
399
- self.heartbeat_task.cancel()
418
+ if self.heartbeat_task is not None:
419
+ self.heartbeat_task.cancel()
400
420
 
401
421
  try:
402
422
  self.unregister()
@@ -406,9 +426,11 @@ class ActionListener:
406
426
  if self.interrupt:
407
427
  self.interrupt.set()
408
428
 
409
- def unregister(self):
429
+ def unregister(self) -> WorkerUnsubscribeRequest:
410
430
  self.run_heartbeat = False
411
- self.heartbeat_task.cancel()
431
+
432
+ if self.heartbeat_task is not None:
433
+ self.heartbeat_task.cancel()
412
434
 
413
435
  try:
414
436
  req = self.aio_client.Unsubscribe(
@@ -418,6 +440,6 @@ class ActionListener:
418
440
  )
419
441
  if self.interrupt is not None:
420
442
  self.interrupt.set()
421
- return req
443
+ return cast(WorkerUnsubscribeRequest, req)
422
444
  except grpc.RpcError as e:
423
445
  raise Exception(f"Failed to unsubscribe: {e}")
@@ -1,5 +1,6 @@
1
- from typing import Any, cast
1
+ from typing import cast
2
2
 
3
+ import grpc.aio
3
4
  from google.protobuf.timestamp_pb2 import Timestamp
4
5
 
5
6
  from hatchet_sdk.clients.dispatcher.action_listener import (
@@ -8,6 +9,7 @@ from hatchet_sdk.clients.dispatcher.action_listener import (
8
9
  GetActionListenerRequest,
9
10
  )
10
11
  from hatchet_sdk.clients.rest.tenacity_utils import tenacity_retry
12
+ from hatchet_sdk.config import ClientConfig
11
13
  from hatchet_sdk.connection import new_conn
12
14
  from hatchet_sdk.contracts.dispatcher_pb2 import (
13
15
  STEP_EVENT_TYPE_COMPLETED,
@@ -26,22 +28,16 @@ from hatchet_sdk.contracts.dispatcher_pb2 import (
26
28
  WorkerRegisterResponse,
27
29
  )
28
30
  from hatchet_sdk.contracts.dispatcher_pb2_grpc import DispatcherStub
29
-
30
- from ...loader import ClientConfig
31
- from ...metadata import get_metadata
31
+ from hatchet_sdk.metadata import get_metadata
32
32
 
33
33
  DEFAULT_REGISTER_TIMEOUT = 30
34
34
 
35
35
 
36
- def new_dispatcher(config: ClientConfig) -> "DispatcherClient":
37
- return DispatcherClient(config=config)
38
-
39
-
40
36
  class DispatcherClient:
41
37
  config: ClientConfig
42
38
 
43
39
  def __init__(self, config: ClientConfig):
44
- conn = new_conn(config)
40
+ conn = new_conn(config, False)
45
41
  self.client = DispatcherStub(conn) # type: ignore[no-untyped-call]
46
42
 
47
43
  aio_conn = new_conn(config, True)
@@ -76,7 +72,7 @@ class DispatcherClient:
76
72
 
77
73
  async def send_step_action_event(
78
74
  self, action: Action, event_type: StepActionEventType, payload: str
79
- ) -> Any:
75
+ ) -> grpc.aio.UnaryUnaryCall[StepActionEvent, ActionEventResponse] | None:
80
76
  try:
81
77
  return await self._try_send_step_action_event(action, event_type, payload)
82
78
  except Exception as e:
@@ -91,12 +87,12 @@ class DispatcherClient:
91
87
  "Failed to send finished event: " + str(e),
92
88
  )
93
89
 
94
- return
90
+ return None
95
91
 
96
92
  @tenacity_retry
97
93
  async def _try_send_step_action_event(
98
94
  self, action: Action, event_type: StepActionEventType, payload: str
99
- ) -> Any:
95
+ ) -> grpc.aio.UnaryUnaryCall[StepActionEvent, ActionEventResponse]:
100
96
  eventTimestamp = Timestamp()
101
97
  eventTimestamp.GetCurrentTime()
102
98
 
@@ -113,15 +109,17 @@ class DispatcherClient:
113
109
  retryCount=action.retry_count,
114
110
  )
115
111
 
116
- ## TODO: What does this return?
117
- return await self.aio_client.SendStepActionEvent(
118
- event,
119
- metadata=get_metadata(self.token),
112
+ return cast(
113
+ grpc.aio.UnaryUnaryCall[StepActionEvent, ActionEventResponse],
114
+ await self.aio_client.SendStepActionEvent(
115
+ event,
116
+ metadata=get_metadata(self.token),
117
+ ),
120
118
  )
121
119
 
122
120
  async def send_group_key_action_event(
123
121
  self, action: Action, event_type: GroupKeyActionEventType, payload: str
124
- ) -> Any:
122
+ ) -> grpc.aio.UnaryUnaryCall[GroupKeyActionEvent, ActionEventResponse]:
125
123
  eventTimestamp = Timestamp()
126
124
  eventTimestamp.GetCurrentTime()
127
125
 
@@ -135,10 +133,12 @@ class DispatcherClient:
135
133
  eventPayload=payload,
136
134
  )
137
135
 
138
- ## TODO: What does this return?
139
- return await self.aio_client.SendGroupKeyActionEvent(
140
- event,
141
- metadata=get_metadata(self.token),
136
+ return cast(
137
+ grpc.aio.UnaryUnaryCall[GroupKeyActionEvent, ActionEventResponse],
138
+ await self.aio_client.SendGroupKeyActionEvent(
139
+ event,
140
+ metadata=get_metadata(self.token),
141
+ ),
142
142
  )
143
143
 
144
144
  def put_overrides_data(self, data: OverridesData) -> ActionEventResponse:
@@ -1,28 +1,41 @@
1
1
  import asyncio
2
- from typing import Any
2
+ from typing import TypeVar, cast
3
3
 
4
+ import grpc.aio
5
+ from grpc._cython import cygrpc # type: ignore[attr-defined]
4
6
 
5
- class Event_ts(asyncio.Event):
7
+
8
+ class ThreadSafeEvent(asyncio.Event):
6
9
  """
7
- Event_ts is a subclass of asyncio.Event that allows for thread-safe setting and clearing of the event.
10
+ ThreadSafeEvent is a subclass of asyncio.Event that allows for thread-safe setting and clearing of the event.
8
11
  """
9
12
 
10
- def __init__(self, *args, **kwargs):
11
- super().__init__(*args, **kwargs)
12
- if self._loop is None:
13
+ def __init__(self) -> None:
14
+ super().__init__()
15
+ if self._loop is None: # type: ignore[has-type]
13
16
  self._loop = asyncio.get_event_loop()
14
17
 
15
- def set(self):
18
+ def set(self) -> None:
16
19
  if not self._loop.is_closed():
17
20
  self._loop.call_soon_threadsafe(super().set)
18
21
 
19
- def clear(self):
22
+ def clear(self) -> None:
20
23
  self._loop.call_soon_threadsafe(super().clear)
21
24
 
22
25
 
23
- async def read_with_interrupt(listener: Any, interrupt: Event_ts):
26
+ TRequest = TypeVar("TRequest")
27
+ TResponse = TypeVar("TResponse")
28
+
29
+
30
+ async def read_with_interrupt(
31
+ listener: grpc.aio.UnaryStreamCall[TRequest, TResponse], interrupt: ThreadSafeEvent
32
+ ) -> TResponse:
24
33
  try:
25
34
  result = await listener.read()
26
- return result
35
+
36
+ if result is cygrpc.EOF:
37
+ raise ValueError("Unexpected EOF")
38
+
39
+ return cast(TResponse, result)
27
40
  finally:
28
41
  interrupt.set()