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
@@ -1,70 +1,56 @@
1
+ import asyncio
1
2
  import json
2
3
  from datetime import datetime
3
- from typing import Any, Callable, Dict, List, Optional, TypedDict, TypeVar, Union
4
+ from typing import Union, cast
4
5
 
5
6
  import grpc
6
7
  from google.protobuf import timestamp_pb2
8
+ from pydantic import BaseModel, Field
7
9
 
8
- from hatchet_sdk.clients.rest.models.workflow_run import WorkflowRun
9
10
  from hatchet_sdk.clients.rest.tenacity_utils import tenacity_retry
10
- from hatchet_sdk.clients.run_event_listener import new_listener
11
+ from hatchet_sdk.clients.run_event_listener import RunEventListenerClient
11
12
  from hatchet_sdk.clients.workflow_listener import PooledWorkflowRunListener
13
+ from hatchet_sdk.config import ClientConfig
12
14
  from hatchet_sdk.connection import new_conn
13
- from hatchet_sdk.contracts.workflows_pb2 import (
14
- BulkTriggerWorkflowRequest,
15
- BulkTriggerWorkflowResponse,
16
- CreateWorkflowVersionOpts,
17
- PutRateLimitRequest,
18
- PutWorkflowRequest,
19
- RateLimitDuration,
20
- ScheduleWorkflowRequest,
21
- TriggerWorkflowRequest,
22
- TriggerWorkflowResponse,
23
- WorkflowVersion,
24
- )
15
+ from hatchet_sdk.contracts import workflows_pb2 as workflow_protos
25
16
  from hatchet_sdk.contracts.workflows_pb2_grpc import WorkflowServiceStub
26
- from hatchet_sdk.utils.serialization import flatten
27
- from hatchet_sdk.workflow_run import RunRef, WorkflowRunRef
28
-
29
- from ..loader import ClientConfig
30
- from ..metadata import get_metadata
31
- from ..workflow import WorkflowMeta
32
-
33
-
34
- def new_admin(config: ClientConfig):
35
- return AdminClient(config)
36
-
37
-
38
- class ScheduleTriggerWorkflowOptions(TypedDict, total=False):
39
- parent_id: Optional[str]
40
- parent_step_run_id: Optional[str]
41
- child_index: Optional[int]
42
- child_key: Optional[str]
43
- namespace: Optional[str]
17
+ from hatchet_sdk.metadata import get_metadata
18
+ from hatchet_sdk.rate_limit import RateLimitDuration
19
+ from hatchet_sdk.utils.proto_enums import convert_python_enum_to_proto, maybe_int_to_str
20
+ from hatchet_sdk.utils.typing import JSONSerializableMapping
21
+ from hatchet_sdk.workflow_run import WorkflowRunRef
22
+
23
+
24
+ class ScheduleTriggerWorkflowOptions(BaseModel):
25
+ parent_id: str | None = None
26
+ parent_step_run_id: str | None = None
27
+ child_index: int | None = None
28
+ child_key: str | None = None
29
+ namespace: str | None = None
44
30
 
45
31
 
46
- class ChildTriggerWorkflowOptions(TypedDict, total=False):
47
- additional_metadata: Dict[str, str] | None = None
48
- sticky: bool | None = None
32
+ class ChildTriggerWorkflowOptions(BaseModel):
33
+ additional_metadata: JSONSerializableMapping = Field(default_factory=dict)
34
+ sticky: bool = False
49
35
 
50
36
 
51
- class ChildWorkflowRunDict(TypedDict, total=False):
37
+ class ChildWorkflowRunDict(BaseModel):
52
38
  workflow_name: str
53
- input: Any
39
+ input: JSONSerializableMapping
54
40
  options: ChildTriggerWorkflowOptions
55
41
  key: str | None = None
56
42
 
57
43
 
