hatchet-sdk 0.47.1__py3-none-any.whl → 1.0.0a1__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.

Potentially problematic release.


This version of hatchet-sdk might be problematic. Click here for more details.

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