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/hatchet.py
CHANGED
|
@@ -1,197 +1,46 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import logging
|
|
3
|
-
from typing import Any, Callable,
|
|
4
|
-
|
|
5
|
-
from pydantic import BaseModel
|
|
6
|
-
from typing_extensions import deprecated
|
|
3
|
+
from typing import Any, Callable, Type, TypeVar, cast, overload
|
|
7
4
|
|
|
5
|
+
from hatchet_sdk.client import Client, new_client, new_client_raw
|
|
6
|
+
from hatchet_sdk.clients.admin import AdminClient
|
|
7
|
+
from hatchet_sdk.clients.dispatcher.dispatcher import DispatcherClient
|
|
8
|
+
from hatchet_sdk.clients.events import EventClient
|
|
8
9
|
from hatchet_sdk.clients.rest_client import RestApi
|
|
10
|
+
from hatchet_sdk.clients.run_event_listener import RunEventListenerClient
|
|
11
|
+
from hatchet_sdk.config import ClientConfig
|
|
9
12
|
from hatchet_sdk.context.context import Context
|
|
10
|
-
from hatchet_sdk.contracts.workflows_pb2 import
|
|
11
|
-
ConcurrencyLimitStrategy,
|
|
12
|
-
CreateStepRateLimit,
|
|
13
|
-
DesiredWorkerLabels,
|
|
14
|
-
StickyStrategy,
|
|
15
|
-
)
|
|
13
|
+
from hatchet_sdk.contracts.workflows_pb2 import DesiredWorkerLabels
|
|
16
14
|
from hatchet_sdk.features.cron import CronClient
|
|
17
15
|
from hatchet_sdk.features.scheduled import ScheduledClient
|
|
18
16
|
from hatchet_sdk.labels import DesiredWorkerLabel
|
|
19
|
-
from hatchet_sdk.
|
|
17
|
+
from hatchet_sdk.logger import logger
|
|
20
18
|
from hatchet_sdk.rate_limit import RateLimit
|
|
21
|
-
from hatchet_sdk.
|
|
22
|
-
|
|
23
|
-
from .client import Client, new_client, new_client_raw
|
|
24
|
-
from .clients.admin import AdminClient
|
|
25
|
-
from .clients.dispatcher.dispatcher import DispatcherClient
|
|
26
|
-
from .clients.events import EventClient
|
|
27
|
-
from .clients.run_event_listener import RunEventListenerClient
|
|
28
|
-
from .logger import logger
|
|
29
|
-
from .worker.worker import Worker
|
|
30
|
-
from .workflow import (
|
|
19
|
+
from hatchet_sdk.worker.worker import Worker
|
|
20
|
+
from hatchet_sdk.workflow import (
|
|
31
21
|
ConcurrencyExpression,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
22
|
+
EmptyModel,
|
|
23
|
+
Step,
|
|
24
|
+
StepType,
|
|
25
|
+
StickyStrategy,
|
|
26
|
+
Task,
|
|
27
|
+
TWorkflowInput,
|
|
28
|
+
WorkflowConfig,
|
|
29
|
+
WorkflowDeclaration,
|
|
35
30
|
)
|
|
36
31
|
|
|
37
|
-
T = TypeVar("T", bound=BaseModel)
|
|
38
32
|
R = TypeVar("R")
|
|
39
|
-
P = ParamSpec("P")
|
|
40
|
-
|
|
41
|
-
TWorkflow = TypeVar("TWorkflow", bound=object)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def workflow(
|
|
45
|
-
name: str = "",
|
|
46
|
-
on_events: list[str] | None = None,
|
|
47
|
-
on_crons: list[str] | None = None,
|
|
48
|
-
version: str = "",
|
|
49
|
-
timeout: str = "60m",
|
|
50
|
-
schedule_timeout: str = "5m",
|
|
51
|
-
sticky: Union[StickyStrategy.Value, None] = None, # type: ignore[name-defined]
|
|
52
|
-
default_priority: int | None = None,
|
|
53
|
-
concurrency: ConcurrencyExpression | None = None,
|
|
54
|
-
input_validator: Type[T] | None = None,
|
|
55
|
-
) -> Callable[[Type[TWorkflow]], WorkflowMeta]:
|
|
56
|
-
on_events = on_events or []
|
|
57
|
-
on_crons = on_crons or []
|
|
58
|
-
|
|
59
|
-
def inner(cls: Type[TWorkflow]) -> WorkflowMeta:
|
|
60
|
-
nonlocal name
|
|
61
|
-
name = name or str(cls.__name__)
|
|
62
|
-
|
|
63
|
-
setattr(cls, "on_events", on_events)
|
|
64
|
-
setattr(cls, "on_crons", on_crons)
|
|
65
|
-
setattr(cls, "name", name)
|
|
66
|
-
setattr(cls, "version", version)
|
|
67
|
-
setattr(cls, "timeout", timeout)
|
|
68
|
-
setattr(cls, "schedule_timeout", schedule_timeout)
|
|
69
|
-
setattr(cls, "sticky", sticky)
|
|
70
|
-
setattr(cls, "default_priority", default_priority)
|
|
71
|
-
setattr(cls, "concurrency_expression", concurrency)
|
|
72
|
-
|
|
73
|
-
# Define a new class with the same name and bases as the original, but
|
|
74
|
-
# with WorkflowMeta as its metaclass
|
|
75
|
-
|
|
76
|
-
## TODO: Figure out how to type this metaclass correctly
|
|
77
|
-
setattr(cls, "input_validator", input_validator)
|
|
78
|
-
|
|
79
|
-
return WorkflowMeta(name, cls.__bases__, dict(cls.__dict__))
|
|
80
|
-
|
|
81
|
-
return inner
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
def step(
|
|
85
|
-
name: str = "",
|
|
86
|
-
timeout: str = "",
|
|
87
|
-
parents: list[str] | None = None,
|
|
88
|
-
retries: int = 0,
|
|
89
|
-
rate_limits: list[RateLimit] | None = None,
|
|
90
|
-
desired_worker_labels: dict[str, DesiredWorkerLabel] = {},
|
|
91
|
-
backoff_factor: float | None = None,
|
|
92
|
-
backoff_max_seconds: int | None = None,
|
|
93
|
-
) -> Callable[[Callable[P, R]], Callable[P, R]]:
|
|
94
|
-
parents = parents or []
|
|
95
|
-
|
|
96
|
-
def inner(func: Callable[P, R]) -> Callable[P, R]:
|
|
97
|
-
limits = None
|
|
98
|
-
if rate_limits:
|
|
99
|
-
limits = [rate_limit._req for rate_limit in rate_limits or []]
|
|
100
|
-
|
|
101
|
-
setattr(func, "_step_name", name.lower() or str(func.__name__).lower())
|
|
102
|
-
setattr(func, "_step_parents", parents)
|
|
103
|
-
setattr(func, "_step_timeout", timeout)
|
|
104
|
-
setattr(func, "_step_retries", retries)
|
|
105
|
-
setattr(func, "_step_rate_limits", limits)
|
|
106
|
-
setattr(func, "_step_backoff_factor", backoff_factor)
|
|
107
|
-
setattr(func, "_step_backoff_max_seconds", backoff_max_seconds)
|
|
108
|
-
|
|
109
|
-
def create_label(d: DesiredWorkerLabel) -> DesiredWorkerLabels:
|
|
110
|
-
value = d["value"] if "value" in d else None
|
|
111
|
-
return DesiredWorkerLabels(
|
|
112
|
-
strValue=str(value) if not isinstance(value, int) else None,
|
|
113
|
-
intValue=value if isinstance(value, int) else None,
|
|
114
|
-
required=d["required"] if "required" in d else None, # type: ignore[arg-type]
|
|
115
|
-
weight=d["weight"] if "weight" in d else None,
|
|
116
|
-
comparator=d["comparator"] if "comparator" in d else None, # type: ignore[arg-type]
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
setattr(
|
|
120
|
-
func,
|
|
121
|
-
"_step_desired_worker_labels",
|
|
122
|
-
{key: create_label(d) for key, d in desired_worker_labels.items()},
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
return func
|
|
126
|
-
|
|
127
|
-
return inner
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
def on_failure_step(
|
|
131
|
-
name: str = "",
|
|
132
|
-
timeout: str = "",
|
|
133
|
-
retries: int = 0,
|
|
134
|
-
rate_limits: list[RateLimit] | None = None,
|
|
135
|
-
backoff_factor: float | None = None,
|
|
136
|
-
backoff_max_seconds: int | None = None,
|
|
137
|
-
) -> Callable[..., Any]:
|
|
138
|
-
def inner(func: Callable[[Context], Any]) -> Callable[[Context], Any]:
|
|
139
|
-
limits = None
|
|
140
|
-
if rate_limits:
|
|
141
|
-
limits = [
|
|
142
|
-
CreateStepRateLimit(key=rate_limit.static_key, units=rate_limit.units) # type: ignore[arg-type]
|
|
143
|
-
for rate_limit in rate_limits or []
|
|
144
|
-
]
|
|
145
|
-
|
|
146
|
-
setattr(
|
|
147
|
-
func, "_on_failure_step_name", name.lower() or str(func.__name__).lower()
|
|
148
|
-
)
|
|
149
|
-
setattr(func, "_on_failure_step_timeout", timeout)
|
|
150
|
-
setattr(func, "_on_failure_step_retries", retries)
|
|
151
|
-
setattr(func, "_on_failure_step_rate_limits", limits)
|
|
152
|
-
setattr(func, "_on_failure_step_backoff_factor", backoff_factor)
|
|
153
|
-
setattr(func, "_on_failure_step_backoff_max_seconds", backoff_max_seconds)
|
|
154
|
-
|
|
155
|
-
return func
|
|
156
|
-
|
|
157
|
-
return inner
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
def concurrency(
|
|
161
|
-
name: str = "",
|
|
162
|
-
max_runs: int = 1,
|
|
163
|
-
limit_strategy: ConcurrencyLimitStrategy = ConcurrencyLimitStrategy.CANCEL_IN_PROGRESS,
|
|
164
|
-
) -> Callable[..., Any]:
|
|
165
|
-
def inner(func: Callable[[Context], Any]) -> Callable[[Context], Any]:
|
|
166
|
-
setattr(
|
|
167
|
-
func,
|
|
168
|
-
"_concurrency_fn_name",
|
|
169
|
-
name.lower() or str(func.__name__).lower(),
|
|
170
|
-
)
|
|
171
|
-
setattr(func, "_concurrency_max_runs", max_runs)
|
|
172
|
-
setattr(func, "_concurrency_limit_strategy", limit_strategy)
|
|
173
|
-
|
|
174
|
-
return func
|
|
175
|
-
|
|
176
|
-
return inner
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
class HatchetRest:
|
|
180
|
-
"""
|
|
181
|
-
Main client for interacting with the Hatchet API.
|
|
182
|
-
|
|
183
|
-
This class provides access to various client interfaces and utility methods
|
|
184
|
-
for working with Hatchet via the REST API,
|
|
185
|
-
|
|
186
|
-
Attributes:
|
|
187
|
-
rest (RestApi): Interface for REST API operations.
|
|
188
|
-
"""
|
|
189
33
|
|
|
190
|
-
rest: RestApi
|
|
191
34
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
35
|
+
def transform_desired_worker_label(d: DesiredWorkerLabel) -> DesiredWorkerLabels:
|
|
36
|
+
value = d.value
|
|
37
|
+
return DesiredWorkerLabels(
|
|
38
|
+
strValue=value if not isinstance(value, int) else None,
|
|
39
|
+
intValue=value if isinstance(value, int) else None,
|
|
40
|
+
required=d.required,
|
|
41
|
+
weight=d.weight,
|
|
42
|
+
comparator=d.comparator, # type: ignore[arg-type]
|
|
43
|
+
)
|
|
195
44
|
|
|
196
45
|
|
|
197
46
|
class Hatchet:
|
|
@@ -227,7 +76,7 @@ class Hatchet:
|
|
|
227
76
|
def __init__(
|
|
228
77
|
self,
|
|
229
78
|
debug: bool = False,
|
|
230
|
-
client:
|
|
79
|
+
client: Client | None = None,
|
|
231
80
|
config: ClientConfig = ClientConfig(),
|
|
232
81
|
):
|
|
233
82
|
"""
|
|
@@ -238,24 +87,14 @@ class Hatchet:
|
|
|
238
87
|
client (Optional[Client], optional): A pre-configured Client instance. Defaults to None.
|
|
239
88
|
config (ClientConfig, optional): Configuration for creating a new Client. Defaults to ClientConfig().
|
|
240
89
|
"""
|
|
241
|
-
if client is not None:
|
|
242
|
-
self._client = client
|
|
243
|
-
else:
|
|
244
|
-
self._client = new_client(config, debug)
|
|
245
90
|
|
|
246
91
|
if debug:
|
|
247
92
|
logger.setLevel(logging.DEBUG)
|
|
248
93
|
|
|
94
|
+
self._client = client if client else new_client(config, debug)
|
|
249
95
|
self.cron = CronClient(self._client)
|
|
250
96
|
self.scheduled = ScheduledClient(self._client)
|
|
251
97
|
|
|
252
|
-
@property
|
|
253
|
-
@deprecated(
|
|
254
|
-
"Direct access to client is deprecated and will be removed in a future version. Use specific client properties (Hatchet.admin, Hatchet.dispatcher, Hatchet.event, Hatchet.rest) instead. [0.32.0]",
|
|
255
|
-
)
|
|
256
|
-
def client(self) -> Client:
|
|
257
|
-
return self._client
|
|
258
|
-
|
|
259
98
|
@property
|
|
260
99
|
def admin(self) -> AdminClient:
|
|
261
100
|
return self._client.admin
|
|
@@ -284,13 +123,108 @@ class Hatchet:
|
|
|
284
123
|
def tenant_id(self) -> str:
|
|
285
124
|
return self._client.config.tenant_id
|
|
286
125
|
|
|
287
|
-
|
|
126
|
+
def step(
|
|
127
|
+
self,
|
|
128
|
+
name: str = "",
|
|
129
|
+
timeout: str = "60m",
|
|
130
|
+
parents: list[str] = [],
|
|
131
|
+
retries: int = 0,
|
|
132
|
+
rate_limits: list[RateLimit] = [],
|
|
133
|
+
desired_worker_labels: dict[str, DesiredWorkerLabel] = {},
|
|
134
|
+
backoff_factor: float | None = None,
|
|
135
|
+
backoff_max_seconds: int | None = None,
|
|
136
|
+
) -> Callable[[Callable[[Any, Context], R]], Step[R]]:
|
|
137
|
+
def inner(func: Callable[[Any, Context], R]) -> Step[R]:
|
|
138
|
+
return Step(
|
|
139
|
+
fn=func,
|
|
140
|
+
type=StepType.DEFAULT,
|
|
141
|
+
name=name.lower() or str(func.__name__).lower(),
|
|
142
|
+
timeout=timeout,
|
|
143
|
+
parents=parents,
|
|
144
|
+
retries=retries,
|
|
145
|
+
rate_limits=[r for rate_limit in rate_limits if (r := rate_limit._req)],
|
|
146
|
+
desired_worker_labels={
|
|
147
|
+
key: transform_desired_worker_label(d)
|
|
148
|
+
for key, d in desired_worker_labels.items()
|
|
149
|
+
},
|
|
150
|
+
backoff_factor=backoff_factor,
|
|
151
|
+
backoff_max_seconds=backoff_max_seconds,
|
|
152
|
+
)
|
|
288
153
|
|
|
289
|
-
|
|
154
|
+
return inner
|
|
290
155
|
|
|
291
|
-
|
|
156
|
+
def on_failure_step(
|
|
157
|
+
self,
|
|
158
|
+
name: str = "",
|
|
159
|
+
timeout: str = "60m",
|
|
160
|
+
parents: list[str] = [],
|
|
161
|
+
retries: int = 0,
|
|
162
|
+
rate_limits: list[RateLimit] = [],
|
|
163
|
+
desired_worker_labels: dict[str, DesiredWorkerLabel] = {},
|
|
164
|
+
backoff_factor: float | None = None,
|
|
165
|
+
backoff_max_seconds: int | None = None,
|
|
166
|
+
) -> Callable[[Callable[[Any, Context], R]], Step[R]]:
|
|
167
|
+
def inner(func: Callable[[Any, Context], R]) -> Step[R]:
|
|
168
|
+
return Step(
|
|
169
|
+
fn=func,
|
|
170
|
+
type=StepType.ON_FAILURE,
|
|
171
|
+
name=name.lower() or str(func.__name__).lower(),
|
|
172
|
+
timeout=timeout,
|
|
173
|
+
parents=parents,
|
|
174
|
+
retries=retries,
|
|
175
|
+
rate_limits=[r for rate_limit in rate_limits if (r := rate_limit._req)],
|
|
176
|
+
desired_worker_labels={
|
|
177
|
+
key: transform_desired_worker_label(d)
|
|
178
|
+
for key, d in desired_worker_labels.items()
|
|
179
|
+
},
|
|
180
|
+
backoff_factor=backoff_factor,
|
|
181
|
+
backoff_max_seconds=backoff_max_seconds,
|
|
182
|
+
)
|
|
292
183
|
|
|
293
|
-
|
|
184
|
+
return inner
|
|
185
|
+
|
|
186
|
+
def task(
|
|
187
|
+
self,
|
|
188
|
+
name: str = "",
|
|
189
|
+
on_events: list[str] = [],
|
|
190
|
+
on_crons: list[str] = [],
|
|
191
|
+
version: str = "",
|
|
192
|
+
timeout: str = "60m",
|
|
193
|
+
schedule_timeout: str = "5m",
|
|
194
|
+
sticky: StickyStrategy | None = None,
|
|
195
|
+
retries: int = 0,
|
|
196
|
+
rate_limits: list[RateLimit] = [],
|
|
197
|
+
desired_worker_labels: dict[str, DesiredWorkerLabel] = {},
|
|
198
|
+
concurrency: ConcurrencyExpression | None = None,
|
|
199
|
+
on_failure: Task[Any, Any] | None = None,
|
|
200
|
+
default_priority: int = 1,
|
|
201
|
+
input_validator: Type[TWorkflowInput] | None = None,
|
|
202
|
+
backoff_factor: float | None = None,
|
|
203
|
+
backoff_max_seconds: int | None = None,
|
|
204
|
+
) -> Callable[[Callable[[Context], R]], Task[R, TWorkflowInput]]:
|
|
205
|
+
def inner(func: Callable[[Context], R]) -> Task[R, TWorkflowInput]:
|
|
206
|
+
return Task[R, TWorkflowInput](
|
|
207
|
+
func,
|
|
208
|
+
hatchet=self,
|
|
209
|
+
name=name,
|
|
210
|
+
on_events=on_events,
|
|
211
|
+
on_crons=on_crons,
|
|
212
|
+
version=version,
|
|
213
|
+
timeout=timeout,
|
|
214
|
+
schedule_timeout=schedule_timeout,
|
|
215
|
+
sticky=sticky,
|
|
216
|
+
retries=retries,
|
|
217
|
+
rate_limits=rate_limits,
|
|
218
|
+
desired_worker_labels=desired_worker_labels,
|
|
219
|
+
concurrency=concurrency,
|
|
220
|
+
on_failure=on_failure,
|
|
221
|
+
default_priority=default_priority,
|
|
222
|
+
input_validator=input_validator,
|
|
223
|
+
backoff_factor=backoff_factor,
|
|
224
|
+
backoff_max_seconds=backoff_max_seconds,
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
return inner
|
|
294
228
|
|
|
295
229
|
def worker(
|
|
296
230
|
self, name: str, max_runs: int | None = None, labels: dict[str, str | int] = {}
|
|
@@ -308,3 +242,66 @@ class Hatchet:
|
|
|
308
242
|
debug=self._client.debug,
|
|
309
243
|
owned_loop=loop is None,
|
|
310
244
|
)
|
|
245
|
+
|
|
246
|
+
@overload
|
|
247
|
+
def declare_workflow(
|
|
248
|
+
self,
|
|
249
|
+
*,
|
|
250
|
+
name: str = "",
|
|
251
|
+
on_events: list[str] = [],
|
|
252
|
+
on_crons: list[str] = [],
|
|
253
|
+
version: str = "",
|
|
254
|
+
timeout: str = "60m",
|
|
255
|
+
schedule_timeout: str = "5m",
|
|
256
|
+
sticky: StickyStrategy | None = None,
|
|
257
|
+
default_priority: int = 1,
|
|
258
|
+
concurrency: ConcurrencyExpression | None = None,
|
|
259
|
+
input_validator: None = None,
|
|
260
|
+
) -> WorkflowDeclaration[EmptyModel]: ...
|
|
261
|
+
|
|
262
|
+
@overload
|
|
263
|
+
def declare_workflow(
|
|
264
|
+
self,
|
|
265
|
+
*,
|
|
266
|
+
name: str = "",
|
|
267
|
+
on_events: list[str] = [],
|
|
268
|
+
on_crons: list[str] = [],
|
|
269
|
+
version: str = "",
|
|
270
|
+
timeout: str = "60m",
|
|
271
|
+
schedule_timeout: str = "5m",
|
|
272
|
+
sticky: StickyStrategy | None = None,
|
|
273
|
+
default_priority: int = 1,
|
|
274
|
+
concurrency: ConcurrencyExpression | None = None,
|
|
275
|
+
input_validator: Type[TWorkflowInput],
|
|
276
|
+
) -> WorkflowDeclaration[TWorkflowInput]: ...
|
|
277
|
+
|
|
278
|
+
def declare_workflow(
|
|
279
|
+
self,
|
|
280
|
+
*,
|
|
281
|
+
name: str = "",
|
|
282
|
+
on_events: list[str] = [],
|
|
283
|
+
on_crons: list[str] = [],
|
|
284
|
+
version: str = "",
|
|
285
|
+
timeout: str = "60m",
|
|
286
|
+
schedule_timeout: str = "5m",
|
|
287
|
+
sticky: StickyStrategy | None = None,
|
|
288
|
+
default_priority: int = 1,
|
|
289
|
+
concurrency: ConcurrencyExpression | None = None,
|
|
290
|
+
input_validator: Type[TWorkflowInput] | None = None,
|
|
291
|
+
) -> WorkflowDeclaration[EmptyModel] | WorkflowDeclaration[TWorkflowInput]:
|
|
292
|
+
return WorkflowDeclaration[TWorkflowInput](
|
|
293
|
+
WorkflowConfig(
|
|
294
|
+
name=name,
|
|
295
|
+
on_events=on_events,
|
|
296
|
+
on_crons=on_crons,
|
|
297
|
+
version=version,
|
|
298
|
+
timeout=timeout,
|
|
299
|
+
schedule_timeout=schedule_timeout,
|
|
300
|
+
sticky=sticky,
|
|
301
|
+
default_priority=default_priority,
|
|
302
|
+
concurrency=concurrency,
|
|
303
|
+
input_validator=input_validator
|
|
304
|
+
or cast(Type[TWorkflowInput], EmptyModel),
|
|
305
|
+
),
|
|
306
|
+
self,
|
|
307
|
+
)
|
hatchet_sdk/labels.py
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
from
|
|
1
|
+
from pydantic import BaseModel
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
class DesiredWorkerLabel(
|
|
4
|
+
class DesiredWorkerLabel(BaseModel):
|
|
5
5
|
value: str | int
|
|
6
|
-
required: bool
|
|
6
|
+
required: bool = False
|
|
7
7
|
weight: int | None = None
|
|
8
|
-
comparator: int | None =
|
|
9
|
-
None # _ClassVar[WorkerLabelComparator] TODO figure out type
|
|
10
|
-
)
|
|
8
|
+
comparator: int | None = None
|
hatchet_sdk/metadata.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
def get_metadata(token: str):
|
|
1
|
+
def get_metadata(token: str) -> list[tuple[str, str]]:
|
|
2
2
|
return [("authorization", "bearer " + token)]
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from importlib.metadata import version
|
|
2
2
|
from typing import Any, Callable, Collection, Coroutine
|
|
3
3
|
|
|
4
|
+
from hatchet_sdk.utils.typing import JSONSerializableMapping
|
|
5
|
+
|
|
4
6
|
try:
|
|
5
7
|
from opentelemetry.context import Context
|
|
6
8
|
from opentelemetry.instrumentation.instrumentor import ( # type: ignore[attr-defined]
|
|
@@ -13,6 +15,7 @@ try:
|
|
|
13
15
|
StatusCode,
|
|
14
16
|
TracerProvider,
|
|
15
17
|
get_tracer,
|
|
18
|
+
get_tracer_provider,
|
|
16
19
|
)
|
|
17
20
|
from opentelemetry.trace.propagation.tracecontext import (
|
|
18
21
|
TraceContextTextMapPropagator,
|
|
@@ -43,49 +46,123 @@ hatchet_sdk_version = version("hatchet-sdk")
|
|
|
43
46
|
|
|
44
47
|
InstrumentKwargs = TracerProvider | MeterProvider | None
|
|
45
48
|
|
|
49
|
+
OTEL_TRACEPARENT_KEY = "traceparent"
|
|
46
50
|
|
|
47
|
-
class HatchetInstrumentor(BaseInstrumentor): # type: ignore[misc]
|
|
48
|
-
OTEL_TRACEPARENT_KEY = "traceparent"
|
|
49
51
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
meter_provider: MeterProvider = NoOpMeterProvider(),
|
|
54
|
-
):
|
|
55
|
-
self.tracer_provider = tracer_provider
|
|
56
|
-
self.meter_provider = meter_provider
|
|
52
|
+
def create_traceparent() -> str | None:
|
|
53
|
+
"""
|
|
54
|
+
Creates and returns a W3C traceparent header value using OpenTelemetry's context propagation.
|
|
57
55
|
|
|
58
|
-
|
|
56
|
+
The traceparent header is used to propagate context information across service boundaries
|
|
57
|
+
in distributed tracing systems. It follows the W3C Trace Context specification.
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
:returns: A W3C-formatted traceparent header value if successful, None if the context
|
|
60
|
+
injection fails or no active span exists.\n
|
|
61
|
+
Example: `00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01`
|
|
62
|
+
:rtype: str | None:
|
|
63
|
+
"""
|
|
63
64
|
|
|
64
|
-
|
|
65
|
+
carrier: dict[str, str] = {}
|
|
66
|
+
TraceContextTextMapPropagator().inject(carrier)
|
|
65
67
|
|
|
66
|
-
|
|
67
|
-
self, metadata: dict[str, str] | None
|
|
68
|
-
) -> Context | None:
|
|
69
|
-
if not metadata:
|
|
70
|
-
return None
|
|
68
|
+
return carrier.get("traceparent")
|
|
71
69
|
|
|
72
|
-
traceparent = metadata.get(self.OTEL_TRACEPARENT_KEY)
|
|
73
70
|
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
def parse_carrier_from_metadata(
|
|
72
|
+
metadata: JSONSerializableMapping | None,
|
|
73
|
+
) -> Context | None:
|
|
74
|
+
"""
|
|
75
|
+
Parses OpenTelemetry trace context from a metadata dictionary.
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
Extracts the trace context from metadata using the W3C Trace Context format,
|
|
78
|
+
specifically looking for the `traceparent` header.
|
|
79
|
+
|
|
80
|
+
:param metadata: A dictionary containing metadata key-value pairs,
|
|
81
|
+
potentially including the `traceparent` header. Can be None.
|
|
82
|
+
:type metadata: dict[str, str] | None
|
|
83
|
+
:returns: The extracted OpenTelemetry Context object if a valid `traceparent`
|
|
84
|
+
is found in the metadata, otherwise None.
|
|
85
|
+
:rtype: Context | None
|
|
86
|
+
|
|
87
|
+
:Example:
|
|
88
|
+
|
|
89
|
+
>>> metadata = {"traceparent": "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01"}
|
|
90
|
+
>>> context = parse_carrier_from_metadata(metadata)
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
if not metadata:
|
|
94
|
+
return None
|
|
95
|
+
|
|
96
|
+
traceparent = metadata.get(OTEL_TRACEPARENT_KEY)
|
|
97
|
+
|
|
98
|
+
if not traceparent:
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
return TraceContextTextMapPropagator().extract({OTEL_TRACEPARENT_KEY: traceparent})
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def inject_traceparent_into_metadata(
|
|
105
|
+
metadata: dict[str, str], traceparent: str | None = None
|
|
106
|
+
) -> dict[str, str]:
|
|
107
|
+
"""
|
|
108
|
+
Injects OpenTelemetry `traceparent` into a metadata dictionary.
|
|
80
109
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if traceparent:
|
|
85
|
-
metadata[self.OTEL_TRACEPARENT_KEY] = traceparent
|
|
110
|
+
Takes a metadata dictionary and an optional `traceparent` string,
|
|
111
|
+
returning a new metadata dictionary with the `traceparent` added under the
|
|
112
|
+
`OTEL_TRACEPARENT_KEY`. If no `traceparent` is provided, it attempts to create one.
|
|
86
113
|
|
|
114
|
+
:param metadata: The metadata dictionary to inject the `traceparent` into.
|
|
115
|
+
:type metadata: dict[str, str]
|
|
116
|
+
:param traceparent: The `traceparent` string to inject. If None, attempts to use
|
|
117
|
+
the current span.
|
|
118
|
+
:type traceparent: str | None, optional
|
|
119
|
+
:returns: A new metadata dictionary containing the original metadata plus
|
|
120
|
+
the injected `traceparent`, if one was available or could be created.
|
|
121
|
+
:rtype: dict[str, str]
|
|
122
|
+
|
|
123
|
+
:Example:
|
|
124
|
+
|
|
125
|
+
>>> metadata = {"key": "value"}
|
|
126
|
+
>>> new_metadata = inject_traceparent(metadata, "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01")
|
|
127
|
+
>>> print(new_metadata)
|
|
128
|
+
{"key": "value", "traceparent": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"}
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
if not traceparent:
|
|
132
|
+
traceparent = create_traceparent()
|
|
133
|
+
|
|
134
|
+
if not traceparent:
|
|
87
135
|
return metadata
|
|
88
136
|
|
|
137
|
+
return {
|
|
138
|
+
**metadata,
|
|
139
|
+
OTEL_TRACEPARENT_KEY: traceparent,
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class HatchetInstrumentor(BaseInstrumentor): # type: ignore[misc]
|
|
144
|
+
def __init__(
|
|
145
|
+
self,
|
|
146
|
+
tracer_provider: TracerProvider | None = None,
|
|
147
|
+
meter_provider: MeterProvider | None = None,
|
|
148
|
+
):
|
|
149
|
+
"""
|
|
150
|
+
Hatchet OpenTelemetry instrumentor.
|
|
151
|
+
|
|
152
|
+
The instrumentor provides an OpenTelemetry integration for Hatchet by setting up
|
|
153
|
+
tracing and metrics collection.
|
|
154
|
+
|
|
155
|
+
:param tracer_provider: TracerProvider | None: The OpenTelemetry TracerProvider to use.
|
|
156
|
+
If not provided, the global tracer provider will be used.
|
|
157
|
+
:param meter_provider: MeterProvider | None: The OpenTelemetry MeterProvider to use.
|
|
158
|
+
If not provided, a no-op meter provider will be used.
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
self.tracer_provider = tracer_provider or get_tracer_provider()
|
|
162
|
+
self.meter_provider = meter_provider or NoOpMeterProvider()
|
|
163
|
+
|
|
164
|
+
super().__init__()
|
|
165
|
+
|
|
89
166
|
def instrumentation_dependencies(self) -> Collection[str]:
|
|
90
167
|
return tuple()
|
|
91
168
|
|
|
@@ -129,7 +206,7 @@ class HatchetInstrumentor(BaseInstrumentor): # type: ignore[misc]
|
|
|
129
206
|
|
|
130
207
|
wrap_function_wrapper(
|
|
131
208
|
hatchet_sdk,
|
|
132
|
-
"clients.admin.
|
|
209
|
+
"clients.admin.AdminClient.aio_run_workflow",
|
|
133
210
|
self._wrap_async_run_workflow,
|
|
134
211
|
)
|
|
135
212
|
|
|
@@ -141,7 +218,7 @@ class HatchetInstrumentor(BaseInstrumentor): # type: ignore[misc]
|
|
|
141
218
|
|
|
142
219
|
wrap_function_wrapper(
|
|
143
220
|
hatchet_sdk,
|
|
144
|
-
"clients.admin.
|
|
221
|
+
"clients.admin.AdminClient.aio_run_workflows",
|
|
145
222
|
self._wrap_async_run_workflows,
|
|
146
223
|
)
|
|
147
224
|
|
|
@@ -154,7 +231,7 @@ class HatchetInstrumentor(BaseInstrumentor): # type: ignore[misc]
|
|
|
154
231
|
kwargs: Any,
|
|
155
232
|
) -> Exception | None:
|
|
156
233
|
action = args[0]
|
|
157
|
-
traceparent =
|
|
234
|
+
traceparent = parse_carrier_from_metadata(action.additional_metadata)
|
|
158
235
|
|
|
159
236
|
with self._tracer.start_as_current_span(
|
|
160
237
|
"hatchet.start_step_run",
|
|
@@ -318,6 +395,6 @@ class HatchetInstrumentor(BaseInstrumentor): # type: ignore[misc]
|
|
|
318
395
|
unwrap(hatchet_sdk, "clients.events.EventClient.push")
|
|
319
396
|
unwrap(hatchet_sdk, "clients.events.EventClient.bulk_push")
|
|
320
397
|
unwrap(hatchet_sdk, "clients.admin.AdminClient.run_workflow")
|
|
321
|
-
unwrap(hatchet_sdk, "clients.admin.
|
|
398
|
+
unwrap(hatchet_sdk, "clients.admin.AdminClient.aio_run_workflow")
|
|
322
399
|
unwrap(hatchet_sdk, "clients.admin.AdminClient.run_workflows")
|
|
323
|
-
unwrap(hatchet_sdk, "clients.admin.
|
|
400
|
+
unwrap(hatchet_sdk, "clients.admin.AdminClient.aio_run_workflows")
|