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