58
- class TriggerWorkflowOptions(ScheduleTriggerWorkflowOptions, total=False):
59
- additional_metadata: Dict[str, str] | None = None
44
+ class TriggerWorkflowOptions(ScheduleTriggerWorkflowOptions):
45
+ additional_metadata: JSONSerializableMapping = Field(default_factory=dict)
60
46
  desired_worker_id: str | None = None
61
47
  namespace: str | None = None
62
48
 
63
49
 
64
- class WorkflowRunDict(TypedDict, total=False):
50
+ class WorkflowRunDict(BaseModel):
65
51
  workflow_name: str
66
- input: Any
67
- options: TriggerWorkflowOptions | None
52
+ input: JSONSerializableMapping
53
+ options: TriggerWorkflowOptions
68
54
 
69
55
 
70
56
  class DedupeViolationErr(Exception):
@@ -73,31 +59,41 @@ class DedupeViolationErr(Exception):
73
59
  pass
74
60
 
75
61
 
76
- class AdminClientBase:
77
- pooled_workflow_listener: PooledWorkflowRunListener | None = None
62
+ class AdminClient:
63
+ def __init__(self, config: ClientConfig):
64
+ conn = new_conn(config, False)
65
+ self.config = config
66
+ self.client = WorkflowServiceStub(conn) # type: ignore[no-untyped-call]
67
+ self.token = config.token
68
+ self.listener_client = RunEventListenerClient(config=config)
69
+ self.namespace = config.namespace
70
+
71
+ self.pooled_workflow_listener: PooledWorkflowRunListener | None = None
78
72
 
79
73
  def _prepare_workflow_request(
80
- self, workflow_name: str, input: any, options: TriggerWorkflowOptions = None
81
- ):
74
+ self,
75
+ workflow_name: str,
76
+ input: JSONSerializableMapping,
77
+ options: TriggerWorkflowOptions,
78
+ ) -> workflow_protos.TriggerWorkflowRequest:
82
79
  try:
83
80
  payload_data = json.dumps(input)
81
+ _options = options.model_dump()
82
+
83
+ _options.pop("namespace")
84
84
 
85
85
  try:
86
- meta = (
87
- None
88
- if options is None or "additional_metadata" not in options
89
- else options["additional_metadata"]
90
- )
91
- if meta is not None:
92
- options = {
93
- **options,
94
- "additional_metadata": json.dumps(meta).encode("utf-8"),
95
- }
86
+ _options = {
87
+ **_options,
88
+ "additional_metadata": json.dumps(
89
+ options.additional_metadata
90
+ ).encode("utf-8"),
91
+ }
96
92
  except json.JSONDecodeError as e:
97
93
  raise ValueError(f"Error encoding payload: {e}")
98
94
 
99
- return TriggerWorkflowRequest(
100
- name=workflow_name, input=payload_data, **(options or {})
95
+ return workflow_protos.TriggerWorkflowRequest(
96
+ name=workflow_name, input=payload_data, **_options
101
97
  )
102
98
  except json.JSONDecodeError as e:
103
99
  raise ValueError(f"Error encoding payload: {e}")
@@ -105,266 +101,135 @@ class AdminClientBase:
105
101
  def _prepare_put_workflow_request(
106
102
  self,
107
103
  name: str,
108
- workflow: CreateWorkflowVersionOpts | WorkflowMeta,
109
- overrides: CreateWorkflowVersionOpts | None = None,
110
- ):
111
- try:
112
- opts: CreateWorkflowVersionOpts
113
-
114
- if isinstance(workflow, CreateWorkflowVersionOpts):
115
- opts = workflow
116
- else:
117
- opts = workflow.get_create_opts(self.client.config.namespace)
104
+ workflow: workflow_protos.CreateWorkflowVersionOpts,
105
+ overrides: workflow_protos.CreateWorkflowVersionOpts | None = None,
106
+ ) -> workflow_protos.PutWorkflowRequest:
107
+ if overrides is not None:
108
+ workflow.MergeFrom(overrides)
118
109
 
119
- if overrides is not None:
120
- opts.MergeFrom(overrides)
110
+ workflow.name = name
121
111
 
