hatchet-sdk 1.18.1__py3-none-any.whl → 1.20.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.

Potentially problematic release.


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

Files changed (234) hide show
  1. hatchet_sdk/clients/dispatcher/action_listener.py +0 -1
  2. hatchet_sdk/clients/dispatcher/dispatcher.py +0 -30
  3. hatchet_sdk/hatchet.py +0 -20
  4. hatchet_sdk/opentelemetry/instrumentor.py +1 -27
  5. hatchet_sdk/runnables/action.py +2 -5
  6. hatchet_sdk/runnables/task.py +0 -1
  7. hatchet_sdk/utils/opentelemetry.py +0 -1
  8. hatchet_sdk/worker/action_listener_process.py +0 -29
  9. hatchet_sdk/worker/runner/runner.py +1 -105
  10. {hatchet_sdk-1.18.1.dist-info → hatchet_sdk-1.20.0.dist-info}/METADATA +2 -3
  11. {hatchet_sdk-1.18.1.dist-info → hatchet_sdk-1.20.0.dist-info}/RECORD +13 -234
  12. hatchet_sdk/v0/__init__.py +0 -251
  13. hatchet_sdk/v0/client.py +0 -119
  14. hatchet_sdk/v0/clients/admin.py +0 -541
  15. hatchet_sdk/v0/clients/dispatcher/action_listener.py +0 -422
  16. hatchet_sdk/v0/clients/dispatcher/dispatcher.py +0 -204
  17. hatchet_sdk/v0/clients/event_ts.py +0 -28
  18. hatchet_sdk/v0/clients/events.py +0 -182
  19. hatchet_sdk/v0/clients/rest/__init__.py +0 -307
  20. hatchet_sdk/v0/clients/rest/api/__init__.py +0 -19
  21. hatchet_sdk/v0/clients/rest/api/api_token_api.py +0 -858
  22. hatchet_sdk/v0/clients/rest/api/default_api.py +0 -2259
  23. hatchet_sdk/v0/clients/rest/api/event_api.py +0 -2548
  24. hatchet_sdk/v0/clients/rest/api/github_api.py +0 -331
  25. hatchet_sdk/v0/clients/rest/api/healthcheck_api.py +0 -483
  26. hatchet_sdk/v0/clients/rest/api/log_api.py +0 -449
  27. hatchet_sdk/v0/clients/rest/api/metadata_api.py +0 -728
  28. hatchet_sdk/v0/clients/rest/api/rate_limits_api.py +0 -423
  29. hatchet_sdk/v0/clients/rest/api/slack_api.py +0 -577
  30. hatchet_sdk/v0/clients/rest/api/sns_api.py +0 -872
  31. hatchet_sdk/v0/clients/rest/api/step_run_api.py +0 -2202
  32. hatchet_sdk/v0/clients/rest/api/tenant_api.py +0 -4430
  33. hatchet_sdk/v0/clients/rest/api/user_api.py +0 -2888
  34. hatchet_sdk/v0/clients/rest/api/worker_api.py +0 -858
  35. hatchet_sdk/v0/clients/rest/api/workflow_api.py +0 -6312
  36. hatchet_sdk/v0/clients/rest/api/workflow_run_api.py +0 -1932
  37. hatchet_sdk/v0/clients/rest/api/workflow_runs_api.py +0 -610
  38. hatchet_sdk/v0/clients/rest/api_client.py +0 -759
  39. hatchet_sdk/v0/clients/rest/api_response.py +0 -22
  40. hatchet_sdk/v0/clients/rest/configuration.py +0 -611
  41. hatchet_sdk/v0/clients/rest/exceptions.py +0 -200
  42. hatchet_sdk/v0/clients/rest/models/__init__.py +0 -274
  43. hatchet_sdk/v0/clients/rest/models/accept_invite_request.py +0 -83
  44. hatchet_sdk/v0/clients/rest/models/api_error.py +0 -102
  45. hatchet_sdk/v0/clients/rest/models/api_errors.py +0 -100
  46. hatchet_sdk/v0/clients/rest/models/api_meta.py +0 -144
  47. hatchet_sdk/v0/clients/rest/models/api_meta_auth.py +0 -85
  48. hatchet_sdk/v0/clients/rest/models/api_meta_integration.py +0 -88
  49. hatchet_sdk/v0/clients/rest/models/api_meta_posthog.py +0 -90
  50. hatchet_sdk/v0/clients/rest/models/api_resource_meta.py +0 -98
  51. hatchet_sdk/v0/clients/rest/models/api_token.py +0 -105
  52. hatchet_sdk/v0/clients/rest/models/bulk_create_event_request.py +0 -100
  53. hatchet_sdk/v0/clients/rest/models/bulk_create_event_response.py +0 -110
  54. hatchet_sdk/v0/clients/rest/models/cancel_event_request.py +0 -85
  55. hatchet_sdk/v0/clients/rest/models/cancel_step_run_request.py +0 -83
  56. hatchet_sdk/v0/clients/rest/models/concurrency_limit_strategy.py +0 -39
  57. hatchet_sdk/v0/clients/rest/models/create_api_token_request.py +0 -92
  58. hatchet_sdk/v0/clients/rest/models/create_api_token_response.py +0 -83
  59. hatchet_sdk/v0/clients/rest/models/create_cron_workflow_trigger_request.py +0 -98
  60. hatchet_sdk/v0/clients/rest/models/create_event_request.py +0 -95
  61. hatchet_sdk/v0/clients/rest/models/create_pull_request_from_step_run.py +0 -83
  62. hatchet_sdk/v0/clients/rest/models/create_sns_integration_request.py +0 -85
  63. hatchet_sdk/v0/clients/rest/models/create_tenant_alert_email_group_request.py +0 -83
  64. hatchet_sdk/v0/clients/rest/models/create_tenant_invite_request.py +0 -86
  65. hatchet_sdk/v0/clients/rest/models/create_tenant_request.py +0 -84
  66. hatchet_sdk/v0/clients/rest/models/cron_workflows.py +0 -131
  67. hatchet_sdk/v0/clients/rest/models/cron_workflows_list.py +0 -110
  68. hatchet_sdk/v0/clients/rest/models/cron_workflows_method.py +0 -37
  69. hatchet_sdk/v0/clients/rest/models/cron_workflows_order_by_field.py +0 -37
  70. hatchet_sdk/v0/clients/rest/models/event.py +0 -143
  71. hatchet_sdk/v0/clients/rest/models/event_data.py +0 -83
  72. hatchet_sdk/v0/clients/rest/models/event_key_list.py +0 -98
  73. hatchet_sdk/v0/clients/rest/models/event_list.py +0 -110
  74. hatchet_sdk/v0/clients/rest/models/event_order_by_direction.py +0 -37
  75. hatchet_sdk/v0/clients/rest/models/event_order_by_field.py +0 -36
  76. hatchet_sdk/v0/clients/rest/models/event_update_cancel200_response.py +0 -85
  77. hatchet_sdk/v0/clients/rest/models/event_workflow_run_summary.py +0 -116
  78. hatchet_sdk/v0/clients/rest/models/events.py +0 -110
  79. hatchet_sdk/v0/clients/rest/models/get_step_run_diff_response.py +0 -100
  80. hatchet_sdk/v0/clients/rest/models/github_app_installation.py +0 -107
  81. hatchet_sdk/v0/clients/rest/models/github_branch.py +0 -86
  82. hatchet_sdk/v0/clients/rest/models/github_repo.py +0 -86
  83. hatchet_sdk/v0/clients/rest/models/info_get_version200_response.py +0 -83
  84. hatchet_sdk/v0/clients/rest/models/job.py +0 -132
  85. hatchet_sdk/v0/clients/rest/models/job_run.py +0 -176
  86. hatchet_sdk/v0/clients/rest/models/job_run_status.py +0 -41
  87. hatchet_sdk/v0/clients/rest/models/link_github_repository_request.py +0 -106
  88. hatchet_sdk/v0/clients/rest/models/list_api_tokens_response.py +0 -110
  89. hatchet_sdk/v0/clients/rest/models/list_github_app_installations_response.py +0 -112
  90. hatchet_sdk/v0/clients/rest/models/list_pull_requests_response.py +0 -100
  91. hatchet_sdk/v0/clients/rest/models/list_slack_webhooks.py +0 -110
  92. hatchet_sdk/v0/clients/rest/models/list_sns_integrations.py +0 -110
  93. hatchet_sdk/v0/clients/rest/models/log_line.py +0 -94
  94. hatchet_sdk/v0/clients/rest/models/log_line_level.py +0 -39
  95. hatchet_sdk/v0/clients/rest/models/log_line_list.py +0 -110
  96. hatchet_sdk/v0/clients/rest/models/log_line_order_by_direction.py +0 -37
  97. hatchet_sdk/v0/clients/rest/models/log_line_order_by_field.py +0 -36
  98. hatchet_sdk/v0/clients/rest/models/pagination_response.py +0 -95
  99. hatchet_sdk/v0/clients/rest/models/pull_request.py +0 -112
  100. hatchet_sdk/v0/clients/rest/models/pull_request_state.py +0 -37
  101. hatchet_sdk/v0/clients/rest/models/queue_metrics.py +0 -97
  102. hatchet_sdk/v0/clients/rest/models/rate_limit.py +0 -117
  103. hatchet_sdk/v0/clients/rest/models/rate_limit_list.py +0 -110
  104. hatchet_sdk/v0/clients/rest/models/rate_limit_order_by_direction.py +0 -37
  105. hatchet_sdk/v0/clients/rest/models/rate_limit_order_by_field.py +0 -38
  106. hatchet_sdk/v0/clients/rest/models/recent_step_runs.py +0 -118
  107. hatchet_sdk/v0/clients/rest/models/reject_invite_request.py +0 -83
  108. hatchet_sdk/v0/clients/rest/models/replay_event_request.py +0 -85
  109. hatchet_sdk/v0/clients/rest/models/replay_workflow_runs_request.py +0 -85
  110. hatchet_sdk/v0/clients/rest/models/replay_workflow_runs_response.py +0 -100
  111. hatchet_sdk/v0/clients/rest/models/rerun_step_run_request.py +0 -83
  112. hatchet_sdk/v0/clients/rest/models/schedule_workflow_run_request.py +0 -92
  113. hatchet_sdk/v0/clients/rest/models/scheduled_run_status.py +0 -42
  114. hatchet_sdk/v0/clients/rest/models/scheduled_workflows.py +0 -149
  115. hatchet_sdk/v0/clients/rest/models/scheduled_workflows_list.py +0 -110
  116. hatchet_sdk/v0/clients/rest/models/scheduled_workflows_method.py +0 -37
  117. hatchet_sdk/v0/clients/rest/models/scheduled_workflows_order_by_field.py +0 -37
  118. hatchet_sdk/v0/clients/rest/models/semaphore_slots.py +0 -113
  119. hatchet_sdk/v0/clients/rest/models/slack_webhook.py +0 -127
  120. hatchet_sdk/v0/clients/rest/models/sns_integration.py +0 -114
  121. hatchet_sdk/v0/clients/rest/models/step.py +0 -123
  122. hatchet_sdk/v0/clients/rest/models/step_run.py +0 -202
  123. hatchet_sdk/v0/clients/rest/models/step_run_archive.py +0 -142
  124. hatchet_sdk/v0/clients/rest/models/step_run_archive_list.py +0 -110
  125. hatchet_sdk/v0/clients/rest/models/step_run_diff.py +0 -91
  126. hatchet_sdk/v0/clients/rest/models/step_run_event.py +0 -122
  127. hatchet_sdk/v0/clients/rest/models/step_run_event_list.py +0 -110
  128. hatchet_sdk/v0/clients/rest/models/step_run_event_reason.py +0 -52
  129. hatchet_sdk/v0/clients/rest/models/step_run_event_severity.py +0 -38
  130. hatchet_sdk/v0/clients/rest/models/step_run_status.py +0 -44
  131. hatchet_sdk/v0/clients/rest/models/tenant.py +0 -118
  132. hatchet_sdk/v0/clients/rest/models/tenant_alert_email_group.py +0 -98
  133. hatchet_sdk/v0/clients/rest/models/tenant_alert_email_group_list.py +0 -112
  134. hatchet_sdk/v0/clients/rest/models/tenant_alerting_settings.py +0 -143
  135. hatchet_sdk/v0/clients/rest/models/tenant_invite.py +0 -120
  136. hatchet_sdk/v0/clients/rest/models/tenant_invite_list.py +0 -110
  137. hatchet_sdk/v0/clients/rest/models/tenant_list.py +0 -110
  138. hatchet_sdk/v0/clients/rest/models/tenant_member.py +0 -123
  139. hatchet_sdk/v0/clients/rest/models/tenant_member_list.py +0 -110
  140. hatchet_sdk/v0/clients/rest/models/tenant_member_role.py +0 -38
  141. hatchet_sdk/v0/clients/rest/models/tenant_queue_metrics.py +0 -116
  142. hatchet_sdk/v0/clients/rest/models/tenant_resource.py +0 -40
  143. hatchet_sdk/v0/clients/rest/models/tenant_resource_limit.py +0 -135
  144. hatchet_sdk/v0/clients/rest/models/tenant_resource_policy.py +0 -102
  145. hatchet_sdk/v0/clients/rest/models/tenant_step_run_queue_metrics.py +0 -83
  146. hatchet_sdk/v0/clients/rest/models/trigger_workflow_run_request.py +0 -91
  147. hatchet_sdk/v0/clients/rest/models/update_tenant_alert_email_group_request.py +0 -83
  148. hatchet_sdk/v0/clients/rest/models/update_tenant_invite_request.py +0 -85
  149. hatchet_sdk/v0/clients/rest/models/update_tenant_request.py +0 -137
  150. hatchet_sdk/v0/clients/rest/models/update_worker_request.py +0 -87
  151. hatchet_sdk/v0/clients/rest/models/user.py +0 -126
  152. hatchet_sdk/v0/clients/rest/models/user_change_password_request.py +0 -88
  153. hatchet_sdk/v0/clients/rest/models/user_login_request.py +0 -86
  154. hatchet_sdk/v0/clients/rest/models/user_register_request.py +0 -91
  155. hatchet_sdk/v0/clients/rest/models/user_tenant_memberships_list.py +0 -110
  156. hatchet_sdk/v0/clients/rest/models/user_tenant_public.py +0 -86
  157. hatchet_sdk/v0/clients/rest/models/webhook_worker.py +0 -100
  158. hatchet_sdk/v0/clients/rest/models/webhook_worker_create_request.py +0 -94
  159. hatchet_sdk/v0/clients/rest/models/webhook_worker_create_response.py +0 -98
  160. hatchet_sdk/v0/clients/rest/models/webhook_worker_created.py +0 -102
  161. hatchet_sdk/v0/clients/rest/models/webhook_worker_list_response.py +0 -110
  162. hatchet_sdk/v0/clients/rest/models/webhook_worker_request.py +0 -102
  163. hatchet_sdk/v0/clients/rest/models/webhook_worker_request_list_response.py +0 -104
  164. hatchet_sdk/v0/clients/rest/models/webhook_worker_request_method.py +0 -38
  165. hatchet_sdk/v0/clients/rest/models/worker.py +0 -239
  166. hatchet_sdk/v0/clients/rest/models/worker_label.py +0 -102
  167. hatchet_sdk/v0/clients/rest/models/worker_list.py +0 -110
  168. hatchet_sdk/v0/clients/rest/models/worker_runtime_info.py +0 -103
  169. hatchet_sdk/v0/clients/rest/models/worker_runtime_sdks.py +0 -38
  170. hatchet_sdk/v0/clients/rest/models/worker_type.py +0 -38
  171. hatchet_sdk/v0/clients/rest/models/workflow.py +0 -165
  172. hatchet_sdk/v0/clients/rest/models/workflow_concurrency.py +0 -107
  173. hatchet_sdk/v0/clients/rest/models/workflow_deployment_config.py +0 -136
  174. hatchet_sdk/v0/clients/rest/models/workflow_kind.py +0 -38
  175. hatchet_sdk/v0/clients/rest/models/workflow_list.py +0 -120
  176. hatchet_sdk/v0/clients/rest/models/workflow_metrics.py +0 -97
  177. hatchet_sdk/v0/clients/rest/models/workflow_run.py +0 -188
  178. hatchet_sdk/v0/clients/rest/models/workflow_run_cancel200_response.py +0 -85
  179. hatchet_sdk/v0/clients/rest/models/workflow_run_list.py +0 -110
  180. hatchet_sdk/v0/clients/rest/models/workflow_run_order_by_direction.py +0 -37
  181. hatchet_sdk/v0/clients/rest/models/workflow_run_order_by_field.py +0 -39
  182. hatchet_sdk/v0/clients/rest/models/workflow_run_shape.py +0 -186
  183. hatchet_sdk/v0/clients/rest/models/workflow_run_status.py +0 -42
  184. hatchet_sdk/v0/clients/rest/models/workflow_run_triggered_by.py +0 -112
  185. hatchet_sdk/v0/clients/rest/models/workflow_runs_cancel_request.py +0 -85
  186. hatchet_sdk/v0/clients/rest/models/workflow_runs_metrics.py +0 -94
  187. hatchet_sdk/v0/clients/rest/models/workflow_runs_metrics_counts.py +0 -104
  188. hatchet_sdk/v0/clients/rest/models/workflow_tag.py +0 -84
  189. hatchet_sdk/v0/clients/rest/models/workflow_trigger_cron_ref.py +0 -86
  190. hatchet_sdk/v0/clients/rest/models/workflow_trigger_event_ref.py +0 -86
  191. hatchet_sdk/v0/clients/rest/models/workflow_triggers.py +0 -141
  192. hatchet_sdk/v0/clients/rest/models/workflow_update_request.py +0 -85
  193. hatchet_sdk/v0/clients/rest/models/workflow_version.py +0 -170
  194. hatchet_sdk/v0/clients/rest/models/workflow_version_concurrency.py +0 -114
  195. hatchet_sdk/v0/clients/rest/models/workflow_version_definition.py +0 -85
  196. hatchet_sdk/v0/clients/rest/models/workflow_version_meta.py +0 -123
  197. hatchet_sdk/v0/clients/rest/models/workflow_workers_count.py +0 -95
  198. hatchet_sdk/v0/clients/rest/rest.py +0 -187
  199. hatchet_sdk/v0/clients/rest/tenacity_utils.py +0 -39
  200. hatchet_sdk/v0/clients/rest_client.py +0 -622
  201. hatchet_sdk/v0/clients/run_event_listener.py +0 -260
  202. hatchet_sdk/v0/clients/workflow_listener.py +0 -277
  203. hatchet_sdk/v0/connection.py +0 -63
  204. hatchet_sdk/v0/context/__init__.py +0 -1
  205. hatchet_sdk/v0/context/context.py +0 -446
  206. hatchet_sdk/v0/context/worker_context.py +0 -28
  207. hatchet_sdk/v0/features/cron.py +0 -286
  208. hatchet_sdk/v0/features/scheduled.py +0 -248
  209. hatchet_sdk/v0/hatchet.py +0 -310
  210. hatchet_sdk/v0/labels.py +0 -10
  211. hatchet_sdk/v0/loader.py +0 -244
  212. hatchet_sdk/v0/metadata.py +0 -2
  213. hatchet_sdk/v0/opentelemetry/instrumentor.py +0 -393
  214. hatchet_sdk/v0/rate_limit.py +0 -126
  215. hatchet_sdk/v0/semver.py +0 -30
  216. hatchet_sdk/v0/token.py +0 -27
  217. hatchet_sdk/v0/utils/aio_utils.py +0 -137
  218. hatchet_sdk/v0/utils/backoff.py +0 -9
  219. hatchet_sdk/v0/utils/types.py +0 -8
  220. hatchet_sdk/v0/utils/typing.py +0 -12
  221. hatchet_sdk/v0/v2/callable.py +0 -202
  222. hatchet_sdk/v0/v2/concurrency.py +0 -47
  223. hatchet_sdk/v0/v2/hatchet.py +0 -224
  224. hatchet_sdk/v0/worker/__init__.py +0 -1
  225. hatchet_sdk/v0/worker/action_listener_process.py +0 -294
  226. hatchet_sdk/v0/worker/runner/run_loop_manager.py +0 -112
  227. hatchet_sdk/v0/worker/runner/runner.py +0 -460
  228. hatchet_sdk/v0/worker/runner/utils/capture_logs.py +0 -81
  229. hatchet_sdk/v0/worker/runner/utils/error_with_traceback.py +0 -6
  230. hatchet_sdk/v0/worker/worker.py +0 -391
  231. hatchet_sdk/v0/workflow.py +0 -261
  232. hatchet_sdk/v0/workflow_run.py +0 -59
  233. {hatchet_sdk-1.18.1.dist-info → hatchet_sdk-1.20.0.dist-info}/WHEEL +0 -0
  234. {hatchet_sdk-1.18.1.dist-info → hatchet_sdk-1.20.0.dist-info}/entry_points.txt +0 -0
