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.
- hatchet_sdk/__init__.py +45 -25
- hatchet_sdk/client.py +19 -94
- hatchet_sdk/clients/admin.py +309 -389
- hatchet_sdk/clients/dispatcher/action_listener.py +131 -109
- hatchet_sdk/clients/dispatcher/dispatcher.py +39 -37
- hatchet_sdk/clients/durable_event_listener.py +327 -0
- hatchet_sdk/clients/event_ts.py +23 -10
- hatchet_sdk/clients/events.py +96 -99
- hatchet_sdk/clients/rest/__init__.py +35 -0
- hatchet_sdk/clients/rest/api/__init__.py +2 -0
- hatchet_sdk/clients/rest/api/log_api.py +258 -0
- hatchet_sdk/clients/rest/api/task_api.py +2200 -0
- hatchet_sdk/clients/rest/api/workflow_runs_api.py +1274 -116
- hatchet_sdk/clients/rest/api_client.py +1 -1
- hatchet_sdk/clients/rest/configuration.py +8 -1
- hatchet_sdk/clients/rest/exceptions.py +21 -0
- hatchet_sdk/clients/rest/models/__init__.py +33 -0
- hatchet_sdk/clients/rest/models/tenant.py +4 -0
- hatchet_sdk/clients/rest/models/tenant_version.py +37 -0
- hatchet_sdk/clients/rest/models/update_tenant_request.py +7 -0
- hatchet_sdk/clients/rest/models/v1_cancel_task_request.py +104 -0
- hatchet_sdk/clients/rest/models/v1_dag_children.py +102 -0
- hatchet_sdk/clients/rest/models/v1_log_line.py +94 -0
- hatchet_sdk/clients/rest/models/v1_log_line_level.py +39 -0
- hatchet_sdk/clients/rest/models/v1_log_line_list.py +110 -0
- hatchet_sdk/clients/rest/models/v1_replay_task_request.py +104 -0
- hatchet_sdk/clients/rest/models/v1_task.py +174 -0
- hatchet_sdk/clients/rest/models/v1_task_event.py +118 -0
- hatchet_sdk/clients/rest/models/v1_task_event_list.py +110 -0
- hatchet_sdk/clients/rest/models/v1_task_event_type.py +55 -0
- hatchet_sdk/clients/rest/models/v1_task_filter.py +106 -0
- hatchet_sdk/clients/rest/models/v1_task_point_metric.py +92 -0
- hatchet_sdk/clients/rest/models/v1_task_point_metrics.py +100 -0
- hatchet_sdk/clients/rest/models/v1_task_run_metric.py +88 -0
- hatchet_sdk/clients/rest/models/v1_task_run_status.py +40 -0
- hatchet_sdk/clients/rest/models/v1_task_status.py +40 -0
- hatchet_sdk/clients/rest/models/v1_task_summary.py +228 -0
- hatchet_sdk/clients/rest/models/v1_task_summary_list.py +110 -0
- hatchet_sdk/clients/rest/models/v1_trigger_workflow_run_request.py +95 -0
- hatchet_sdk/clients/rest/models/v1_workflow_run.py +171 -0
- hatchet_sdk/clients/rest/models/v1_workflow_run_details.py +145 -0
- hatchet_sdk/clients/rest/models/v1_workflow_run_display_name.py +98 -0
- hatchet_sdk/clients/rest/models/v1_workflow_run_display_name_list.py +114 -0
- hatchet_sdk/clients/rest/models/v1_workflow_type.py +37 -0
- hatchet_sdk/clients/rest/models/workflow_run_shape_item_for_workflow_run_details.py +104 -0
- hatchet_sdk/clients/rest/rest.py +37 -26
- hatchet_sdk/clients/rest/tenacity_utils.py +1 -1
- hatchet_sdk/clients/rest_client.py +153 -116
- hatchet_sdk/clients/run_event_listener.py +65 -60
- hatchet_sdk/clients/workflow_listener.py +75 -66
- hatchet_sdk/config.py +117 -0
- hatchet_sdk/connection.py +27 -13
- hatchet_sdk/context/__init__.py +0 -1
- hatchet_sdk/context/context.py +118 -280
- hatchet_sdk/contracts/dispatcher_pb2_grpc.py +1 -1
- hatchet_sdk/contracts/events_pb2.py +2 -2
- hatchet_sdk/contracts/events_pb2_grpc.py +1 -1
- hatchet_sdk/contracts/v1/dispatcher_pb2.py +36 -0
- hatchet_sdk/contracts/v1/dispatcher_pb2.pyi +38 -0
- hatchet_sdk/contracts/v1/dispatcher_pb2_grpc.py +145 -0
- hatchet_sdk/contracts/v1/shared/condition_pb2.py +39 -0
- hatchet_sdk/contracts/v1/shared/condition_pb2.pyi +72 -0
- hatchet_sdk/contracts/v1/shared/condition_pb2_grpc.py +29 -0
- hatchet_sdk/contracts/v1/workflows_pb2.py +67 -0
- hatchet_sdk/contracts/v1/workflows_pb2.pyi +228 -0
- hatchet_sdk/contracts/v1/workflows_pb2_grpc.py +234 -0
- hatchet_sdk/contracts/workflows_pb2_grpc.py +1 -1
- hatchet_sdk/features/cron.py +43 -57
- hatchet_sdk/features/scheduled.py +60 -74
- hatchet_sdk/hatchet.py +491 -218
- hatchet_sdk/labels.py +4 -6
- hatchet_sdk/metadata.py +1 -1
- hatchet_sdk/opentelemetry/instrumentor.py +17 -18
- hatchet_sdk/rate_limit.py +40 -55
- hatchet_sdk/runnables/contextvars.py +12 -0
- hatchet_sdk/runnables/standalone.py +194 -0
- hatchet_sdk/runnables/task.py +144 -0
- hatchet_sdk/runnables/types.py +138 -0
- hatchet_sdk/runnables/workflow.py +764 -0
- hatchet_sdk/token.py +13 -9
- hatchet_sdk/utils/aio_utils.py +0 -119
- hatchet_sdk/utils/proto_enums.py +47 -0
- hatchet_sdk/utils/timedelta_to_expression.py +23 -0
- hatchet_sdk/utils/typing.py +10 -2
- hatchet_sdk/v0/__init__.py +251 -0
- hatchet_sdk/v0/client.py +119 -0
- hatchet_sdk/v0/clients/admin.py +541 -0
- hatchet_sdk/v0/clients/dispatcher/action_listener.py +422 -0
- hatchet_sdk/v0/clients/dispatcher/dispatcher.py +204 -0
- hatchet_sdk/v0/clients/event_ts.py +28 -0
- hatchet_sdk/v0/clients/events.py +182 -0
- hatchet_sdk/v0/clients/rest/__init__.py +307 -0
- hatchet_sdk/v0/clients/rest/api/__init__.py +19 -0
- hatchet_sdk/v0/clients/rest/api/api_token_api.py +858 -0
- hatchet_sdk/v0/clients/rest/api/default_api.py +2259 -0
- hatchet_sdk/v0/clients/rest/api/event_api.py +2548 -0
- hatchet_sdk/v0/clients/rest/api/github_api.py +331 -0
- hatchet_sdk/v0/clients/rest/api/healthcheck_api.py +483 -0
- hatchet_sdk/v0/clients/rest/api/log_api.py +449 -0
- hatchet_sdk/v0/clients/rest/api/metadata_api.py +728 -0
- hatchet_sdk/v0/clients/rest/api/rate_limits_api.py +423 -0
- hatchet_sdk/v0/clients/rest/api/slack_api.py +577 -0
- hatchet_sdk/v0/clients/rest/api/sns_api.py +872 -0
- hatchet_sdk/v0/clients/rest/api/step_run_api.py +2202 -0
- hatchet_sdk/v0/clients/rest/api/tenant_api.py +4430 -0
- hatchet_sdk/v0/clients/rest/api/user_api.py +2888 -0
- hatchet_sdk/v0/clients/rest/api/worker_api.py +858 -0
- hatchet_sdk/v0/clients/rest/api/workflow_api.py +6312 -0
- hatchet_sdk/v0/clients/rest/api/workflow_run_api.py +1932 -0
- hatchet_sdk/v0/clients/rest/api/workflow_runs_api.py +610 -0
- hatchet_sdk/v0/clients/rest/api_client.py +759 -0
- hatchet_sdk/v0/clients/rest/api_response.py +22 -0
- hatchet_sdk/v0/clients/rest/configuration.py +611 -0
- hatchet_sdk/v0/clients/rest/exceptions.py +200 -0
- hatchet_sdk/v0/clients/rest/models/__init__.py +274 -0
- hatchet_sdk/v0/clients/rest/models/accept_invite_request.py +83 -0
- hatchet_sdk/v0/clients/rest/models/api_error.py +102 -0
- hatchet_sdk/v0/clients/rest/models/api_errors.py +100 -0
- hatchet_sdk/v0/clients/rest/models/api_meta.py +144 -0
- hatchet_sdk/v0/clients/rest/models/api_meta_auth.py +85 -0
- hatchet_sdk/v0/clients/rest/models/api_meta_integration.py +88 -0
- hatchet_sdk/v0/clients/rest/models/api_meta_posthog.py +90 -0
- hatchet_sdk/v0/clients/rest/models/api_resource_meta.py +98 -0
- hatchet_sdk/v0/clients/rest/models/api_token.py +105 -0
- hatchet_sdk/v0/clients/rest/models/bulk_create_event_request.py +100 -0
- hatchet_sdk/v0/clients/rest/models/bulk_create_event_response.py +110 -0
- hatchet_sdk/v0/clients/rest/models/cancel_event_request.py +85 -0
- hatchet_sdk/v0/clients/rest/models/cancel_step_run_request.py +83 -0
- hatchet_sdk/v0/clients/rest/models/concurrency_limit_strategy.py +39 -0
- hatchet_sdk/v0/clients/rest/models/create_api_token_request.py +92 -0
- hatchet_sdk/v0/clients/rest/models/create_api_token_response.py +83 -0
- hatchet_sdk/v0/clients/rest/models/create_cron_workflow_trigger_request.py +98 -0
- hatchet_sdk/v0/clients/rest/models/create_event_request.py +95 -0
- hatchet_sdk/v0/clients/rest/models/create_pull_request_from_step_run.py +83 -0
- hatchet_sdk/v0/clients/rest/models/create_sns_integration_request.py +85 -0
- hatchet_sdk/v0/clients/rest/models/create_tenant_alert_email_group_request.py +83 -0
- hatchet_sdk/v0/clients/rest/models/create_tenant_invite_request.py +86 -0
- hatchet_sdk/v0/clients/rest/models/create_tenant_request.py +84 -0
- hatchet_sdk/v0/clients/rest/models/cron_workflows.py +131 -0
- hatchet_sdk/v0/clients/rest/models/cron_workflows_list.py +110 -0
- hatchet_sdk/v0/clients/rest/models/cron_workflows_method.py +37 -0
- hatchet_sdk/v0/clients/rest/models/cron_workflows_order_by_field.py +37 -0
- hatchet_sdk/v0/clients/rest/models/event.py +143 -0
- hatchet_sdk/v0/clients/rest/models/event_data.py +83 -0
- hatchet_sdk/v0/clients/rest/models/event_key_list.py +98 -0
- hatchet_sdk/v0/clients/rest/models/event_list.py +110 -0
- hatchet_sdk/v0/clients/rest/models/event_order_by_direction.py +37 -0
- hatchet_sdk/v0/clients/rest/models/event_order_by_field.py +36 -0
- hatchet_sdk/v0/clients/rest/models/event_update_cancel200_response.py +85 -0
- hatchet_sdk/v0/clients/rest/models/event_workflow_run_summary.py +116 -0
- hatchet_sdk/v0/clients/rest/models/events.py +110 -0
- hatchet_sdk/v0/clients/rest/models/get_step_run_diff_response.py +100 -0
- hatchet_sdk/v0/clients/rest/models/github_app_installation.py +107 -0
- hatchet_sdk/v0/clients/rest/models/github_branch.py +86 -0
- hatchet_sdk/v0/clients/rest/models/github_repo.py +86 -0
- hatchet_sdk/v0/clients/rest/models/info_get_version200_response.py +83 -0
- hatchet_sdk/v0/clients/rest/models/job.py +132 -0
- hatchet_sdk/v0/clients/rest/models/job_run.py +176 -0
- hatchet_sdk/v0/clients/rest/models/job_run_status.py +41 -0
- hatchet_sdk/v0/clients/rest/models/link_github_repository_request.py +106 -0
- hatchet_sdk/v0/clients/rest/models/list_api_tokens_response.py +110 -0
- hatchet_sdk/v0/clients/rest/models/list_github_app_installations_response.py +112 -0
- hatchet_sdk/v0/clients/rest/models/list_pull_requests_response.py +100 -0
- hatchet_sdk/v0/clients/rest/models/list_slack_webhooks.py +110 -0
- hatchet_sdk/v0/clients/rest/models/list_sns_integrations.py +110 -0
- hatchet_sdk/v0/clients/rest/models/log_line.py +94 -0
- hatchet_sdk/v0/clients/rest/models/log_line_level.py +39 -0
- hatchet_sdk/v0/clients/rest/models/log_line_list.py +110 -0
- hatchet_sdk/v0/clients/rest/models/log_line_order_by_direction.py +37 -0
- hatchet_sdk/v0/clients/rest/models/log_line_order_by_field.py +36 -0
- hatchet_sdk/v0/clients/rest/models/pagination_response.py +95 -0
- hatchet_sdk/v0/clients/rest/models/pull_request.py +112 -0
- hatchet_sdk/v0/clients/rest/models/pull_request_state.py +37 -0
- hatchet_sdk/v0/clients/rest/models/queue_metrics.py +97 -0
- hatchet_sdk/v0/clients/rest/models/rate_limit.py +117 -0
- hatchet_sdk/v0/clients/rest/models/rate_limit_list.py +110 -0
- hatchet_sdk/v0/clients/rest/models/rate_limit_order_by_direction.py +37 -0
- hatchet_sdk/v0/clients/rest/models/rate_limit_order_by_field.py +38 -0
- hatchet_sdk/v0/clients/rest/models/recent_step_runs.py +118 -0
- hatchet_sdk/v0/clients/rest/models/reject_invite_request.py +83 -0
- hatchet_sdk/v0/clients/rest/models/replay_event_request.py +85 -0
- hatchet_sdk/v0/clients/rest/models/replay_workflow_runs_request.py +85 -0
- hatchet_sdk/v0/clients/rest/models/replay_workflow_runs_response.py +100 -0
- hatchet_sdk/v0/clients/rest/models/rerun_step_run_request.py +83 -0
- hatchet_sdk/v0/clients/rest/models/schedule_workflow_run_request.py +92 -0
- hatchet_sdk/v0/clients/rest/models/scheduled_run_status.py +42 -0
- hatchet_sdk/v0/clients/rest/models/scheduled_workflows.py +149 -0
- hatchet_sdk/v0/clients/rest/models/scheduled_workflows_list.py +110 -0
- hatchet_sdk/v0/clients/rest/models/scheduled_workflows_method.py +37 -0
- hatchet_sdk/v0/clients/rest/models/scheduled_workflows_order_by_field.py +37 -0
- hatchet_sdk/v0/clients/rest/models/semaphore_slots.py +113 -0
- hatchet_sdk/v0/clients/rest/models/slack_webhook.py +127 -0
- hatchet_sdk/v0/clients/rest/models/sns_integration.py +114 -0
- hatchet_sdk/v0/clients/rest/models/step.py +123 -0
- hatchet_sdk/v0/clients/rest/models/step_run.py +202 -0
- hatchet_sdk/v0/clients/rest/models/step_run_archive.py +142 -0
- hatchet_sdk/v0/clients/rest/models/step_run_archive_list.py +110 -0
- hatchet_sdk/v0/clients/rest/models/step_run_diff.py +91 -0
- hatchet_sdk/v0/clients/rest/models/step_run_event.py +122 -0
- hatchet_sdk/v0/clients/rest/models/step_run_event_list.py +110 -0
- hatchet_sdk/v0/clients/rest/models/step_run_event_reason.py +52 -0
- hatchet_sdk/v0/clients/rest/models/step_run_event_severity.py +38 -0
- hatchet_sdk/v0/clients/rest/models/step_run_status.py +44 -0
- hatchet_sdk/v0/clients/rest/models/tenant.py +118 -0
- hatchet_sdk/v0/clients/rest/models/tenant_alert_email_group.py +98 -0
- hatchet_sdk/v0/clients/rest/models/tenant_alert_email_group_list.py +112 -0
- hatchet_sdk/v0/clients/rest/models/tenant_alerting_settings.py +143 -0
- hatchet_sdk/v0/clients/rest/models/tenant_invite.py +120 -0
- hatchet_sdk/v0/clients/rest/models/tenant_invite_list.py +110 -0
- hatchet_sdk/v0/clients/rest/models/tenant_list.py +110 -0
- hatchet_sdk/v0/clients/rest/models/tenant_member.py +123 -0
- hatchet_sdk/v0/clients/rest/models/tenant_member_list.py +110 -0
- hatchet_sdk/v0/clients/rest/models/tenant_member_role.py +38 -0
- hatchet_sdk/v0/clients/rest/models/tenant_queue_metrics.py +116 -0
- hatchet_sdk/v0/clients/rest/models/tenant_resource.py +40 -0
- hatchet_sdk/v0/clients/rest/models/tenant_resource_limit.py +135 -0
- hatchet_sdk/v0/clients/rest/models/tenant_resource_policy.py +102 -0
- hatchet_sdk/v0/clients/rest/models/tenant_step_run_queue_metrics.py +83 -0
- hatchet_sdk/v0/clients/rest/models/trigger_workflow_run_request.py +91 -0
- hatchet_sdk/v0/clients/rest/models/update_tenant_alert_email_group_request.py +83 -0
- hatchet_sdk/v0/clients/rest/models/update_tenant_invite_request.py +85 -0
- hatchet_sdk/v0/clients/rest/models/update_tenant_request.py +137 -0
- hatchet_sdk/v0/clients/rest/models/update_worker_request.py +87 -0
- hatchet_sdk/v0/clients/rest/models/user.py +126 -0
- hatchet_sdk/v0/clients/rest/models/user_change_password_request.py +88 -0
- hatchet_sdk/v0/clients/rest/models/user_login_request.py +86 -0
- hatchet_sdk/v0/clients/rest/models/user_register_request.py +91 -0
- hatchet_sdk/v0/clients/rest/models/user_tenant_memberships_list.py +110 -0
- hatchet_sdk/v0/clients/rest/models/user_tenant_public.py +86 -0
- hatchet_sdk/v0/clients/rest/models/webhook_worker.py +100 -0
- hatchet_sdk/v0/clients/rest/models/webhook_worker_create_request.py +94 -0
- hatchet_sdk/v0/clients/rest/models/webhook_worker_create_response.py +98 -0
- hatchet_sdk/v0/clients/rest/models/webhook_worker_created.py +102 -0
- hatchet_sdk/v0/clients/rest/models/webhook_worker_list_response.py +110 -0
- hatchet_sdk/v0/clients/rest/models/webhook_worker_request.py +102 -0
- hatchet_sdk/v0/clients/rest/models/webhook_worker_request_list_response.py +104 -0
- hatchet_sdk/v0/clients/rest/models/webhook_worker_request_method.py +38 -0
- hatchet_sdk/v0/clients/rest/models/worker.py +239 -0
- hatchet_sdk/v0/clients/rest/models/worker_label.py +102 -0
- hatchet_sdk/v0/clients/rest/models/worker_list.py +110 -0
- hatchet_sdk/v0/clients/rest/models/worker_runtime_info.py +103 -0
- hatchet_sdk/v0/clients/rest/models/worker_runtime_sdks.py +38 -0
- hatchet_sdk/v0/clients/rest/models/worker_type.py +38 -0
- hatchet_sdk/v0/clients/rest/models/workflow.py +165 -0
- hatchet_sdk/v0/clients/rest/models/workflow_concurrency.py +107 -0
- hatchet_sdk/v0/clients/rest/models/workflow_deployment_config.py +136 -0
- hatchet_sdk/v0/clients/rest/models/workflow_kind.py +38 -0
- hatchet_sdk/v0/clients/rest/models/workflow_list.py +120 -0
- hatchet_sdk/v0/clients/rest/models/workflow_metrics.py +97 -0
- hatchet_sdk/v0/clients/rest/models/workflow_run.py +188 -0
- hatchet_sdk/v0/clients/rest/models/workflow_run_cancel200_response.py +85 -0
- hatchet_sdk/v0/clients/rest/models/workflow_run_list.py +110 -0
- hatchet_sdk/v0/clients/rest/models/workflow_run_order_by_direction.py +37 -0
- hatchet_sdk/v0/clients/rest/models/workflow_run_order_by_field.py +39 -0
- hatchet_sdk/v0/clients/rest/models/workflow_run_shape.py +186 -0
- hatchet_sdk/v0/clients/rest/models/workflow_run_status.py +42 -0
- hatchet_sdk/v0/clients/rest/models/workflow_run_triggered_by.py +112 -0
- hatchet_sdk/v0/clients/rest/models/workflow_runs_cancel_request.py +85 -0
- hatchet_sdk/v0/clients/rest/models/workflow_runs_metrics.py +94 -0
- hatchet_sdk/v0/clients/rest/models/workflow_runs_metrics_counts.py +104 -0
- hatchet_sdk/v0/clients/rest/models/workflow_tag.py +84 -0
- hatchet_sdk/v0/clients/rest/models/workflow_trigger_cron_ref.py +86 -0
- hatchet_sdk/v0/clients/rest/models/workflow_trigger_event_ref.py +86 -0
- hatchet_sdk/v0/clients/rest/models/workflow_triggers.py +141 -0
- hatchet_sdk/v0/clients/rest/models/workflow_update_request.py +85 -0
- hatchet_sdk/v0/clients/rest/models/workflow_version.py +170 -0
- hatchet_sdk/v0/clients/rest/models/workflow_version_concurrency.py +114 -0
- hatchet_sdk/v0/clients/rest/models/workflow_version_definition.py +85 -0
- hatchet_sdk/v0/clients/rest/models/workflow_version_meta.py +123 -0
- hatchet_sdk/v0/clients/rest/models/workflow_workers_count.py +95 -0
- hatchet_sdk/v0/clients/rest/rest.py +187 -0
- hatchet_sdk/v0/clients/rest/tenacity_utils.py +39 -0
- hatchet_sdk/v0/clients/rest_client.py +622 -0
- hatchet_sdk/v0/clients/run_event_listener.py +260 -0
- hatchet_sdk/v0/clients/workflow_listener.py +277 -0
- hatchet_sdk/v0/connection.py +63 -0
- hatchet_sdk/v0/context/__init__.py +1 -0
- hatchet_sdk/v0/context/context.py +446 -0
- hatchet_sdk/v0/context/worker_context.py +28 -0
- hatchet_sdk/v0/contracts/dispatcher_pb2.py +102 -0
- hatchet_sdk/v0/contracts/dispatcher_pb2.pyi +387 -0
- hatchet_sdk/v0/contracts/dispatcher_pb2_grpc.py +621 -0
- hatchet_sdk/v0/contracts/events_pb2.py +46 -0
- hatchet_sdk/v0/contracts/events_pb2.pyi +87 -0
- hatchet_sdk/v0/contracts/events_pb2_grpc.py +274 -0
- hatchet_sdk/v0/contracts/workflows_pb2.py +80 -0
- hatchet_sdk/v0/contracts/workflows_pb2.pyi +312 -0
- hatchet_sdk/v0/contracts/workflows_pb2_grpc.py +277 -0
- hatchet_sdk/v0/features/cron.py +286 -0
- hatchet_sdk/v0/features/scheduled.py +248 -0
- hatchet_sdk/v0/hatchet.py +310 -0
- hatchet_sdk/v0/labels.py +10 -0
- hatchet_sdk/v0/logger.py +13 -0
- hatchet_sdk/v0/metadata.py +2 -0
- hatchet_sdk/v0/opentelemetry/instrumentor.py +396 -0
- hatchet_sdk/v0/rate_limit.py +126 -0
- hatchet_sdk/v0/token.py +27 -0
- hatchet_sdk/v0/utils/aio_utils.py +137 -0
- hatchet_sdk/v0/utils/backoff.py +9 -0
- hatchet_sdk/v0/utils/typing.py +12 -0
- hatchet_sdk/{v2 → v0/v2}/callable.py +8 -8
- hatchet_sdk/{v2 → v0/v2}/concurrency.py +2 -2
- hatchet_sdk/{v2 → v0/v2}/hatchet.py +10 -10
- hatchet_sdk/v0/worker/__init__.py +1 -0
- hatchet_sdk/v0/worker/action_listener_process.py +294 -0
- hatchet_sdk/v0/worker/runner/run_loop_manager.py +112 -0
- hatchet_sdk/v0/worker/runner/runner.py +460 -0
- hatchet_sdk/v0/worker/runner/utils/capture_logs.py +81 -0
- hatchet_sdk/v0/worker/worker.py +391 -0
- hatchet_sdk/{workflow.py → v0/workflow.py} +4 -4
- hatchet_sdk/v0/workflow_run.py +59 -0
- hatchet_sdk/waits.py +120 -0
- hatchet_sdk/worker/__init__.py +0 -1
- hatchet_sdk/worker/action_listener_process.py +80 -55
- hatchet_sdk/worker/runner/run_loop_manager.py +46 -34
- hatchet_sdk/worker/runner/runner.py +82 -87
- hatchet_sdk/worker/runner/utils/capture_logs.py +26 -23
- hatchet_sdk/worker/worker.py +172 -149
- hatchet_sdk/workflow_run.py +7 -21
- {hatchet_sdk-0.47.1.dist-info → hatchet_sdk-1.0.0a1.dist-info}/METADATA +2 -2
- hatchet_sdk-1.0.0a1.dist-info/RECORD +505 -0
- {hatchet_sdk-0.47.1.dist-info → hatchet_sdk-1.0.0a1.dist-info}/entry_points.txt +2 -0
- hatchet_sdk/utils/serialization.py +0 -18
- hatchet_sdk-0.47.1.dist-info/RECORD +0 -237
- /hatchet_sdk/{loader.py → v0/loader.py} +0 -0
- /hatchet_sdk/{semver.py → v0/semver.py} +0 -0
- /hatchet_sdk/{utils → v0/utils}/types.py +0 -0
- /hatchet_sdk/{worker → v0/worker}/runner/utils/error_with_traceback.py +0 -0
- {hatchet_sdk-0.47.1.dist-info → hatchet_sdk-1.0.0a1.dist-info}/WHEEL +0 -0
hatchet_sdk/worker/worker.py
CHANGED
|
@@ -2,33 +2,38 @@ import asyncio
|
|
|
2
2
|
import multiprocessing
|
|
3
3
|
import multiprocessing.context
|
|
4
4
|
import os
|
|
5
|
+
import re
|
|
5
6
|
import signal
|
|
6
7
|
import sys
|
|
7
|
-
from concurrent.futures import Future
|
|
8
8
|
from dataclasses import dataclass, field
|
|
9
9
|
from enum import Enum
|
|
10
10
|
from multiprocessing import Queue
|
|
11
11
|
from multiprocessing.process import BaseProcess
|
|
12
12
|
from types import FrameType
|
|
13
|
-
from typing import Any,
|
|
13
|
+
from typing import Any, TypeVar, get_type_hints
|
|
14
14
|
|
|
15
15
|
from aiohttp import web
|
|
16
16
|
from aiohttp.web_request import Request
|
|
17
17
|
from aiohttp.web_response import Response
|
|
18
|
-
from prometheus_client import
|
|
18
|
+
from prometheus_client import Gauge, generate_latest
|
|
19
|
+
from pydantic import BaseModel
|
|
19
20
|
|
|
20
|
-
from hatchet_sdk import
|
|
21
|
-
from hatchet_sdk.
|
|
22
|
-
from hatchet_sdk.
|
|
23
|
-
from hatchet_sdk.
|
|
21
|
+
from hatchet_sdk.client import Client
|
|
22
|
+
from hatchet_sdk.clients.dispatcher.action_listener import Action
|
|
23
|
+
from hatchet_sdk.config import ClientConfig
|
|
24
|
+
from hatchet_sdk.contracts.v1.workflows_pb2 import CreateWorkflowVersionRequest
|
|
24
25
|
from hatchet_sdk.logger import logger
|
|
25
|
-
from hatchet_sdk.
|
|
26
|
-
from hatchet_sdk.
|
|
27
|
-
from hatchet_sdk.
|
|
28
|
-
from hatchet_sdk.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
from hatchet_sdk.runnables.task import Task
|
|
27
|
+
from hatchet_sdk.runnables.workflow import BaseWorkflow
|
|
28
|
+
from hatchet_sdk.utils.typing import WorkflowValidator, is_basemodel_subclass
|
|
29
|
+
from hatchet_sdk.worker.action_listener_process import (
|
|
30
|
+
ActionEvent,
|
|
31
|
+
worker_action_listener_process,
|
|
32
|
+
)
|
|
33
|
+
from hatchet_sdk.worker.runner.run_loop_manager import (
|
|
34
|
+
STOP_LOOP_TYPE,
|
|
35
|
+
WorkerActionRunLoopManager,
|
|
36
|
+
)
|
|
32
37
|
|
|
33
38
|
T = TypeVar("T")
|
|
34
39
|
|
|
@@ -45,62 +50,76 @@ class WorkerStartOptions:
|
|
|
45
50
|
loop: asyncio.AbstractEventLoop | None = field(default=None)
|
|
46
51
|
|
|
47
52
|
|
|
48
|
-
|
|
53
|
+
class HealthCheckResponse(BaseModel):
|
|
54
|
+
status: str
|
|
55
|
+
name: str
|
|
56
|
+
slots: int
|
|
57
|
+
actions: list[str]
|
|
58
|
+
labels: dict[str, str | int]
|
|
59
|
+
python_version: str
|
|
49
60
|
|
|
50
61
|
|
|
51
62
|
class Worker:
|
|
52
63
|
def __init__(
|
|
53
64
|
self,
|
|
54
65
|
name: str,
|
|
55
|
-
config: ClientConfig
|
|
56
|
-
|
|
66
|
+
config: ClientConfig,
|
|
67
|
+
slots: int | None = None,
|
|
57
68
|
labels: dict[str, str | int] = {},
|
|
58
69
|
debug: bool = False,
|
|
59
70
|
owned_loop: bool = True,
|
|
60
71
|
handle_kill: bool = True,
|
|
72
|
+
workflows: list[BaseWorkflow[Any]] = [],
|
|
61
73
|
) -> None:
|
|
62
|
-
self.name = name
|
|
63
74
|
self.config = config
|
|
64
|
-
self.
|
|
75
|
+
self.name = self.config.namespace + name
|
|
76
|
+
self.slots = slots
|
|
65
77
|
self.debug = debug
|
|
66
78
|
self.labels = labels
|
|
67
79
|
self.handle_kill = handle_kill
|
|
68
80
|
self.owned_loop = owned_loop
|
|
69
81
|
|
|
70
|
-
self.
|
|
82
|
+
self.action_registry: dict[str, Task[Any, Any]] = {}
|
|
83
|
+
self.durable_action_registry: dict[str, Task[Any, Any]] = {}
|
|
71
84
|
|
|
72
|
-
self.action_registry: dict[str, Callable[[Context], Any]] = {}
|
|
73
85
|
self.validator_registry: dict[str, WorkflowValidator] = {}
|
|
74
86
|
|
|
75
87
|
self.killing: bool = False
|
|
76
88
|
self._status: WorkerStatus
|
|
77
89
|
|
|
78
|
-
self.action_listener_process: BaseProcess
|
|
79
|
-
self.
|
|
80
|
-
|
|
90
|
+
self.action_listener_process: BaseProcess | None = None
|
|
91
|
+
self.durable_action_listener_process: BaseProcess | None = None
|
|
92
|
+
|
|
93
|
+
self.action_listener_health_check: asyncio.Task[None]
|
|
94
|
+
|
|
95
|
+
self.action_runner: WorkerActionRunLoopManager | None = None
|
|
96
|
+
self.durable_action_runner: WorkerActionRunLoopManager | None = None
|
|
81
97
|
|
|
82
98
|
self.ctx = multiprocessing.get_context("spawn")
|
|
83
99
|
|
|
84
|
-
self.action_queue: "Queue[
|
|
85
|
-
self.event_queue: "Queue[
|
|
100
|
+
self.action_queue: "Queue[Action | STOP_LOOP_TYPE]" = self.ctx.Queue()
|
|
101
|
+
self.event_queue: "Queue[ActionEvent]" = self.ctx.Queue()
|
|
102
|
+
|
|
103
|
+
self.durable_action_queue: "Queue[Action | STOP_LOOP_TYPE]" = self.ctx.Queue()
|
|
104
|
+
self.durable_event_queue: "Queue[ActionEvent]" = self.ctx.Queue()
|
|
86
105
|
|
|
87
106
|
self.loop: asyncio.AbstractEventLoop
|
|
88
107
|
|
|
89
|
-
self.client =
|
|
90
|
-
self.name = self.client.config.namespace + self.name
|
|
108
|
+
self.client = Client(config=self.config, debug=self.debug)
|
|
91
109
|
|
|
92
110
|
self._setup_signal_handlers()
|
|
93
111
|
|
|
94
112
|
self.worker_status_gauge = Gauge(
|
|
95
|
-
"
|
|
113
|
+
"hatchet_worker_status_" + re.sub(r"\W+", "", name),
|
|
114
|
+
"Current status of the Hatchet worker",
|
|
96
115
|
)
|
|
97
116
|
|
|
98
|
-
|
|
99
|
-
self.
|
|
117
|
+
self.has_any_durable = False
|
|
118
|
+
self.has_any_non_durable = False
|
|
100
119
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
) -> None:
|
|
120
|
+
self.register_workflows(workflows)
|
|
121
|
+
|
|
122
|
+
def register_workflow_from_opts(self, opts: CreateWorkflowVersionRequest) -> None:
|
|
104
123
|
try:
|
|
105
124
|
self.client.admin.put_workflow(opts.name, opts)
|
|
106
125
|
except Exception as e:
|
|
@@ -108,78 +127,87 @@ class Worker:
|
|
|
108
127
|
logger.error(e)
|
|
109
128
|
sys.exit(1)
|
|
110
129
|
|
|
111
|
-
def register_workflow(self, workflow:
|
|
112
|
-
## Hack for typing
|
|
113
|
-
assert isinstance(workflow, WorkflowInterface)
|
|
114
|
-
|
|
130
|
+
def register_workflow(self, workflow: BaseWorkflow[Any]) -> None:
|
|
115
131
|
namespace = self.client.config.namespace
|
|
116
132
|
|
|
133
|
+
opts = workflow._get_create_opts(namespace)
|
|
134
|
+
name = workflow._get_name(namespace)
|
|
135
|
+
|
|
117
136
|
try:
|
|
118
|
-
self.client.admin.put_workflow(
|
|
119
|
-
workflow.get_name(namespace), workflow.get_create_opts(namespace)
|
|
120
|
-
)
|
|
137
|
+
self.client.admin.put_workflow(name, opts)
|
|
121
138
|
except Exception as e:
|
|
122
|
-
logger.error(
|
|
139
|
+
logger.error(
|
|
140
|
+
f"failed to register workflow: {workflow._get_name(namespace)}"
|
|
141
|
+
)
|
|
123
142
|
logger.error(e)
|
|
124
143
|
sys.exit(1)
|
|
125
144
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
) -> Callable[[Context], T]:
|
|
129
|
-
def action_function(context: Context) -> T:
|
|
130
|
-
return action_func(workflow, context)
|
|
145
|
+
for step in workflow.tasks:
|
|
146
|
+
action_name = workflow._create_action_name(namespace, step)
|
|
131
147
|
|
|
132
|
-
if
|
|
133
|
-
|
|
148
|
+
if workflow.is_durable:
|
|
149
|
+
self.has_any_durable = True
|
|
150
|
+
self.durable_action_registry[action_name] = step
|
|
134
151
|
else:
|
|
135
|
-
|
|
152
|
+
self.has_any_non_durable = True
|
|
153
|
+
self.action_registry[action_name] = step
|
|
136
154
|
|
|
137
|
-
return
|
|
138
|
-
|
|
139
|
-
for action_name, action_func in workflow.get_actions(namespace):
|
|
140
|
-
self.action_registry[action_name] = create_action_function(action_func)
|
|
141
|
-
return_type = get_type_hints(action_func).get("return")
|
|
155
|
+
return_type = get_type_hints(step.fn).get("return")
|
|
142
156
|
|
|
143
157
|
self.validator_registry[action_name] = WorkflowValidator(
|
|
144
|
-
workflow_input=workflow.input_validator,
|
|
158
|
+
workflow_input=workflow.config.input_validator,
|
|
145
159
|
step_output=return_type if is_basemodel_subclass(return_type) else None,
|
|
146
160
|
)
|
|
147
161
|
|
|
162
|
+
def register_workflows(self, workflows: list[BaseWorkflow[Any]]) -> None:
|
|
163
|
+
for workflow in workflows:
|
|
164
|
+
self.register_workflow(workflow)
|
|
165
|
+
|
|
166
|
+
@property
|
|
148
167
|
def status(self) -> WorkerStatus:
|
|
149
168
|
return self._status
|
|
150
169
|
|
|
151
|
-
def
|
|
170
|
+
def _setup_loop(self, loop: asyncio.AbstractEventLoop | None = None) -> bool:
|
|
152
171
|
try:
|
|
153
|
-
loop = loop or asyncio.get_running_loop()
|
|
154
|
-
self.loop = loop
|
|
155
|
-
created_loop = False
|
|
172
|
+
self.loop = loop or asyncio.get_running_loop()
|
|
156
173
|
logger.debug("using existing event loop")
|
|
157
|
-
|
|
174
|
+
|
|
175
|
+
created_loop = False
|
|
158
176
|
except RuntimeError:
|
|
159
177
|
self.loop = asyncio.new_event_loop()
|
|
178
|
+
|
|
160
179
|
logger.debug("creating new event loop")
|
|
161
|
-
asyncio.set_event_loop(self.loop)
|
|
162
180
|
created_loop = True
|
|
163
|
-
return created_loop
|
|
164
181
|
|
|
165
|
-
|
|
166
|
-
|
|
182
|
+
asyncio.set_event_loop(self.loop)
|
|
183
|
+
|
|
184
|
+
return created_loop
|
|
185
|
+
|
|
186
|
+
async def _health_check_handler(self, request: Request) -> Response:
|
|
187
|
+
response = HealthCheckResponse(
|
|
188
|
+
status=self.status.name,
|
|
189
|
+
name=self.name,
|
|
190
|
+
slots=self.slots or 0,
|
|
191
|
+
actions=list(self.action_registry.keys()),
|
|
192
|
+
labels=self.labels,
|
|
193
|
+
python_version=sys.version,
|
|
194
|
+
).model_dump()
|
|
167
195
|
|
|
168
|
-
return web.json_response(
|
|
196
|
+
return web.json_response(response)
|
|
169
197
|
|
|
170
|
-
async def
|
|
171
|
-
self.worker_status_gauge.set(1 if self.status
|
|
198
|
+
async def _metrics_handler(self, request: Request) -> Response:
|
|
199
|
+
self.worker_status_gauge.set(1 if self.status == WorkerStatus.HEALTHY else 0)
|
|
172
200
|
|
|
173
201
|
return web.Response(body=generate_latest(), content_type="text/plain")
|
|
174
202
|
|
|
175
|
-
async def
|
|
176
|
-
port = self.config.
|
|
203
|
+
async def _start_health_server(self) -> None:
|
|
204
|
+
port = self.config.healthcheck.port
|
|
177
205
|
|
|
178
206
|
app = web.Application()
|
|
179
207
|
app.add_routes(
|
|
180
208
|
[
|
|
181
|
-
web.get("/health", self.
|
|
182
|
-
web.get("/metrics", self.
|
|
209
|
+
web.get("/health", self._health_check_handler),
|
|
210
|
+
web.get("/metrics", self._metrics_handler),
|
|
183
211
|
]
|
|
184
212
|
)
|
|
185
213
|
|
|
@@ -195,14 +223,10 @@ class Worker:
|
|
|
195
223
|
|
|
196
224
|
logger.info(f"healthcheck server running on port {port}")
|
|
197
225
|
|
|
198
|
-
def start(
|
|
199
|
-
self
|
|
200
|
-
) -> Future[asyncio.Task[Any] | None]:
|
|
201
|
-
self.owned_loop = self.setup_loop(options.loop)
|
|
226
|
+
def start(self, options: WorkerStartOptions = WorkerStartOptions()) -> None:
|
|
227
|
+
self.owned_loop = self._setup_loop(options.loop)
|
|
202
228
|
|
|
203
|
-
|
|
204
|
-
self.async_start(options, _from_start=True), self.loop
|
|
205
|
-
)
|
|
229
|
+
asyncio.run_coroutine_threadsafe(self._aio_start(), self.loop)
|
|
206
230
|
|
|
207
231
|
# start the loop and wait until its closed
|
|
208
232
|
if self.owned_loop:
|
|
@@ -211,73 +235,75 @@ class Worker:
|
|
|
211
235
|
if self.handle_kill:
|
|
212
236
|
sys.exit(0)
|
|
213
237
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
## Start methods
|
|
217
|
-
async def async_start(
|
|
218
|
-
self,
|
|
219
|
-
options: WorkerStartOptions = WorkerStartOptions(),
|
|
220
|
-
_from_start: bool = False,
|
|
221
|
-
) -> Any | None:
|
|
238
|
+
async def _aio_start(self) -> None:
|
|
222
239
|
main_pid = os.getpid()
|
|
240
|
+
|
|
223
241
|
logger.info("------------------------------------------")
|
|
224
242
|
logger.info("STARTING HATCHET...")
|
|
225
243
|
logger.debug(f"worker runtime starting on PID: {main_pid}")
|
|
226
244
|
|
|
227
245
|
self._status = WorkerStatus.STARTING
|
|
228
246
|
|
|
229
|
-
if
|
|
230
|
-
|
|
247
|
+
if (
|
|
248
|
+
len(self.action_registry.keys()) == 0
|
|
249
|
+
and len(self.durable_action_registry.keys()) == 0
|
|
250
|
+
):
|
|
251
|
+
raise ValueError(
|
|
231
252
|
"no actions registered, register workflows or actions before starting worker"
|
|
232
253
|
)
|
|
233
|
-
return None
|
|
234
254
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
self.setup_loop(options.loop)
|
|
255
|
+
if self.config.healthcheck.enabled:
|
|
256
|
+
await self._start_health_server()
|
|
238
257
|
|
|
239
|
-
if self.
|
|
240
|
-
|
|
258
|
+
if self.has_any_non_durable:
|
|
259
|
+
self.action_listener_process = self._start_action_listener(is_durable=False)
|
|
260
|
+
self.action_runner = self._run_action_runner(is_durable=False)
|
|
241
261
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
262
|
+
if self.has_any_durable:
|
|
263
|
+
self.durable_action_listener_process = self._start_action_listener(
|
|
264
|
+
is_durable=True
|
|
265
|
+
)
|
|
266
|
+
self.durable_action_runner = self._run_action_runner(is_durable=True)
|
|
245
267
|
|
|
246
268
|
self.action_listener_health_check = self.loop.create_task(
|
|
247
269
|
self._check_listener_health()
|
|
248
270
|
)
|
|
249
271
|
|
|
250
|
-
|
|
272
|
+
await self.action_listener_health_check
|
|
251
273
|
|
|
252
|
-
def _run_action_runner(self) -> WorkerActionRunLoopManager:
|
|
274
|
+
def _run_action_runner(self, is_durable: bool) -> WorkerActionRunLoopManager:
|
|
253
275
|
# Retrieve the shared queue
|
|
254
276
|
return WorkerActionRunLoopManager(
|
|
255
|
-
self.name,
|
|
256
|
-
self.action_registry,
|
|
277
|
+
self.name + ("_durable" if is_durable else ""),
|
|
278
|
+
self.durable_action_registry if is_durable else self.action_registry,
|
|
257
279
|
self.validator_registry,
|
|
258
|
-
self.
|
|
280
|
+
1_000 if is_durable else self.slots,
|
|
259
281
|
self.config,
|
|
260
|
-
self.action_queue,
|
|
261
|
-
self.event_queue,
|
|
282
|
+
self.durable_action_queue if is_durable else self.action_queue,
|
|
283
|
+
self.durable_event_queue if is_durable else self.event_queue,
|
|
262
284
|
self.loop,
|
|
263
285
|
self.handle_kill,
|
|
264
286
|
self.client.debug,
|
|
265
287
|
self.labels,
|
|
266
288
|
)
|
|
267
289
|
|
|
268
|
-
def
|
|
269
|
-
|
|
270
|
-
|
|
290
|
+
def _start_action_listener(
|
|
291
|
+
self, is_durable: bool
|
|
292
|
+
) -> multiprocessing.context.SpawnProcess:
|
|
271
293
|
try:
|
|
272
294
|
process = self.ctx.Process(
|
|
273
295
|
target=worker_action_listener_process,
|
|
274
296
|
args=(
|
|
275
|
-
self.name,
|
|
276
|
-
|
|
277
|
-
|
|
297
|
+
self.name + ("_durable" if is_durable else ""),
|
|
298
|
+
(
|
|
299
|
+
list(self.durable_action_registry.keys())
|
|
300
|
+
if is_durable
|
|
301
|
+
else list(self.action_registry.keys())
|
|
302
|
+
),
|
|
303
|
+
1_000 if is_durable else self.slots,
|
|
278
304
|
self.config,
|
|
279
|
-
self.action_queue,
|
|
280
|
-
self.event_queue,
|
|
305
|
+
self.durable_action_queue if is_durable else self.action_queue,
|
|
306
|
+
self.durable_event_queue if is_durable else self.event_queue,
|
|
281
307
|
self.handle_kill,
|
|
282
308
|
self.client.debug,
|
|
283
309
|
self.labels,
|
|
@@ -296,8 +322,13 @@ class Worker:
|
|
|
296
322
|
try:
|
|
297
323
|
while not self.killing:
|
|
298
324
|
if (
|
|
299
|
-
self.action_listener_process
|
|
300
|
-
|
|
325
|
+
not self.action_listener_process
|
|
326
|
+
and not self.durable_action_listener_process
|
|
327
|
+
) or (
|
|
328
|
+
self.action_listener_process
|
|
329
|
+
and self.durable_action_listener_process
|
|
330
|
+
and not self.action_listener_process.is_alive()
|
|
331
|
+
and not self.durable_action_listener_process.is_alive()
|
|
301
332
|
):
|
|
302
333
|
logger.debug("child action listener process killed...")
|
|
303
334
|
self._status = WorkerStatus.UNHEALTHY
|
|
@@ -310,7 +341,6 @@ class Worker:
|
|
|
310
341
|
except Exception as e:
|
|
311
342
|
logger.error(f"error checking listener health: {e}")
|
|
312
343
|
|
|
313
|
-
## Cleanup methods
|
|
314
344
|
def _setup_signal_handlers(self) -> None:
|
|
315
345
|
signal.signal(signal.SIGTERM, self._handle_exit_signal)
|
|
316
346
|
signal.signal(signal.SIGINT, self._handle_exit_signal)
|
|
@@ -323,70 +353,63 @@ class Worker:
|
|
|
323
353
|
|
|
324
354
|
def _handle_force_quit_signal(self, signum: int, frame: FrameType | None) -> None:
|
|
325
355
|
logger.info("received SIGQUIT...")
|
|
326
|
-
self.
|
|
356
|
+
self.loop.create_task(self._exit_forcefully())
|
|
327
357
|
|
|
328
|
-
async def
|
|
358
|
+
async def _close(self) -> None:
|
|
329
359
|
logger.info(f"closing worker '{self.name}'...")
|
|
330
360
|
self.killing = True
|
|
331
|
-
# self.action_queue.close()
|
|
332
|
-
# self.event_queue.close()
|
|
333
361
|
|
|
334
362
|
if self.action_runner is not None:
|
|
335
363
|
self.action_runner.cleanup()
|
|
336
364
|
|
|
365
|
+
if self.durable_action_runner is not None:
|
|
366
|
+
self.durable_action_runner.cleanup()
|
|
367
|
+
|
|
337
368
|
await self.action_listener_health_check
|
|
338
369
|
|
|
339
370
|
async def exit_gracefully(self) -> None:
|
|
340
371
|
logger.debug(f"gracefully stopping worker: {self.name}")
|
|
341
372
|
|
|
342
373
|
if self.killing:
|
|
343
|
-
return self.
|
|
374
|
+
return await self._exit_forcefully()
|
|
344
375
|
|
|
345
376
|
self.killing = True
|
|
346
377
|
|
|
347
|
-
|
|
378
|
+
if self.action_runner:
|
|
379
|
+
await self.action_runner.wait_for_tasks()
|
|
380
|
+
await self.action_runner.exit_gracefully()
|
|
348
381
|
|
|
349
|
-
|
|
382
|
+
if self.durable_action_runner:
|
|
383
|
+
await self.durable_action_runner.wait_for_tasks()
|
|
384
|
+
await self.durable_action_runner.exit_gracefully()
|
|
350
385
|
|
|
351
386
|
if self.action_listener_process and self.action_listener_process.is_alive():
|
|
352
387
|
self.action_listener_process.kill()
|
|
353
388
|
|
|
354
|
-
|
|
389
|
+
if (
|
|
390
|
+
self.durable_action_listener_process
|
|
391
|
+
and self.durable_action_listener_process.is_alive()
|
|
392
|
+
):
|
|
393
|
+
self.durable_action_listener_process.kill()
|
|
394
|
+
|
|
395
|
+
await self._close()
|
|
355
396
|
if self.loop and self.owned_loop:
|
|
356
397
|
self.loop.stop()
|
|
357
398
|
|
|
358
399
|
logger.info("👋")
|
|
359
400
|
|
|
360
|
-
def
|
|
401
|
+
async def _exit_forcefully(self) -> None:
|
|
361
402
|
self.killing = True
|
|
362
403
|
|
|
363
404
|
logger.debug(f"forcefully stopping worker: {self.name}")
|
|
364
405
|
|
|
365
|
-
self.
|
|
406
|
+
await self._close()
|
|
366
407
|
|
|
367
408
|
if self.action_listener_process:
|
|
368
|
-
self.action_listener_process.kill()
|
|
369
|
-
|
|
370
|
-
logger.info("👋")
|
|
371
|
-
sys.exit(
|
|
372
|
-
1
|
|
373
|
-
) # Exit immediately TODO - should we exit with 1 here, there may be other workers to cleanup
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
def register_on_worker(callable: HatchetCallable[T], worker: Worker) -> None:
|
|
377
|
-
worker.register_function(callable.get_action_name(), callable)
|
|
378
|
-
|
|
379
|
-
if callable.function_on_failure is not None:
|
|
380
|
-
worker.register_function(
|
|
381
|
-
callable.function_on_failure.get_action_name(), callable.function_on_failure
|
|
382
|
-
)
|
|
383
|
-
|
|
384
|
-
if callable.function_concurrency is not None:
|
|
385
|
-
worker.register_function(
|
|
386
|
-
callable.function_concurrency.get_action_name(),
|
|
387
|
-
callable.function_concurrency,
|
|
388
|
-
)
|
|
409
|
+
self.action_listener_process.kill()
|
|
389
410
|
|
|
390
|
-
|
|
411
|
+
if self.durable_action_listener_process:
|
|
412
|
+
self.durable_action_listener_process.kill()
|
|
391
413
|
|
|
392
|
-
|
|
414
|
+
logger.info("👋")
|
|
415
|
+
sys.exit(1)
|
hatchet_sdk/workflow_run.py
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
|
|
4
4
|
from hatchet_sdk.clients.run_event_listener import (
|
|
5
5
|
RunEventListener,
|
|
6
6
|
RunEventListenerClient,
|
|
7
7
|
)
|
|
8
8
|
from hatchet_sdk.clients.workflow_listener import PooledWorkflowRunListener
|
|
9
|
-
from hatchet_sdk.utils.aio_utils import
|
|
9
|
+
from hatchet_sdk.utils.aio_utils import get_active_event_loop
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class WorkflowRunRef:
|
|
13
|
-
workflow_run_id: str
|
|
14
|
-
|
|
15
13
|
def __init__(
|
|
16
14
|
self,
|
|
17
15
|
workflow_run_id: str,
|
|
@@ -22,17 +20,18 @@ class WorkflowRunRef:
|
|
|
22
20
|
self.workflow_listener = workflow_listener
|
|
23
21
|
self.workflow_run_event_listener = workflow_run_event_listener
|
|
24
22
|
|
|
25
|
-
def __str__(self):
|
|
23
|
+
def __str__(self) -> str:
|
|
26
24
|
return self.workflow_run_id
|
|
27
25
|
|
|
28
26
|
def stream(self) -> RunEventListener:
|
|
29
27
|
return self.workflow_run_event_listener.stream(self.workflow_run_id)
|
|
30
28
|
|
|
31
|
-
def
|
|
32
|
-
return self.workflow_listener.result(self.workflow_run_id)
|
|
29
|
+
async def aio_result(self) -> dict[str, Any]:
|
|
30
|
+
return await self.workflow_listener.result(self.workflow_run_id)
|
|
33
31
|
|
|
34
|
-
def
|
|
32
|
+
def result(self) -> dict[str, Any]:
|
|
35
33
|
coro = self.workflow_listener.result(self.workflow_run_id)
|
|
34
|
+
|
|
36
35
|
loop = get_active_event_loop()
|
|
37
36
|
|
|
38
37
|
if loop is None:
|
|
@@ -44,16 +43,3 @@ class WorkflowRunRef:
|
|
|
44
43
|
asyncio.set_event_loop(None)
|
|
45
44
|
else:
|
|
46
45
|
return loop.run_until_complete(coro)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
T = TypeVar("T")
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
class RunRef(WorkflowRunRef, Generic[T]):
|
|
53
|
-
async def result(self) -> T:
|
|
54
|
-
res = await self.workflow_listener.result(self.workflow_run_id)
|
|
55
|
-
|
|
56
|
-
if len(res) == 1:
|
|
57
|
-
return list(res.values())[0]
|
|
58
|
-
|
|
59
|
-
return res
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: hatchet-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0a1
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Alexander Belanger
|
|
6
6
|
Author-email: alexander@hatchet.run
|
|
@@ -28,8 +28,8 @@ Requires-Dist: opentelemetry-sdk (>=1.28.0,<2.0.0) ; extra == "otel"
|
|
|
28
28
|
Requires-Dist: prometheus-client (>=0.21.1,<0.22.0)
|
|
29
29
|
Requires-Dist: protobuf (>=5.29.1,<6.0.0)
|
|
30
30
|
Requires-Dist: pydantic (>=2.6.3,<3.0.0)
|
|
31
|
+
Requires-Dist: pydantic-settings (>=2.7.1,<3.0.0)
|
|
31
32
|
Requires-Dist: python-dateutil (>=2.9.0.post0,<3.0.0)
|
|
32
|
-
Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
|
|
33
33
|
Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
|
|
34
34
|
Requires-Dist: tenacity (>=8.4.1)
|
|
35
35
|
Requires-Dist: urllib3 (>=1.26.20)
|