122
- opts.name = name
112
+ return workflow_protos.PutWorkflowRequest(
113
+ opts=workflow,
114
+ )
123
115
 
124
- return PutWorkflowRequest(
125
- opts=opts,
116
+ def _parse_schedule(
117
+ self, schedule: datetime | timestamp_pb2.Timestamp
118
+ ) -> timestamp_pb2.Timestamp:
119
+ if isinstance(schedule, datetime):
120
+ t = schedule.timestamp()
121
+ seconds = int(t)
122
+ nanos = int(t % 1 * 1e9)
123
+ return timestamp_pb2.Timestamp(seconds=seconds, nanos=nanos)
124
+ elif isinstance(schedule, timestamp_pb2.Timestamp):
125
+ return schedule
126
+ else:
127
+ raise ValueError(
128
+ "Invalid schedule type. Must be datetime or timestamp_pb2.Timestamp."
126
129
  )
127
- except grpc.RpcError as e:
128
- raise ValueError(f"Could not put workflow: {e}")
129
130
 
130
131
  def _prepare_schedule_workflow_request(
131
132
  self,
132
133
  name: str,
133
- schedules: List[Union[datetime, timestamp_pb2.Timestamp]],
134
- input={},
135
- options: ScheduleTriggerWorkflowOptions = None,
136
- ):
137
- timestamp_schedules = []
138
- for schedule in schedules:
139
- if isinstance(schedule, datetime):
140
- t = schedule.timestamp()
141
- seconds = int(t)
142
- nanos = int(t % 1 * 1e9)
143
- timestamp = timestamp_pb2.Timestamp(seconds=seconds, nanos=nanos)
144
- timestamp_schedules.append(timestamp)
145
- elif isinstance(schedule, timestamp_pb2.Timestamp):
146
- timestamp_schedules.append(schedule)
147
- else:
148
- raise ValueError(
149
- "Invalid schedule type. Must be datetime or timestamp_pb2.Timestamp."
150
- )
151
-
152
- return ScheduleWorkflowRequest(
134
+ schedules: list[Union[datetime, timestamp_pb2.Timestamp]],
135
+ input: JSONSerializableMapping = {},
136
+ options: ScheduleTriggerWorkflowOptions = ScheduleTriggerWorkflowOptions(),
137
+ ) -> workflow_protos.ScheduleWorkflowRequest:
138
+ return workflow_protos.ScheduleWorkflowRequest(
153
139
  name=name,
154
- schedules=timestamp_schedules,
140
+ schedules=[self._parse_schedule(schedule) for schedule in schedules],
155
141
  input=json.dumps(input),
156
- **(options or {}),
157
- )
158
-
159
-
160
- T = TypeVar("T")
161
-
162
-
163
- class AdminClientAioImpl(AdminClientBase):
164
- def __init__(self, config: ClientConfig):
165
- aio_conn = new_conn(config, True)
166
- self.config = config
167
- self.aio_client = WorkflowServiceStub(aio_conn)
168
- self.token = config.token
169
- self.listener_client = new_listener(config)
170
- self.namespace = config.namespace
171
-
172
- async def run(
173
- self,
174
- function: Union[str, Callable[[Any], T]],
175
- input: any,
176
- options: TriggerWorkflowOptions = None,
177
- ) -> "RunRef[T]":
178
- workflow_name = function
179
-
180
- if not isinstance(function, str):
181
- workflow_name = function.function_name
182
-
183
- wrr = await self.run_workflow(workflow_name, input, options)
184
-
185
- return RunRef[T](
186
- wrr.workflow_run_id, wrr.workflow_listener, wrr.workflow_run_event_listener
142
+ **options.model_dump(),
187
143
  )
188
144
 
189
145
  ## IMPORTANT: Keep this method's signature in sync with the wrapper in the OTel instrumentor
190
146
  @tenacity_retry
191
- async def run_workflow(
192
- self, workflow_name: str, input: any, options: TriggerWorkflowOptions = None
147
+ async def aio_run_workflow(
148
+ self,
149
+ workflow_name: str,
150
+ input: JSONSerializableMapping,
151
+ options: TriggerWorkflowOptions = TriggerWorkflowOptions(),
193
152
  ) -> WorkflowRunRef:
194
- try:
195
- if not self.pooled_workflow_listener:
196
- self.pooled_workflow_listener = PooledWorkflowRunListener(self.config)
197
-
198
- namespace = self.namespace
199
-
200
- if (
201
- options is not None
202
- and "namespace" in options
203
- and options["namespace"] is not None
204
- ):
205
- namespace = options.pop("namespace")
206
-
207
- if namespace != "" and not workflow_name.startswith(self.namespace):
208
- workflow_name = f"{namespace}{workflow_name}"
209
-
210
- request = self._prepare_workflow_request(workflow_name, input, options)
211
-
212
- resp: TriggerWorkflowResponse = await self.aio_client.TriggerWorkflow(
213
- request,
214
- metadata=get_metadata(self.token),
215
- )
216
-
217
- return WorkflowRunRef(
218
- workflow_run_id=resp.workflow_run_id,
219
- workflow_listener=self.pooled_workflow_listener,
220
- workflow_run_event_listener=self.listener_client,
221
- )
222
- except (grpc.RpcError, grpc.aio.AioRpcError) as e:
223
- if e.code() == grpc.StatusCode.ALREADY_EXISTS:
224
- raise DedupeViolationErr(e.details())
153
+ ## IMPORTANT: The `pooled_workflow_listener` must be created 1) lazily, and not at `init` time, and 2) on the
154
+ ## main thread. If 1) is not followed, you'll get an error about something being attached to the wrong event
155
+ ## loop. If 2) is not followed, you'll get an error about the event loop not being set up.
156
+ if not self.pooled_workflow_listener:
157
+ self.pooled_workflow_listener = PooledWorkflowRunListener(self.config)
225
158
 
226
- raise e
159
+ return await asyncio.to_thread(self.run_workflow, workflow_name, input, options)
227
160
 
228
- ## IMPORTANT: Keep this method's signature in sync with the wrapper in the OTel instrumentor
229
161
  @tenacity_retry
230
- async def run_workflows(
162
+ async def aio_run_workflows(
231
163
  self,
232
164
  workflows: list[WorkflowRunDict],
233
- options: TriggerWorkflowOptions | None = None,
234
- ) -> List[WorkflowRunRef]:
235
- if len(workflows) == 0:
236
- raise ValueError("No workflows to run")
237
-
165
+ options: TriggerWorkflowOptions = TriggerWorkflowOptions(),
166
+ ) -> list[WorkflowRunRef]:
167
+ ## IMPORTANT: The `pooled_workflow_listener` must be created 1) lazily, and not at `init` time, and 2) on the
168
+ ## main thread. If 1) is not followed, you'll get an error about something being attached to the wrong event
169
+ ## loop. If 2) is not followed, you'll get an error about the event loop not being set up.
238
170
  if not self.pooled_workflow_listener:
239
171
  self.pooled_workflow_listener = PooledWorkflowRunListener(self.config)
240
172
 
241
- namespace = self.namespace
242
-
243
- if (
244
- options is not None
245
- and "namespace" in options
246
- and options["namespace"] is not None
247
- ):
248
- namespace = options["namespace"]
249
- del options["namespace"]
250
-
251
- workflow_run_requests: TriggerWorkflowRequest = []
252
-
253
- for workflow in workflows:
254
- workflow_name = workflow["workflow_name"]
255
- input_data = workflow["input"]
256
- options = workflow["options"]
257
-
258
- if namespace != "" and not workflow_name.startswith(self.namespace):
259
- workflow_name = f"{namespace}{workflow_name}"
260
-
261
- # Prepare and trigger workflow for each workflow name and input
262
- request = self._prepare_workflow_request(workflow_name, input_data, options)
263
- workflow_run_requests.append(request)
264
-
265
- request = BulkTriggerWorkflowRequest(workflows=workflow_run_requests)
266
-
267
- resp: BulkTriggerWorkflowResponse = await self.aio_client.BulkTriggerWorkflow(
268
- request,
269
- metadata=get_metadata(self.token),
270
- )
271
-
272
- return [
273
- WorkflowRunRef(
274
- workflow_run_id=workflow_run_id,
275
- workflow_listener=self.pooled_workflow_listener,
276
- workflow_run_event_listener=self.listener_client,
277
- )
278
- for workflow_run_id in resp.workflow_run_ids
279
- ]
173
+ return await asyncio.to_thread(self.run_workflows, workflows, options)
280
174
 
281
175
  @tenacity_retry
282
- async def put_workflow(
176
+ async def aio_put_workflow(
283
177
  self,
284
178
  name: str,
285
- workflow: CreateWorkflowVersionOpts | WorkflowMeta,
286
- overrides: CreateWorkflowVersionOpts | None = None,
287
- ) -> WorkflowVersion:
288
- opts = self._prepare_put_workflow_request(name, workflow, overrides)
179
+ workflow: workflow_protos.CreateWorkflowVersionOpts,
180
+ overrides: workflow_protos.CreateWorkflowVersionOpts | None = None,
181
+ ) -> workflow_protos.WorkflowVersion:
182
+ ## IMPORTANT: The `pooled_workflow_listener` must be created 1) lazily, and not at `init` time, and 2) on the
183
+ ## main thread. If 1) is not followed, you'll get an error about something being attached to the wrong event
184
+ ## loop. If 2) is not followed, you'll get an error about the event loop not being set up.
185
+ if not self.pooled_workflow_listener:
186
+ self.pooled_workflow_listener = PooledWorkflowRunListener(self.config)
289
187
 
290
- return await self.aio_client.PutWorkflow(
291
- opts,
292
- metadata=get_metadata(self.token),
293
- )
188
+ return await asyncio.to_thread(self.put_workflow, name, workflow, overrides)
294
189
 
295
190
  @tenacity_retry
296
- async def put_rate_limit(
191
+ async def aio_put_rate_limit(
297
192
  self,
298
193
  key: str,
299
194
  limit: int,
300
195
  duration: RateLimitDuration = RateLimitDuration.SECOND,
301
- ):
302
- await self.aio_client.PutRateLimit(
303
- PutRateLimitRequest(
304
- key=key,
305
- limit=limit,
306
- duration=duration,
307
- ),
308
- metadata=get_metadata(self.token),
309
- )
196
+ ) -> None:
197
+ ## IMPORTANT: The `pooled_workflow_listener` must be created 1) lazily, and not at `init` time, and 2) on the
198
+ ## main thread. If 1) is not followed, you'll get an error about something being attached to the wrong event
199
+ ## loop. If 2) is not followed, you'll get an error about the event loop not being set up.
200
+ if not self.pooled_workflow_listener:
201
+ self.pooled_workflow_listener = PooledWorkflowRunListener(self.config)
202
+
203
+ return await asyncio.to_thread(self.put_rate_limit, key, limit, duration)
310
204
 
311
205
  @tenacity_retry
312
- async def schedule_workflow(
206
+ async def aio_schedule_workflow(
313
207
  self,
314
208
  name: str,
315
- schedules: List[Union[datetime, timestamp_pb2.Timestamp]],
316
- input={},
317
- options: ScheduleTriggerWorkflowOptions = None,
318
- ) -> WorkflowVersion:
319
- try:
320
- namespace = self.namespace
321
-
322
- if (
323
- options is not None
324
- and "namespace" in options
325
- and options["namespace"] is not None
326
- ):
327
- namespace = options["namespace"]
328
- del options["namespace"]
329
-
330
- if namespace != "" and not name.startswith(self.namespace):
331
- name = f"{namespace}{name}"
332
-
333
- request = self._prepare_schedule_workflow_request(
334
- name, schedules, input, options
335
- )
336
-
337
- return await self.aio_client.ScheduleWorkflow(
338
- request,
339
- metadata=get_metadata(self.token),
340
- )
341
- except (grpc.aio.AioRpcError, grpc.RpcError) as e:
342
- if e.code() == grpc.StatusCode.ALREADY_EXISTS:
343
- raise DedupeViolationErr(e.details())
344
-
345
- raise e
346
-
209
+ schedules: list[Union[datetime, timestamp_pb2.Timestamp]],
210
+ input: JSONSerializableMapping = {},
211
+ options: ScheduleTriggerWorkflowOptions = ScheduleTriggerWorkflowOptions(),
212
+ ) -> workflow_protos.WorkflowVersion:
213
+ ## IMPORTANT: The `pooled_workflow_listener` must be created 1) lazily, and not at `init` time, and 2) on the
214
+ ## main thread. If 1) is not followed, you'll get an error about something being attached to the wrong event
215
+ ## loop. If 2) is not followed, you'll get an error about the event loop not being set up.
216
+ if not self.pooled_workflow_listener:
217
+ self.pooled_workflow_listener = PooledWorkflowRunListener(self.config)
347
218
 
348
- class AdminClient(AdminClientBase):
349
- def __init__(self, config: ClientConfig):
350
- conn = new_conn(config)
351
- self.config = config
352
- self.client = WorkflowServiceStub(conn)
353
- self.aio = AdminClientAioImpl(config)
354
- self.token = config.token
355
- self.listener_client = new_listener(config)
356
- self.namespace = config.namespace
219
+ return await asyncio.to_thread(
220
+ self.schedule_workflow, name, schedules, input, options
221
+ )
357
222
 
358
223
  @tenacity_retry
359
224
  def put_workflow(
360
225
  self,
361
226
  name: str,
362
- workflow: CreateWorkflowVersionOpts | WorkflowMeta,
363
- overrides: CreateWorkflowVersionOpts | None = None,
364
- ) -> WorkflowVersion:
227
+ workflow: workflow_protos.CreateWorkflowVersionOpts,
228
+ overrides: workflow_protos.CreateWorkflowVersionOpts | None = None,
229
+ ) -> workflow_protos.WorkflowVersion:
365
230
  opts = self._prepare_put_workflow_request(name, workflow, overrides)
366
231
 
367
- resp: WorkflowVersion = self.client.PutWorkflow(
232
+ resp: workflow_protos.WorkflowVersion = self.client.PutWorkflow(
368
233
  opts,
369
234
  metadata=get_metadata(self.token),
370
235
  )
@@ -376,13 +241,16 @@ class AdminClient(AdminClientBase):
376
241
  self,
377
242
  key: str,
378
243
  limit: int,
379
- duration: Union[RateLimitDuration.Value, str] = RateLimitDuration.SECOND,
380
- ):
244
+ duration: RateLimitDuration = RateLimitDuration.SECOND,
245
+ ) -> None:
246
+ duration_proto = convert_python_enum_to_proto(
247
+ duration, workflow_protos.RateLimitDuration
248
+ )
381
249
  self.client.PutRateLimit(
382
- PutRateLimitRequest(
250
+ workflow_protos.PutRateLimitRequest(
383
251
  key=key,
384
252
  limit=limit,
385
- duration=duration,
253
+ duration=maybe_int_to_str(duration_proto),
386
254
  ),
387
255
  metadata=get_metadata(self.token),
388
256
  )
@@ -391,20 +259,12 @@ class AdminClient(AdminClientBase):
391
259
  def schedule_workflow(
392
260
  self,
393
261
  name: str,
394
- schedules: List[Union[datetime, timestamp_pb2.Timestamp]],
395
- input={},
396
- options: ScheduleTriggerWorkflowOptions = None,
397
- ) -> WorkflowVersion:
262
+ schedules: list[Union[datetime, timestamp_pb2.Timestamp]],
263
+ input: JSONSerializableMapping = {},
264
+ options: ScheduleTriggerWorkflowOptions = ScheduleTriggerWorkflowOptions(),
265
+ ) -> workflow_protos.WorkflowVersion:
398
266
  try:
