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
|
@@ -3,23 +3,24 @@ import contextvars
|
|
|
3
3
|
import ctypes
|
|
4
4
|
import functools
|
|
5
5
|
import json
|
|
6
|
-
import time
|
|
7
6
|
import traceback
|
|
8
7
|
from concurrent.futures import ThreadPoolExecutor
|
|
9
8
|
from enum import Enum
|
|
10
9
|
from multiprocessing import Queue
|
|
11
10
|
from threading import Thread, current_thread
|
|
12
|
-
from typing import Any, Callable, Dict, cast
|
|
11
|
+
from typing import Any, Callable, Dict, Literal, cast, overload
|
|
13
12
|
|
|
14
13
|
from pydantic import BaseModel
|
|
15
14
|
|
|
16
|
-
from hatchet_sdk.client import
|
|
17
|
-
from hatchet_sdk.clients.admin import
|
|
18
|
-
from hatchet_sdk.clients.dispatcher.action_listener import Action
|
|
19
|
-
from hatchet_sdk.clients.dispatcher.dispatcher import
|
|
20
|
-
from hatchet_sdk.clients.
|
|
15
|
+
from hatchet_sdk.client import Client
|
|
16
|
+
from hatchet_sdk.clients.admin import AdminClient
|
|
17
|
+
from hatchet_sdk.clients.dispatcher.action_listener import Action, ActionType
|
|
18
|
+
from hatchet_sdk.clients.dispatcher.dispatcher import DispatcherClient
|
|
19
|
+
from hatchet_sdk.clients.durable_event_listener import DurableEventListener
|
|
20
|
+
from hatchet_sdk.clients.run_event_listener import RunEventListenerClient
|
|
21
21
|
from hatchet_sdk.clients.workflow_listener import PooledWorkflowRunListener
|
|
22
|
-
from hatchet_sdk.
|
|
22
|
+
from hatchet_sdk.config import ClientConfig
|
|
23
|
+
from hatchet_sdk.context.context import Context, DurableContext
|
|
23
24
|
from hatchet_sdk.context.worker_context import WorkerContext
|
|
24
25
|
from hatchet_sdk.contracts.dispatcher_pb2 import (
|
|
25
26
|
GROUP_KEY_EVENT_TYPE_COMPLETED,
|
|
@@ -28,14 +29,20 @@ from hatchet_sdk.contracts.dispatcher_pb2 import (
|
|
|
28
29
|
STEP_EVENT_TYPE_COMPLETED,
|
|
29
30
|
STEP_EVENT_TYPE_FAILED,
|
|
30
31
|
STEP_EVENT_TYPE_STARTED,
|
|
31
|
-
ActionType,
|
|
32
32
|
)
|
|
33
|
-
from hatchet_sdk.loader import ClientConfig
|
|
34
33
|
from hatchet_sdk.logger import logger
|
|
35
|
-
from hatchet_sdk.
|
|
36
|
-
|
|
34
|
+
from hatchet_sdk.runnables.contextvars import (
|
|
35
|
+
ctx_step_run_id,
|
|
36
|
+
ctx_worker_id,
|
|
37
|
+
ctx_workflow_run_id,
|
|
38
|
+
spawn_index_lock,
|
|
39
|
+
workflow_spawn_indices,
|
|
40
|
+
)
|
|
41
|
+
from hatchet_sdk.runnables.task import Task
|
|
42
|
+
from hatchet_sdk.runnables.types import R, TWorkflowInput
|
|
43
|
+
from hatchet_sdk.utils.typing import WorkflowValidator
|
|
37
44
|
from hatchet_sdk.worker.action_listener_process import ActionEvent
|
|
38
|
-
from hatchet_sdk.worker.runner.utils.capture_logs import copy_context_vars
|
|
45
|
+
from hatchet_sdk.worker.runner.utils.capture_logs import copy_context_vars
|
|
39
46
|
|
|
40
47
|
|
|
41
48
|
class WorkerStatus(Enum):
|
|
@@ -49,28 +56,28 @@ class Runner:
|
|
|
49
56
|
def __init__(
|
|
50
57
|
self,
|
|
51
58
|
name: str,
|
|
52
|
-
event_queue: "Queue[
|
|
53
|
-
|
|
59
|
+
event_queue: "Queue[ActionEvent]",
|
|
60
|
+
config: ClientConfig,
|
|
61
|
+
slots: int | None = None,
|
|
54
62
|
handle_kill: bool = True,
|
|
55
|
-
action_registry: dict[str,
|
|
63
|
+
action_registry: dict[str, Task[TWorkflowInput, R]] = {},
|
|
56
64
|
validator_registry: dict[str, WorkflowValidator] = {},
|
|
57
|
-
config: ClientConfig = ClientConfig(),
|
|
58
65
|
labels: dict[str, str | int] = {},
|
|
59
66
|
):
|
|
60
67
|
# We store the config so we can dynamically create clients for the dispatcher client.
|
|
61
68
|
self.config = config
|
|
62
|
-
self.client =
|
|
69
|
+
self.client = Client(config)
|
|
63
70
|
self.name = self.client.config.namespace + name
|
|
64
|
-
self.
|
|
71
|
+
self.slots = slots
|
|
65
72
|
self.tasks: dict[str, asyncio.Task[Any]] = {} # Store run ids and futures
|
|
66
73
|
self.contexts: dict[str, Context] = {} # Store run ids and contexts
|
|
67
|
-
self.action_registry
|
|
74
|
+
self.action_registry = action_registry
|
|
68
75
|
self.validator_registry = validator_registry
|
|
69
76
|
|
|
70
77
|
self.event_queue = event_queue
|
|
71
78
|
|
|
72
79
|
# The thread pool is used for synchronous functions which need to run concurrently
|
|
73
|
-
self.thread_pool = ThreadPoolExecutor(max_workers=
|
|
80
|
+
self.thread_pool = ThreadPoolExecutor(max_workers=slots)
|
|
74
81
|
self.threads: Dict[str, Thread] = {} # Store run ids and threads
|
|
75
82
|
|
|
76
83
|
self.killing = False
|
|
@@ -78,13 +85,14 @@ class Runner:
|
|
|
78
85
|
|
|
79
86
|
# We need to initialize a new admin and dispatcher client *after* we've started the event loop,
|
|
80
87
|
# otherwise the grpc.aio methods will use a different event loop and we'll get a bunch of errors.
|
|
81
|
-
self.dispatcher_client =
|
|
82
|
-
self.admin_client =
|
|
83
|
-
self.workflow_run_event_listener =
|
|
88
|
+
self.dispatcher_client = DispatcherClient(self.config)
|
|
89
|
+
self.admin_client = AdminClient(self.config)
|
|
90
|
+
self.workflow_run_event_listener = RunEventListenerClient(self.config)
|
|
84
91
|
self.client.workflow_listener = PooledWorkflowRunListener(self.config)
|
|
92
|
+
self.durable_event_listener = DurableEventListener(self.config)
|
|
85
93
|
|
|
86
94
|
self.worker_context = WorkerContext(
|
|
87
|
-
labels=labels, client=
|
|
95
|
+
labels=labels, client=Client(config=config).dispatcher
|
|
88
96
|
)
|
|
89
97
|
|
|
90
98
|
def create_workflow_run_url(self, action: Action) -> str:
|
|
@@ -130,7 +138,7 @@ class Runner:
|
|
|
130
138
|
ActionEvent(
|
|
131
139
|
action=action,
|
|
132
140
|
type=STEP_EVENT_TYPE_FAILED,
|
|
133
|
-
payload=str(
|
|
141
|
+
payload=str(pretty_format_exception(f"{e}", e)),
|
|
134
142
|
)
|
|
135
143
|
)
|
|
136
144
|
|
|
@@ -172,7 +180,7 @@ class Runner:
|
|
|
172
180
|
ActionEvent(
|
|
173
181
|
action=action,
|
|
174
182
|
type=GROUP_KEY_EVENT_TYPE_FAILED,
|
|
175
|
-
payload=str(
|
|
183
|
+
payload=str(pretty_format_exception(f"{e}", e)),
|
|
176
184
|
)
|
|
177
185
|
)
|
|
178
186
|
|
|
@@ -195,10 +203,9 @@ class Runner:
|
|
|
195
203
|
|
|
196
204
|
return inner_callback
|
|
197
205
|
|
|
198
|
-
## TODO: Stricter type hinting here
|
|
199
206
|
def thread_action_func(
|
|
200
|
-
self,
|
|
201
|
-
) ->
|
|
207
|
+
self, ctx: Context, task: Task[TWorkflowInput, R], action: Action
|
|
208
|
+
) -> R:
|
|
202
209
|
if action.step_run_id is not None and action.step_run_id != "":
|
|
203
210
|
self.threads[action.step_run_id] = current_thread()
|
|
204
211
|
elif (
|
|
@@ -207,25 +214,23 @@ class Runner:
|
|
|
207
214
|
):
|
|
208
215
|
self.threads[action.get_group_key_run_id] = current_thread()
|
|
209
216
|
|
|
210
|
-
return
|
|
217
|
+
return task.call(ctx)
|
|
211
218
|
|
|
212
|
-
## TODO: Stricter type hinting here
|
|
213
219
|
# We wrap all actions in an async func
|
|
214
220
|
async def async_wrapped_action_func(
|
|
215
221
|
self,
|
|
216
|
-
|
|
217
|
-
|
|
222
|
+
ctx: Context,
|
|
223
|
+
task: Task[TWorkflowInput, R],
|
|
218
224
|
action: Action,
|
|
219
225
|
run_id: str,
|
|
220
|
-
) ->
|
|
221
|
-
|
|
222
|
-
|
|
226
|
+
) -> R:
|
|
227
|
+
ctx_step_run_id.set(action.step_run_id)
|
|
228
|
+
ctx_workflow_run_id.set(action.workflow_run_id)
|
|
229
|
+
ctx_worker_id.set(action.worker_id)
|
|
223
230
|
|
|
224
231
|
try:
|
|
225
|
-
if
|
|
226
|
-
|
|
227
|
-
) or asyncio.iscoroutinefunction(action_func):
|
|
228
|
-
return await action_func(context)
|
|
232
|
+
if task.is_async_function:
|
|
233
|
+
return await task.aio_call(ctx)
|
|
229
234
|
else:
|
|
230
235
|
pfunc = functools.partial(
|
|
231
236
|
# we must copy the context vars to the new thread, as only asyncio natively supports
|
|
@@ -233,8 +238,8 @@ class Runner:
|
|
|
233
238
|
copy_context_vars,
|
|
234
239
|
contextvars.copy_context().items(),
|
|
235
240
|
self.thread_action_func,
|
|
236
|
-
|
|
237
|
-
|
|
241
|
+
ctx,
|
|
242
|
+
task,
|
|
238
243
|
action,
|
|
239
244
|
)
|
|
240
245
|
|
|
@@ -242,7 +247,7 @@ class Runner:
|
|
|
242
247
|
return await loop.run_in_executor(self.thread_pool, pfunc)
|
|
243
248
|
except Exception as e:
|
|
244
249
|
logger.error(
|
|
245
|
-
|
|
250
|
+
pretty_format_exception(
|
|
246
251
|
f"exception raised in action ({action.action_id}, retry={action.retry_count}):\n{e}",
|
|
247
252
|
e,
|
|
248
253
|
)
|
|
@@ -261,30 +266,29 @@ class Runner:
|
|
|
261
266
|
if run_id in self.contexts:
|
|
262
267
|
del self.contexts[run_id]
|
|
263
268
|
|
|
269
|
+
@overload
|
|
270
|
+
def create_context(
|
|
271
|
+
self, action: Action, is_durable: Literal[True] = True
|
|
272
|
+
) -> DurableContext: ...
|
|
273
|
+
|
|
274
|
+
@overload
|
|
264
275
|
def create_context(
|
|
265
|
-
self, action: Action,
|
|
276
|
+
self, action: Action, is_durable: Literal[False] = False
|
|
277
|
+
) -> Context: ...
|
|
278
|
+
|
|
279
|
+
def create_context(
|
|
280
|
+
self, action: Action, is_durable: bool = True
|
|
266
281
|
) -> Context | DurableContext:
|
|
267
|
-
|
|
268
|
-
return DurableContext(
|
|
269
|
-
action,
|
|
270
|
-
self.dispatcher_client,
|
|
271
|
-
self.admin_client,
|
|
272
|
-
self.client.event,
|
|
273
|
-
self.client.rest,
|
|
274
|
-
self.client.workflow_listener,
|
|
275
|
-
self.workflow_run_event_listener,
|
|
276
|
-
self.worker_context,
|
|
277
|
-
self.client.config.namespace,
|
|
278
|
-
validator_registry=self.validator_registry,
|
|
279
|
-
)
|
|
282
|
+
constructor = DurableContext if is_durable else Context
|
|
280
283
|
|
|
281
|
-
return
|
|
284
|
+
return constructor(
|
|
282
285
|
action,
|
|
283
286
|
self.dispatcher_client,
|
|
284
287
|
self.admin_client,
|
|
285
288
|
self.client.event,
|
|
286
289
|
self.client.rest,
|
|
287
290
|
self.client.workflow_listener,
|
|
291
|
+
self.durable_event_listener,
|
|
288
292
|
self.workflow_run_event_listener,
|
|
289
293
|
self.worker_context,
|
|
290
294
|
self.client.config.namespace,
|
|
@@ -292,22 +296,20 @@ class Runner:
|
|
|
292
296
|
)
|
|
293
297
|
|
|
294
298
|
## IMPORTANT: Keep this method's signature in sync with the wrapper in the OTel instrumentor
|
|
295
|
-
async def handle_start_step_run(self, action: Action) -> None
|
|
299
|
+
async def handle_start_step_run(self, action: Action) -> None:
|
|
296
300
|
action_name = action.action_id
|
|
297
301
|
|
|
298
302
|
# Find the corresponding action function from the registry
|
|
299
303
|
action_func = self.action_registry.get(action_name)
|
|
300
304
|
|
|
301
|
-
context = self.create_context(action, action_func)
|
|
302
|
-
|
|
303
|
-
self.contexts[action.step_run_id] = context
|
|
304
|
-
|
|
305
305
|
if action_func:
|
|
306
|
+
context = self.create_context(
|
|
307
|
+
action, True if action_func.is_durable else False
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
self.contexts[action.step_run_id] = context
|
|
306
311
|
self.event_queue.put(
|
|
307
|
-
ActionEvent(
|
|
308
|
-
action=action,
|
|
309
|
-
type=STEP_EVENT_TYPE_STARTED,
|
|
310
|
-
)
|
|
312
|
+
ActionEvent(action=action, type=STEP_EVENT_TYPE_STARTED, payload="")
|
|
311
313
|
)
|
|
312
314
|
|
|
313
315
|
loop = asyncio.get_event_loop()
|
|
@@ -322,25 +324,20 @@ class Runner:
|
|
|
322
324
|
|
|
323
325
|
try:
|
|
324
326
|
await task
|
|
325
|
-
except Exception
|
|
326
|
-
|
|
327
|
+
except Exception:
|
|
328
|
+
# do nothing, this should be caught in the callback
|
|
329
|
+
pass
|
|
327
330
|
|
|
328
|
-
|
|
331
|
+
## Once the step run completes, we need to remove the workflow spawn index
|
|
332
|
+
## so we don't leak memory
|
|
333
|
+
if action.workflow_run_id in workflow_spawn_indices:
|
|
334
|
+
async with spawn_index_lock:
|
|
335
|
+
workflow_spawn_indices.pop(action.workflow_run_id)
|
|
329
336
|
|
|
330
337
|
## IMPORTANT: Keep this method's signature in sync with the wrapper in the OTel instrumentor
|
|
331
338
|
async def handle_start_group_key_run(self, action: Action) -> Exception | None:
|
|
332
339
|
action_name = action.action_id
|
|
333
|
-
context =
|
|
334
|
-
action,
|
|
335
|
-
self.dispatcher_client,
|
|
336
|
-
self.admin_client,
|
|
337
|
-
self.client.event,
|
|
338
|
-
self.client.rest,
|
|
339
|
-
self.client.workflow_listener,
|
|
340
|
-
self.workflow_run_event_listener,
|
|
341
|
-
self.worker_context,
|
|
342
|
-
self.client.config.namespace,
|
|
343
|
-
)
|
|
340
|
+
context = self.create_context(action)
|
|
344
341
|
|
|
345
342
|
self.contexts[action.get_group_key_run_id] = context
|
|
346
343
|
|
|
@@ -351,8 +348,7 @@ class Runner:
|
|
|
351
348
|
# send an event that the group key run has started
|
|
352
349
|
self.event_queue.put(
|
|
353
350
|
ActionEvent(
|
|
354
|
-
action=action,
|
|
355
|
-
type=GROUP_KEY_EVENT_TYPE_STARTED,
|
|
351
|
+
action=action, type=GROUP_KEY_EVENT_TYPE_STARTED, payload=""
|
|
356
352
|
)
|
|
357
353
|
)
|
|
358
354
|
|
|
@@ -434,13 +430,12 @@ class Runner:
|
|
|
434
430
|
self.cleanup_run_id(run_id)
|
|
435
431
|
|
|
436
432
|
def serialize_output(self, output: Any) -> str:
|
|
437
|
-
|
|
438
433
|
if isinstance(output, BaseModel):
|
|
439
434
|
return output.model_dump_json()
|
|
440
435
|
|
|
441
436
|
if output is not None:
|
|
442
437
|
try:
|
|
443
|
-
return json.dumps(output)
|
|
438
|
+
return json.dumps(output, default=str)
|
|
444
439
|
except Exception as e:
|
|
445
440
|
logger.error(f"Could not serialize output: {e}")
|
|
446
441
|
return str(output)
|
|
@@ -455,6 +450,6 @@ class Runner:
|
|
|
455
450
|
running = len(self.tasks.keys())
|
|
456
451
|
|
|
457
452
|
|
|
458
|
-
def
|
|
453
|
+
def pretty_format_exception(message: str, e: Exception) -> str:
|
|
459
454
|
trace = "".join(traceback.format_exception(type(e), e, e.__traceback__))
|
|
460
455
|
return f"{message}\n{trace}"
|
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
import contextvars
|
|
2
1
|
import functools
|
|
3
2
|
import logging
|
|
4
3
|
from concurrent.futures import ThreadPoolExecutor
|
|
4
|
+
from contextvars import ContextVar
|
|
5
5
|
from io import StringIO
|
|
6
|
-
from typing import Any,
|
|
6
|
+
from typing import Any, Awaitable, Callable, ItemsView, ParamSpec, TypeVar
|
|
7
7
|
|
|
8
|
-
from hatchet_sdk import logger
|
|
9
8
|
from hatchet_sdk.clients.events import EventClient
|
|
9
|
+
from hatchet_sdk.logger import logger
|
|
10
|
+
from hatchet_sdk.runnables.contextvars import ctx_step_run_id, ctx_workflow_run_id
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
)
|
|
14
|
-
sr: contextvars.ContextVar[str | None] = contextvars.ContextVar(
|
|
15
|
-
"step_run_id", default=None
|
|
16
|
-
)
|
|
12
|
+
T = TypeVar("T")
|
|
13
|
+
P = ParamSpec("P")
|
|
17
14
|
|
|
18
15
|
|
|
19
|
-
def copy_context_vars(
|
|
16
|
+
def copy_context_vars(
|
|
17
|
+
ctx_vars: ItemsView[ContextVar[Any], Any],
|
|
18
|
+
func: Callable[P, T],
|
|
19
|
+
*args: P.args,
|
|
20
|
+
**kwargs: P.kwargs,
|
|
21
|
+
) -> T:
|
|
20
22
|
for var, value in ctx_vars:
|
|
21
23
|
var.set(value)
|
|
22
24
|
return func(*args, **kwargs)
|
|
@@ -25,19 +27,20 @@ def copy_context_vars(ctx_vars, func, *args, **kwargs):
|
|
|
25
27
|
class InjectingFilter(logging.Filter):
|
|
26
28
|
# For some reason, only the InjectingFilter has access to the contextvars method sr.get(),
|
|
27
29
|
# otherwise we would use emit within the CustomLogHandler
|
|
28
|
-
def filter(self, record):
|
|
29
|
-
|
|
30
|
-
record.
|
|
30
|
+
def filter(self, record: logging.LogRecord) -> bool:
|
|
31
|
+
## TODO: Change how we do this to not assign to the log record
|
|
32
|
+
record.workflow_run_id = ctx_workflow_run_id.get()
|
|
33
|
+
record.step_run_id = ctx_step_run_id.get()
|
|
31
34
|
return True
|
|
32
35
|
|
|
33
36
|
|
|
34
|
-
class CustomLogHandler(logging.StreamHandler):
|
|
35
|
-
def __init__(self, event_client: EventClient, stream=None):
|
|
37
|
+
class CustomLogHandler(logging.StreamHandler): # type: ignore[type-arg]
|
|
38
|
+
def __init__(self, event_client: EventClient, stream: StringIO | None = None):
|
|
36
39
|
super().__init__(stream)
|
|
37
40
|
self.logger_thread_pool = ThreadPoolExecutor(max_workers=1)
|
|
38
41
|
self.event_client = event_client
|
|
39
42
|
|
|
40
|
-
def _log(self, line: str, step_run_id: str | None):
|
|
43
|
+
def _log(self, line: str, step_run_id: str | None) -> None:
|
|
41
44
|
try:
|
|
42
45
|
if not step_run_id:
|
|
43
46
|
return
|
|
@@ -46,20 +49,20 @@ class CustomLogHandler(logging.StreamHandler):
|
|
|
46
49
|
except Exception as e:
|
|
47
50
|
logger.error(f"Error logging: {e}")
|
|
48
51
|
|
|
49
|
-
def emit(self, record):
|
|
52
|
+
def emit(self, record: logging.LogRecord) -> None:
|
|
50
53
|
super().emit(record)
|
|
51
54
|
|
|
52
55
|
log_entry = self.format(record)
|
|
53
|
-
|
|
56
|
+
|
|
57
|
+
## TODO: Change how we do this to not assign to the log record
|
|
58
|
+
self.logger_thread_pool.submit(self._log, log_entry, record.step_run_id) # type: ignore
|
|
54
59
|
|
|
55
60
|
|
|
56
61
|
def capture_logs(
|
|
57
|
-
logger: logging.Logger,
|
|
58
|
-
|
|
59
|
-
func: Coroutine[Any, Any, Any],
|
|
60
|
-
):
|
|
62
|
+
logger: logging.Logger, event_client: "EventClient", func: Callable[P, Awaitable[T]]
|
|
63
|
+
) -> Callable[P, Awaitable[T]]:
|
|
61
64
|
@functools.wraps(func)
|
|
62
|
-
async def wrapper(*args, **kwargs):
|
|
65
|
+
async def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
|
|
63
66
|
if not logger:
|
|
64
67
|
raise Exception("No logger configured on client")
|
|
65
68
|
|