@@ -1,260 +0,0 @@
1
- import asyncio
2
- import json
3
- from typing import AsyncGenerator
4
-
5
- import grpc
6
-
7
- from hatchet_sdk.contracts.dispatcher_pb2 import (
8
- RESOURCE_TYPE_STEP_RUN,
9
- RESOURCE_TYPE_WORKFLOW_RUN,
10
- ResourceEventType,
11
- SubscribeToWorkflowEventsRequest,
12
- WorkflowEvent,
13
- )
14
- from hatchet_sdk.contracts.dispatcher_pb2_grpc import DispatcherStub
15
- from hatchet_sdk.v0.connection import new_conn
16
-
17
- from ..loader import ClientConfig
18
- from ..metadata import get_metadata
19
-
20
- DEFAULT_ACTION_LISTENER_RETRY_INTERVAL = 5 # seconds
21
- DEFAULT_ACTION_LISTENER_RETRY_COUNT = 5
22
-
23
-
24
- class StepRunEventType:
25
- STEP_RUN_EVENT_TYPE_STARTED = "STEP_RUN_EVENT_TYPE_STARTED"
26
- STEP_RUN_EVENT_TYPE_COMPLETED = "STEP_RUN_EVENT_TYPE_COMPLETED"
27
- STEP_RUN_EVENT_TYPE_FAILED = "STEP_RUN_EVENT_TYPE_FAILED"
28
- STEP_RUN_EVENT_TYPE_CANCELLED = "STEP_RUN_EVENT_TYPE_CANCELLED"
29
- STEP_RUN_EVENT_TYPE_TIMED_OUT = "STEP_RUN_EVENT_TYPE_TIMED_OUT"
30
- STEP_RUN_EVENT_TYPE_STREAM = "STEP_RUN_EVENT_TYPE_STREAM"
31
-
32
-
33
- class WorkflowRunEventType:
34
- WORKFLOW_RUN_EVENT_TYPE_STARTED = "WORKFLOW_RUN_EVENT_TYPE_STARTED"
35
- WORKFLOW_RUN_EVENT_TYPE_COMPLETED = "WORKFLOW_RUN_EVENT_TYPE_COMPLETED"
36
- WORKFLOW_RUN_EVENT_TYPE_FAILED = "WORKFLOW_RUN_EVENT_TYPE_FAILED"
37
- WORKFLOW_RUN_EVENT_TYPE_CANCELLED = "WORKFLOW_RUN_EVENT_TYPE_CANCELLED"
38
- WORKFLOW_RUN_EVENT_TYPE_TIMED_OUT = "WORKFLOW_RUN_EVENT_TYPE_TIMED_OUT"
39
-
40
-
41
- step_run_event_type_mapping = {
42
- ResourceEventType.RESOURCE_EVENT_TYPE_STARTED: StepRunEventType.STEP_RUN_EVENT_TYPE_STARTED,
43
- ResourceEventType.RESOURCE_EVENT_TYPE_COMPLETED: StepRunEventType.STEP_RUN_EVENT_TYPE_COMPLETED,
44
- ResourceEventType.RESOURCE_EVENT_TYPE_FAILED: StepRunEventType.STEP_RUN_EVENT_TYPE_FAILED,
45
- ResourceEventType.RESOURCE_EVENT_TYPE_CANCELLED: StepRunEventType.STEP_RUN_EVENT_TYPE_CANCELLED,
46
- ResourceEventType.RESOURCE_EVENT_TYPE_TIMED_OUT: StepRunEventType.STEP_RUN_EVENT_TYPE_TIMED_OUT,
47
- ResourceEventType.RESOURCE_EVENT_TYPE_STREAM: StepRunEventType.STEP_RUN_EVENT_TYPE_STREAM,
48
- }
49
-
50
- workflow_run_event_type_mapping = {
51
- ResourceEventType.RESOURCE_EVENT_TYPE_STARTED: WorkflowRunEventType.WORKFLOW_RUN_EVENT_TYPE_STARTED,
52
- ResourceEventType.RESOURCE_EVENT_TYPE_COMPLETED: WorkflowRunEventType.WORKFLOW_RUN_EVENT_TYPE_COMPLETED,
53
- ResourceEventType.RESOURCE_EVENT_TYPE_FAILED: WorkflowRunEventType.WORKFLOW_RUN_EVENT_TYPE_FAILED,
54
- ResourceEventType.RESOURCE_EVENT_TYPE_CANCELLED: WorkflowRunEventType.WORKFLOW_RUN_EVENT_TYPE_CANCELLED,
55
- ResourceEventType.RESOURCE_EVENT_TYPE_TIMED_OUT: WorkflowRunEventType.WORKFLOW_RUN_EVENT_TYPE_TIMED_OUT,
56
- }
57
-
58
-
59
- class StepRunEvent:
60
- def __init__(self, type: StepRunEventType, payload: str):
61
- self.type = type
62
- self.payload = payload
63
-
64
-
65
- def new_listener(config: ClientConfig):
66
- return RunEventListenerClient(config=config)
67
-
68
-
69
- class RunEventListener:
70
-
71
- workflow_run_id: str = None
72
- additional_meta_kv: tuple[str, str] = None
73
-
74
- def __init__(self, client: DispatcherStub, token: str):
75
- self.client = client
76
- self.stop_signal = False
77
- self.token = token
78
-
79
- @classmethod
80
- def for_run_id(cls, workflow_run_id: str, client: DispatcherStub, token: str):
81
- listener = RunEventListener(client, token)
82
- listener.workflow_run_id = workflow_run_id
83
- return listener
84
-
85
- @classmethod
86
- def for_additional_meta(
87
- cls, key: str, value: str, client: DispatcherStub, token: str
88
- ):
89
- listener = RunEventListener(client, token)
90
- listener.additional_meta_kv = (key, value)
91
- return listener
92
-
93
- def abort(self):
94
- self.stop_signal = True
95
-
96
- def __aiter__(self):
97
- return self._generator()
98
-
99
- async def __anext__(self):
100
- return await self._generator().__anext__()
101
-
102
- def __iter__(self):
103
- try:
104
- loop = asyncio.get_event_loop()
105
- except RuntimeError as e:
106
- if str(e).startswith("There is no current event loop in thread"):
107
- loop = asyncio.new_event_loop()
108
- asyncio.set_event_loop(loop)
109
- else:
110
- raise e
111
-
112
- async_iter = self.__aiter__()
113
-
114
- while True:
115
- try:
116
- future = asyncio.ensure_future(async_iter.__anext__())
117
- yield loop.run_until_complete(future)
118
- except StopAsyncIteration:
119
- break
120
- except Exception as e:
121
- print(f"Error in synchronous iterator: {e}")
122
- break
123
-
124
- async def _generator(self) -> AsyncGenerator[StepRunEvent, None]:
125
- while True:
126
- if self.stop_signal:
127
- listener = None
128
- break
129
-
130
- listener = await self.retry_subscribe()
131
-
132
- try:
133
- async for workflow_event in listener:
134
- eventType = None
135
- if workflow_event.resourceType == RESOURCE_TYPE_STEP_RUN:
136
- if workflow_event.eventType in step_run_event_type_mapping:
137
- eventType = step_run_event_type_mapping[
138
- workflow_event.eventType
139
- ]
140
- else:
141
- raise Exception(
142
- f"Unknown event type: {workflow_event.eventType}"
143
- )
144
- payload = None
145
-
146
- try:
147
- if workflow_event.eventPayload:
148
- payload = json.loads(workflow_event.eventPayload)
149
- except Exception as e:
150
- payload = workflow_event.eventPayload
151
- pass
152
-
153
- yield StepRunEvent(type=eventType, payload=payload)
154
- elif workflow_event.resourceType == RESOURCE_TYPE_WORKFLOW_RUN:
155
- if workflow_event.eventType in workflow_run_event_type_mapping:
156
- eventType = workflow_run_event_type_mapping[
157
- workflow_event.eventType
158
- ]
159
- else:
160
- raise Exception(
161
- f"Unknown event type: {workflow_event.eventType}"
162
- )
163
-
164
- payload = None
165
-
166
- try:
167
- if workflow_event.eventPayload:
168
- payload = json.loads(workflow_event.eventPayload)
169
- except Exception as e:
170
- pass
171
-
172
- yield StepRunEvent(type=eventType, payload=payload)
173
-
174
- if workflow_event.hangup:
175
- listener = None
176
- break
177
-
178
- break
179
- except grpc.RpcError as e:
180
- # Handle different types of errors
181
- if e.code() == grpc.StatusCode.CANCELLED:
182
- # Context cancelled, unsubscribe and close
183
- break
184
- elif e.code() == grpc.StatusCode.UNAVAILABLE:
185
- # Retry logic
186
- # logger.info("Could not connect to Hatchet, retrying...")
187
- listener = await self.retry_subscribe()
188
- elif e.code() == grpc.StatusCode.DEADLINE_EXCEEDED:
189
- # logger.info("Deadline exceeded, retrying subscription")
190
- continue
191
- else:
192
- # Unknown error, report and break
193
- # logger.error(f"Failed to receive message: {e}")
194
- break
195
- # Raise StopAsyncIteration to properly end the generator
196
-
197
- async def retry_subscribe(self):
198
- retries = 0
199
-
200
- while retries < DEFAULT_ACTION_LISTENER_RETRY_COUNT:
201
- try:
202
- if retries > 0:
203
- await asyncio.sleep(DEFAULT_ACTION_LISTENER_RETRY_INTERVAL)
204
-
205
- if self.workflow_run_id is not None:
206
- return self.client.SubscribeToWorkflowEvents(
207
- SubscribeToWorkflowEventsRequest(
208
- workflowRunId=self.workflow_run_id,
209
- ),
210
- metadata=get_metadata(self.token),
211
- )
212
- elif self.additional_meta_kv is not None:
213
- return self.client.SubscribeToWorkflowEvents(
214
- SubscribeToWorkflowEventsRequest(
215
- additionalMetaKey=self.additional_meta_kv[0],
216
- additionalMetaValue=self.additional_meta_kv[1],
217
- ),
218
- metadata=get_metadata(self.token),
219
- )
220
- else:
221
- raise Exception("no listener method provided")
222
-
223
- except grpc.RpcError as e:
224
- if e.code() == grpc.StatusCode.UNAVAILABLE:
225
- retries = retries + 1
226
- else:
227
- raise ValueError(f"gRPC error: {e}")
228
-
229
-
230
- class RunEventListenerClient:
231
- def __init__(self, config: ClientConfig):
232
- self.token = config.token
233
- self.config = config
234
- self.client: DispatcherStub = None
235
-
236
- def stream_by_run_id(self, workflow_run_id: str):
237
- return self.stream(workflow_run_id)
238
-
239
- def stream(self, workflow_run_id: str):
240
- if not isinstance(workflow_run_id, str) and hasattr(workflow_run_id, "__str__"):
241
- workflow_run_id = str(workflow_run_id)
242
-
243
- if not self.client:
244
- aio_conn = new_conn(self.config, True)
245
- self.client = DispatcherStub(aio_conn)
246
-
247
- return RunEventListener.for_run_id(workflow_run_id, self.client, self.token)
248
-
249
- def stream_by_additional_metadata(self, key: str, value: str):
250
- if not self.client:
251
- aio_conn = new_conn(self.config, True)
252
- self.client = DispatcherStub(aio_conn)
253
-
254
- return RunEventListener.for_additional_meta(key, value, self.client, self.token)
255
-
256
- async def on(self, workflow_run_id: str, handler: callable = None):
257
- async for event in self.stream(workflow_run_id):
258
- # call the handler if provided
259
- if handler:
260
- handler(event)
@@ -1,277 +0,0 @@
1
- import asyncio
2
- import json
3
- from collections.abc import AsyncIterator
4
- from typing import AsyncGenerator
5
-
6
- import grpc
7
- from grpc._cython import cygrpc
8
-
9
- from hatchet_sdk.contracts.dispatcher_pb2 import (
10
- SubscribeToWorkflowRunsRequest,
11
- WorkflowRunEvent,
12
- )
13
- from hatchet_sdk.contracts.dispatcher_pb2_grpc import DispatcherStub
14
- from hatchet_sdk.v0.clients.event_ts import ThreadSafeEvent, read_with_interrupt
15
- from hatchet_sdk.v0.connection import new_conn
16
-
17
- from ...logger import logger
18
- from ..loader import ClientConfig
19
- from ..metadata import get_metadata
20
-
21
- DEFAULT_WORKFLOW_LISTENER_RETRY_INTERVAL = 3 # seconds
22
- DEFAULT_WORKFLOW_LISTENER_RETRY_COUNT = 5
23
- DEFAULT_WORKFLOW_LISTENER_INTERRUPT_INTERVAL = 1800 # 30 minutes
24
-
25
- DEDUPE_MESSAGE = "DUPLICATE_WORKFLOW_RUN"
26
-
27
-
28
- class _Subscription:
29
- def __init__(self, id: int, workflow_run_id: str):
30
- self.id = id
31
- self.workflow_run_id = workflow_run_id
32
- self.queue: asyncio.Queue[WorkflowRunEvent | None] = asyncio.Queue()
33
-
34
- async def __aiter__(self):
35
- return self
36
-
37
- async def __anext__(self) -> WorkflowRunEvent:
38
- return await self.queue.get()
39
-
40
- async def get(self) -> WorkflowRunEvent:
41
- event = await self.queue.get()
42
-
43
- if event is None:
44
- raise StopAsyncIteration
45
-
46
- return event
47
-
48
- async def put(self, item: WorkflowRunEvent):
49
- await self.queue.put(item)
50
-
51
- async def close(self):
52
- await self.queue.put(None)
53
-
54
-
55
- class PooledWorkflowRunListener:
56
- # list of all active subscriptions, mapping from a subscription id to a workflow run id
57
- subscriptionsToWorkflows: dict[int, str] = {}
58
-
59
- # list of workflow run ids mapped to an array of subscription ids
60
- workflowsToSubscriptions: dict[str, list[int]] = {}
61
-
62
- subscription_counter: int = 0
63
- subscription_counter_lock: asyncio.Lock = asyncio.Lock()
64
-
65
- requests: asyncio.Queue[SubscribeToWorkflowRunsRequest] = asyncio.Queue()
66
-
67
- listener: AsyncGenerator[WorkflowRunEvent, None] = None
68
- listener_task: asyncio.Task = None
69
-
70
- curr_requester: int = 0
71
-
72
- # events have keys of the format workflow_run_id + subscription_id
73
- events: dict[int, _Subscription] = {}
74
-
75
- interrupter: asyncio.Task = None
76
-
77
- def __init__(self, config: ClientConfig):
78
- try:
79
- asyncio.get_running_loop()
80
- except RuntimeError:
81
- loop = asyncio.new_event_loop()
82
- asyncio.set_event_loop(loop)
83
-
84
- conn = new_conn(config, True)
85
- self.client = DispatcherStub(conn)
86
- self.token = config.token
87
- self.config = config
88
-
89
- async def _interrupter(self):
90
- """
91
- _interrupter runs in a separate thread and interrupts the listener according to a configurable duration.
92
- """
93
- await asyncio.sleep(DEFAULT_WORKFLOW_LISTENER_INTERRUPT_INTERVAL)
94
-
95
- if self.interrupt is not None:
96
- self.interrupt.set()
97
-
98
- async def _init_producer(self):
99
- try:
100
- if not self.listener:
101
- while True:
102
- try:
103
- self.listener = await self._retry_subscribe()
104
-
105
- logger.debug("Workflow run listener connected.")
106
-
107
- # spawn an interrupter task
108
- if self.interrupter is not None and not self.interrupter.done():
109
- self.interrupter.cancel()
110
-
111
- self.interrupter = asyncio.create_task(self._interrupter())
112
-
113
- while True:
114
- self.interrupt = ThreadSafeEvent()
115
- t = asyncio.create_task(
116
- read_with_interrupt(self.listener, self.interrupt)
117
- )
118
- await self.interrupt.wait()
119
-
120
- if not t.done():
121
- # print a warning
122
- logger.warning(
123
- "Interrupted read_with_interrupt task of workflow run listener"
124
- )
125
-
126
- t.cancel()
127
- self.listener.cancel()
128
- await asyncio.sleep(
129
- DEFAULT_WORKFLOW_LISTENER_RETRY_INTERVAL
130
- )
131
- break
132
-
133
- workflow_event: WorkflowRunEvent = t.result()
134
-
135
- if workflow_event is cygrpc.EOF:
136
- break
137
-
138
- # get a list of subscriptions for this workflow
139
- subscriptions = self.workflowsToSubscriptions.get(
140
- workflow_event.workflowRunId, []
141
- )
142
-
143
- for subscription_id in subscriptions:
144
- await self.events[subscription_id].put(workflow_event)
145
-
146
- except grpc.RpcError as e:
147
- logger.debug(f"grpc error in workflow run listener: {e}")
148
- await asyncio.sleep(DEFAULT_WORKFLOW_LISTENER_RETRY_INTERVAL)
149
- continue
150
-
151
- except Exception as e:
152
- logger.error(f"Error in workflow run listener: {e}")
153
-
154
- self.listener = None
155
-
156
- # close all subscriptions
157
- for subscription_id in self.events:
158
- await self.events[subscription_id].close()
159
-
160
- raise e
161
-
162
- async def _request(self) -> AsyncIterator[SubscribeToWorkflowRunsRequest]:
163
- self.curr_requester = self.curr_requester + 1
164
-
165
- # replay all existing subscriptions
166
- workflow_run_set = set(self.subscriptionsToWorkflows.values())
167
-
168
- for workflow_run_id in workflow_run_set:
169
- yield SubscribeToWorkflowRunsRequest(
170
- workflowRunId=workflow_run_id,
171
- )
172
-
173
- while True:
174
- request = await self.requests.get()
175
-
176
- # if the request is an int which matches the current requester, then we should stop
177
- if request == self.curr_requester:
178
- break
179
-
180
- # if we've gotten an int that doesn't match the current requester, then we should ignore it
181
- if isinstance(request, int):
182
- continue
183
-
184
- yield request
185
- self.requests.task_done()
186
-
187
- def cleanup_subscription(self, subscription_id: int):
188
- workflow_run_id = self.subscriptionsToWorkflows[subscription_id]
189
-
190
- if workflow_run_id in self.workflowsToSubscriptions:
191
- self.workflowsToSubscriptions[workflow_run_id].remove(subscription_id)
192
-
193
- del self.subscriptionsToWorkflows[subscription_id]
194
- del self.events[subscription_id]
195
-
196
- async def subscribe(self, workflow_run_id: str):
197
- init_producer: asyncio.Task = None
198
- try:
199
- # create a new subscription id, place a mutex on the counter
200
- await self.subscription_counter_lock.acquire()
201
- self.subscription_counter += 1
202
- subscription_id = self.subscription_counter
203
- self.subscription_counter_lock.release()
204
-
205
- self.subscriptionsToWorkflows[subscription_id] = workflow_run_id
206
-
207
- if workflow_run_id not in self.workflowsToSubscriptions:
208
- self.workflowsToSubscriptions[workflow_run_id] = [subscription_id]
209
- else:
210
- self.workflowsToSubscriptions[workflow_run_id].append(subscription_id)
211
-
212
- self.events[subscription_id] = _Subscription(
213
- subscription_id, workflow_run_id
214
- )
215
-
216
- await self.requests.put(
217
- SubscribeToWorkflowRunsRequest(
218
- workflowRunId=workflow_run_id,
219
- )
220
- )
221
-
222
- if not self.listener_task or self.listener_task.done():
223
- self.listener_task = asyncio.create_task(self._init_producer())
224
-
225
- event = await self.events[subscription_id].get()
226
-
227
- return event
228
- except asyncio.CancelledError:
229
- raise
230
- finally:
231
- self.cleanup_subscription(subscription_id)
232
-
233
- async def result(self, workflow_run_id: str):
234
- from hatchet_sdk.v0.clients.admin import DedupeViolationErr
235
-
236
- event = await self.subscribe(workflow_run_id)
237
-
238
- errors = []
239
-
240
- if event.results:
241
- errors = [result.error for result in event.results if result.error]
242
-
243
- if errors:
244
- if DEDUPE_MESSAGE in errors[0]:
245
- raise DedupeViolationErr(errors[0])
246
- else:
247
- raise Exception(f"Workflow Errors: {errors}")
248
-
249
- results = {
250
- result.stepReadableId: json.loads(result.output)
251
- for result in event.results
252
- if result.output
253
- }
254
-
255
- return results
256
-
257
- async def _retry_subscribe(self):
258
- retries = 0
259
-
260
- while retries < DEFAULT_WORKFLOW_LISTENER_RETRY_COUNT:
261
- try:
262
- if retries > 0:
263
- await asyncio.sleep(DEFAULT_WORKFLOW_LISTENER_RETRY_INTERVAL)
264
-
265
- # signal previous async iterator to stop
266
- if self.curr_requester != 0:
267
- self.requests.put_nowait(self.curr_requester)
268
-
269
- return self.client.SubscribeToWorkflowRuns(
270
- self._request(),
271
- metadata=get_metadata(self.token),
272
- )
273
- except grpc.RpcError as e:
274
- if e.code() == grpc.StatusCode.UNAVAILABLE:
275
- retries = retries + 1
276
- else:
277
- raise ValueError(f"gRPC error: {e}")
@@ -1,63 +0,0 @@
1
- import os
2
- from typing import TYPE_CHECKING
3
-
4
- import grpc
5
-
6
- if TYPE_CHECKING:
7
- from hatchet_sdk.v0.loader import ClientConfig
8
-
9
-
10
- def new_conn(config: "ClientConfig", aio=False):
11
- credentials: grpc.ChannelCredentials | None = None
12
-
13
- # load channel credentials
14
- if config.tls_config.tls_strategy == "tls":
15
- root: bytes | None = None
16
-
17
- if config.tls_config.ca_file:
18
- root = open(config.tls_config.ca_file, "rb").read()
19
-
20
- credentials = grpc.ssl_channel_credentials(root_certificates=root)
21
- elif config.tls_config.tls_strategy == "mtls":
22
- root = open(config.tls_config.ca_file, "rb").read()
23
- private_key = open(config.tls_config.key_file, "rb").read()
24
- certificate_chain = open(config.tls_config.cert_file, "rb").read()
25
-
26
- credentials = grpc.ssl_channel_credentials(
27
- root_certificates=root,
28
- private_key=private_key,
29
- certificate_chain=certificate_chain,
30
- )
31
-
32
- start = grpc if not aio else grpc.aio
33
-
34
- channel_options = [
35
- ("grpc.max_send_message_length", config.grpc_max_send_message_length),
36
- ("grpc.max_receive_message_length", config.grpc_max_recv_message_length),
37
- ("grpc.keepalive_time_ms", 10 * 1000),
38
- ("grpc.keepalive_timeout_ms", 60 * 1000),
39
- ("grpc.client_idle_timeout_ms", 60 * 1000),
40
- ("grpc.http2.max_pings_without_data", 0),
41
- ("grpc.keepalive_permit_without_calls", 1),
42
- ]
43
-
44
- # Set environment variable to disable fork support. Reference: https://github.com/grpc/grpc/issues/28557
45
- # When steps execute via os.fork, we see `TSI_DATA_CORRUPTED` errors.
46
- os.environ["GRPC_ENABLE_FORK_SUPPORT"] = "False"
47
-
48
- if config.tls_config.tls_strategy == "none":
49
- conn = start.insecure_channel(
50
- target=config.host_port,
51
- options=channel_options,
52
- )
53
- else:
54
- channel_options.append(
55
- ("grpc.ssl_target_name_override", config.tls_config.server_name)
56
- )
57
-
58
- conn = start.secure_channel(
59
- target=config.host_port,
60
- credentials=credentials,
61
- options=channel_options,
62
- )
63
- return conn
@@ -1 +0,0 @@
1
- from .context import Context