399
- namespace = self.namespace
400
-
401
- if (
402
- options is not None
403
- and "namespace" in options
404
- and options["namespace"] is not None
405
- ):
406
- namespace = options["namespace"]
407
- del options["namespace"]
267
+ namespace = options.namespace or self.namespace
408
268
 
409
269
  if namespace != "" and not name.startswith(self.namespace):
410
270
  name = f"{namespace}{name}"
@@ -413,9 +273,12 @@ class AdminClient(AdminClientBase):
413
273
  name, schedules, input, options
414
274
  )
415
275
 
416
- return self.client.ScheduleWorkflow(
417
- request,
418
- metadata=get_metadata(self.token),
276
+ return cast(
277
+ workflow_protos.WorkflowVersion,
278
+ self.client.ScheduleWorkflow(
279
+ request,
280
+ metadata=get_metadata(self.token),
281
+ ),
419
282
  )
420
283
  except (grpc.RpcError, grpc.aio.AioRpcError) as e:
421
284
  if e.code() == grpc.StatusCode.ALREADY_EXISTS:
@@ -426,30 +289,28 @@ class AdminClient(AdminClientBase):
426
289
  ## IMPORTANT: Keep this method's signature in sync with the wrapper in the OTel instrumentor
427
290
  @tenacity_retry
428
291
  def run_workflow(
429
- self, workflow_name: str, input: any, options: TriggerWorkflowOptions = None
292
+ self,
293
+ workflow_name: str,
294
+ input: JSONSerializableMapping,
295
+ options: TriggerWorkflowOptions = TriggerWorkflowOptions(),
430
296
  ) -> WorkflowRunRef:
431
297
  try:
432
298
  if not self.pooled_workflow_listener:
433
299
  self.pooled_workflow_listener = PooledWorkflowRunListener(self.config)
434
300
 
435
- namespace = self.namespace
436
-
437
- ## TODO: Factor this out - it's repeated a lot of places
438
- if (
439
- options is not None
440
- and "namespace" in options
441
- and options["namespace"] is not None
442
- ):
443
- namespace = options.pop("namespace")
301
+ namespace = options.namespace or self.namespace
444
302
 
445
303
  if namespace != "" and not workflow_name.startswith(self.namespace):
446
304
  workflow_name = f"{namespace}{workflow_name}"
447
305
 
448
306
  request = self._prepare_workflow_request(workflow_name, input, options)
449
307
 
450
- resp: TriggerWorkflowResponse = self.client.TriggerWorkflow(
451
- request,
452
- metadata=get_metadata(self.token),
308
+ resp = cast(
309
+ workflow_protos.TriggerWorkflowResponse,
310
+ self.client.TriggerWorkflow(
311
+ request,
312
+ metadata=get_metadata(self.token),
313
+ ),
453
314
  )
454
315
 
455
316
  return WorkflowRunRef(
@@ -463,43 +324,43 @@ class AdminClient(AdminClientBase):
463
324
 
464
325
  raise e
465
326
 
327
+ def _prepare_workflow_run_request(
328
+ self, workflow: WorkflowRunDict, options: TriggerWorkflowOptions
329
+ ) -> workflow_protos.TriggerWorkflowRequest:
330
+ workflow_name = workflow.workflow_name
331
+ input_data = workflow.input
332
+ options = workflow.options
333
+
334
+ namespace = options.namespace or self.namespace
335
+
336
+ if namespace != "" and not workflow_name.startswith(self.namespace):
337
+ workflow_name = f"{namespace}{workflow_name}"
338
+
339
+ return self._prepare_workflow_request(workflow_name, input_data, options)
340
+
466
341
  ## IMPORTANT: Keep this method's signature in sync with the wrapper in the OTel instrumentor
467
342
  @tenacity_retry
468
343
  def run_workflows(
469
- self, workflows: List[WorkflowRunDict], options: TriggerWorkflowOptions = None
344
+ self,
345
+ workflows: list[WorkflowRunDict],
346
+ options: TriggerWorkflowOptions = TriggerWorkflowOptions(),
470
347
  ) -> list[WorkflowRunRef]:
471
- workflow_run_requests: TriggerWorkflowRequest = []
472
348
  if not self.pooled_workflow_listener:
473
349
  self.pooled_workflow_listener = PooledWorkflowRunListener(self.config)
474
350
 
475
- for workflow in workflows:
476
- workflow_name = workflow["workflow_name"]
477
- input_data = workflow["input"]
478
- options = workflow["options"]
479
-
480
- namespace = self.namespace
481
-
482
- if (
483
- options is not None
484
- and "namespace" in options
485
- and options["namespace"] is not None
486
- ):
487
- namespace = options["namespace"]
488
- del options["namespace"]
489
-
490
- if namespace != "" and not workflow_name.startswith(self.namespace):
491
- workflow_name = f"{namespace}{workflow_name}"
492
-
493
- # Prepare and trigger workflow for each workflow name and input
494
- request = self._prepare_workflow_request(workflow_name, input_data, options)
495
-
496
- workflow_run_requests.append(request)
497
-
498
- request = BulkTriggerWorkflowRequest(workflows=workflow_run_requests)
351
+ bulk_request = workflow_protos.BulkTriggerWorkflowRequest(
352
+ workflows=[
353
+ self._prepare_workflow_run_request(workflow, options)
354
+ for workflow in workflows
355
+ ]
356
+ )
499
357
 
500
- resp: BulkTriggerWorkflowResponse = self.client.BulkTriggerWorkflow(
501
- request,
502
- metadata=get_metadata(self.token),
358
+ resp = cast(
359
+ workflow_protos.BulkTriggerWorkflowResponse,
360
+ self.client.BulkTriggerWorkflow(
361
+ bulk_request,
362
+ metadata=get_metadata(self.token),
363
+ ),
503
364
  )
504
365
 
505
366
  return [
@@ -511,32 +372,12 @@ class AdminClient(AdminClientBase):
511
372
  for workflow_run_id in resp.workflow_run_ids
512
373
  ]
513
374
 
514
- def run(
515
- self,
516
- function: Union[str, Callable[[Any], T]],
517
- input: any,
518
- options: TriggerWorkflowOptions = None,
519
- ) -> "RunRef[T]":
520
- workflow_name = function
521
-
522
- if not isinstance(function, str):
523
- workflow_name = function.function_name
524
-
525
- wrr = self.run_workflow(workflow_name, input, options)
526
-
527
- return RunRef[T](
528
- wrr.workflow_run_id, wrr.workflow_listener, wrr.workflow_run_event_listener
529
- )
530
-
531
375
  def get_workflow_run(self, workflow_run_id: str) -> WorkflowRunRef:
532
- try:
533
- if not self.pooled_workflow_listener:
534
- self.pooled_workflow_listener = PooledWorkflowRunListener(self.config)
376
+ if not self.pooled_workflow_listener:
377
+ self.pooled_workflow_listener = PooledWorkflowRunListener(self.config)
535
378
 
536
- return WorkflowRunRef(
537
- workflow_run_id=workflow_run_id,
538
- workflow_listener=self.pooled_workflow_listener,
539
- workflow_run_event_listener=self.listener_client,
540
- )
541
- except grpc.RpcError as e:
542
- raise ValueError(f"Could not get workflow run: {e}")
379
+ return WorkflowRunRef(
380
+ workflow_run_id=workflow_run_id,
381
+ workflow_listener=self.pooled_workflow_listener,
382
+ workflow_run_event_listener=self.listener_client,
383
+ )