prefect-client 3.9.1.dev7__tar.gz → 3.9.2.dev1__tar.gz
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.
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/PKG-INFO +3 -3
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/README.md +2 -2
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/AGENTS.md +1 -1
- prefect_client-3.9.2.dev1/src/prefect/_build_info.py +5 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/concurrency/AGENTS.md +1 -1
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/concurrency/_leases.py +64 -8
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/deployments/runner.py +4 -4
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/flow_engine.py +8 -2
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/flow_runs.py +14 -1
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/flows.py +5 -5
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_flow_run_executor.py +42 -16
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/deployments.py +8 -2
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/flow_runs.py +18 -8
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/work_queues.py +19 -5
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/workers.py +52 -8
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/types/_datetime.py +4 -1
- prefect_client-3.9.1.dev7/src/prefect/_build_info.py +0 -5
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/.gitignore +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/LICENSE +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/hatch_build.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/pyproject.toml +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/.prefectignore +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/__main__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_experimental/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_experimental/_launchers.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_experimental/bundles/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_experimental/bundles/execute.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_experimental/plugins/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_experimental/plugins/apply.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_experimental/plugins/diagnostics.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_experimental/plugins/manager.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_experimental/plugins/spec.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_experimental/sla/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_experimental/sla/client.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_experimental/sla/objects.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_flow_run_suspension.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/_logging.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/_observation_delivery.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/analytics/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/analytics/ci_detection.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/analytics/client.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/analytics/device_id.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/analytics/emit.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/analytics/enabled.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/analytics/events.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/analytics/milestones.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/analytics/notice.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/analytics/service.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/ast_utils.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/attempt_control.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/buildx.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/compatibility/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/compatibility/async_dispatch.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/compatibility/backports.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/compatibility/blocks.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/compatibility/deprecated.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/compatibility/deprecated_paths.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/compatibility/migration.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/compatibility/starlette.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/concurrency/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/concurrency/api.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/concurrency/calls.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/concurrency/cancellation.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/concurrency/event_loop.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/concurrency/inspection.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/concurrency/primitives.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/concurrency/services.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/concurrency/threads.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/concurrency/waiters.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/control_listener.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/deprecated.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/engine.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/git.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/infrastructure_exit_codes.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/installation.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/integrations.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/launchers.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/lazy.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/metrics.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/observability.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/observers.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/plugins/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/plugins/apply.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/plugins/collections.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/plugins/diagnostics.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/plugins/manager.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/plugins/spec.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/plugins/startup.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/pydantic/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/pydantic/schemas.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/pydantic/v1_schema.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/pydantic/v2_schema.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/pydantic/validated_func.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/pytz.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/result_records.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/retries.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/schema.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/schemas/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/schemas/_registry.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/schemas/bases.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/schemas/fields.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/schemas/serializers.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/schemas/validators.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/send_entrypoint_logs.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/server_maintenance.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/states.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/testing.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/urls.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/uuid7.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/version_checking.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/versioning.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/waiters.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_internal/websockets.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_sdk/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_sdk/fetcher.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_sdk/generator.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_sdk/models.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_sdk/naming.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_sdk/renderer.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_sdk/schema_converter.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_sdk/templates/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_sdk/templates/sdk.py.jinja +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_sdk/types.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_sdk/unions.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_vendor/croniter/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/_vendor/croniter/croniter.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/agent.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/analytics/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/artifacts.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/assets/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/assets/core.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/assets/materialize.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/automations.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/blocks/AGENTS.md +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/blocks/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/blocks/abstract.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/blocks/core.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/blocks/fields.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/blocks/notifications.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/blocks/redis.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/blocks/system.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/blocks/webhook.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/bundles/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/bundles/_file_collector.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/bundles/_ignore_filter.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/bundles/_path_resolver.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/bundles/_zip_builder.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/bundles/_zip_extractor.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/bundles/execute.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/cache_policies.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/AGENTS.md +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/attribution.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/base.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/cloud.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/collections.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/constants.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_artifacts/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_artifacts/client.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_automations/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_automations/client.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_blocks_documents/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_blocks_documents/client.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_blocks_schemas/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_blocks_schemas/client.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_blocks_types/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_blocks_types/client.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_concurrency_limits/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_concurrency_limits/client.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_deployments/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_deployments/client.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_events/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_events/client.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_flow_runs/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_flow_runs/client.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_flows/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_flows/client.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_logs/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_logs/client.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_variables/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_variables/client.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_work_pools/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/_work_pools/client.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/base.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/orchestration/routes.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/schemas/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/schemas/actions.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/schemas/events.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/schemas/filters.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/schemas/objects.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/schemas/responses.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/schemas/schedules.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/schemas/sorting.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/schemas/worker_channel.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/subscriptions.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/types/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/types/flexible_schedule_list.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/client/utilities.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/concurrency/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/concurrency/_asyncio.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/concurrency/_events.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/concurrency/_sync.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/concurrency/asyncio.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/concurrency/context.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/concurrency/services.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/concurrency/sync.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/concurrency/v1/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/concurrency/v1/_asyncio.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/concurrency/v1/_events.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/concurrency/v1/asyncio.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/concurrency/v1/context.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/concurrency/v1/services.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/concurrency/v1/sync.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/context.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/deployments/AGENTS.md +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/deployments/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/deployments/base.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/deployments/deployments.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/deployments/flow_runs.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/deployments/schedules.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/deployments/steps/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/deployments/steps/core.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/deployments/steps/pull.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/deployments/steps/utility.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/docker/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/docker/_buildx.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/docker/docker_image.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/engine.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/events/AGENTS.md +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/events/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/events/actions.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/events/clients.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/events/filters.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/events/related.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/events/schemas/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/events/schemas/automations.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/events/schemas/deployment_triggers.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/events/schemas/events.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/events/schemas/labelling.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/events/subscribers.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/events/utilities.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/events/worker.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/exceptions.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/filesystems.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/futures.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/infrastructure/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/infrastructure/base.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/infrastructure/provisioners/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/infrastructure/provisioners/cloud_run.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/infrastructure/provisioners/coiled.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/infrastructure/provisioners/container_instance.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/infrastructure/provisioners/ecs.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/infrastructure/provisioners/modal.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/input/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/input/actions.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/input/run_input.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/locking/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/locking/_filelock.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/locking/filesystem.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/locking/memory.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/locking/protocol.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/logging/AGENTS.md +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/logging/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/logging/clients.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/logging/configuration.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/logging/filters.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/logging/formatters.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/logging/handlers.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/logging/highlighters.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/logging/loggers.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/logging/logging.yml +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/main.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/plugins.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/py.typed +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/results.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/AGENTS.md +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_cancel_finalizer.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_cancellation_manager.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_control_channel.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_deployment_registry.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_event_emitter.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_flow_resolver.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_hook_runner.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_limit_manager.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_process_manager.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_scheduled_run_poller.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_starter_bundle.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_starter_direct.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_starter_engine.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_state_proposer.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_uv_command.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_workspace_hook_runner.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_workspace_resolver.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_workspace_runtime.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_workspace_runtime_bootstrap.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_workspace_starter.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_workspace_supervisor.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/runner.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/server.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/storage.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runtime/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runtime/deployment.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runtime/flow_run.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runtime/task_run.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/schedules.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/serializers.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/_ui_static.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/admin.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/artifacts.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/automations.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/background_workers.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/block_capabilities.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/block_documents.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/block_schemas.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/block_types.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/clients.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/collections.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/collections_data/views/aggregate-worker-metadata.json +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/concurrency_limits.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/concurrency_limits_v2.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/csrf_token.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/dependencies.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/events.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/flow_run_states.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/flows.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/logs.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/middleware.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/observed_states.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/root.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/run_history.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/saved_searches.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/server.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/static/prefect-logo-mark-gradient.png +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/task_run_states.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/task_runs.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/task_workers.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/templates.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/ui/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/ui/flow_runs.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/ui/flows.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/ui/schemas.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/ui/task_runs.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/validation.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/variables.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/AGENTS.md +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/_types.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/base.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/constants.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/context.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/legacy.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/_defaults.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/api.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/cli.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/client.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/cloud.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/deployments.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/events.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/experiments.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/flows.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/internal.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/logging.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/plugins.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/results.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/root.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/runner.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/server/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/server/api.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/server/concurrency.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/server/database.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/server/deployments.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/server/docket.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/server/ephemeral.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/server/events.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/server/flow_run_graph.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/server/logs.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/server/root.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/server/services.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/server/tasks.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/server/ui.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/server/worker_channel.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/tasks.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/telemetry.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/testing.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/models/worker.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/profiles.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/profiles.toml +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/settings/sources.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/states.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/task_engine.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/task_runners.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/task_runs.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/task_worker.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/tasks.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/telemetry/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/telemetry/run_telemetry.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/transactions.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/types/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/types/_concurrency.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/types/_datetime_deprecations.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/types/entrypoint.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/types/names.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/AGENTS.md +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/annotations.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/asyncutils/AGENTS.md +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/asyncutils/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/callables/AGENTS.md +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/callables/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/collections.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/compat.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/context.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/dispatch.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/dockerutils.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/engine/AGENTS.md +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/engine/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/filesystem/AGENTS.md +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/filesystem/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/generics.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/hashing.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/importtools.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/math.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/names.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/processutils/AGENTS.md +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/processutils/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/pydantic.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/render_swagger.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/schema_tools/AGENTS.md +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/schema_tools/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/schema_tools/hydration.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/schema_tools/validation.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/services.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/slugify.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/templating/AGENTS.md +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/templating/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/text.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/timeout.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/urls.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/utilities/visualization.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/variables.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/workers/AGENTS.md +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/workers/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/workers/_cleanup.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/workers/_cleanup_handlers.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/workers/_worker_channel/__init__.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/workers/_worker_channel/_protocol.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/workers/_worker_channel/_state.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/workers/_worker_channel/_sync.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/workers/_worker_channel/_transport.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/workers/base.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/workers/block.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/workers/cloud.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/workers/process.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/workers/server.py +0 -0
- {prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/workers/utilities.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: prefect-client
|
|
3
|
-
Version: 3.9.
|
|
3
|
+
Version: 3.9.2.dev1
|
|
4
4
|
Summary: Workflow orchestration and management.
|
|
5
5
|
Project-URL: Changelog, https://github.com/PrefectHQ/prefect/releases
|
|
6
6
|
Project-URL: Documentation, https://www.prefect.io/docs
|
|
@@ -163,7 +163,7 @@ describing the functionality you are interested in using and we will do our best
|
|
|
163
163
|
## Next steps
|
|
164
164
|
|
|
165
165
|
There's lots more you can do to orchestrate and observe your workflows with Prefect!
|
|
166
|
-
Start with our [friendly tutorial](https://www.prefect.io/docs/
|
|
166
|
+
Start with our [friendly tutorial](https://www.prefect.io/docs/v3/get-started/quickstart) or explore the [core concepts of Prefect workflows](https://www.prefect.io/docs/concepts/).
|
|
167
167
|
|
|
168
168
|
## Join the community
|
|
169
169
|
|
|
@@ -173,6 +173,6 @@ All community forums, including code contributions, issue discussions, and Slack
|
|
|
173
173
|
|
|
174
174
|
## Contribute
|
|
175
175
|
|
|
176
|
-
See our [documentation on contributing to Prefect](https://www.prefect.io/docs/
|
|
176
|
+
See our [documentation on contributing to Prefect](https://www.prefect.io/docs/contribute).
|
|
177
177
|
|
|
178
178
|
Thanks for being part of the mission to build a new kind of workflow system and, of course, **happy engineering!**
|
|
@@ -94,7 +94,7 @@ describing the functionality you are interested in using and we will do our best
|
|
|
94
94
|
## Next steps
|
|
95
95
|
|
|
96
96
|
There's lots more you can do to orchestrate and observe your workflows with Prefect!
|
|
97
|
-
Start with our [friendly tutorial](https://www.prefect.io/docs/
|
|
97
|
+
Start with our [friendly tutorial](https://www.prefect.io/docs/v3/get-started/quickstart) or explore the [core concepts of Prefect workflows](https://www.prefect.io/docs/concepts/).
|
|
98
98
|
|
|
99
99
|
## Join the community
|
|
100
100
|
|
|
@@ -104,6 +104,6 @@ All community forums, including code contributions, issue discussions, and Slack
|
|
|
104
104
|
|
|
105
105
|
## Contribute
|
|
106
106
|
|
|
107
|
-
See our [documentation on contributing to Prefect](https://www.prefect.io/docs/
|
|
107
|
+
See our [documentation on contributing to Prefect](https://www.prefect.io/docs/contribute).
|
|
108
108
|
|
|
109
109
|
Thanks for being part of the mission to build a new kind of workflow system and, of course, **happy engineering!**
|
|
@@ -29,7 +29,7 @@ Runtime flow/task parameter values must come from `utilities.callables.get_call_
|
|
|
29
29
|
- **Sync and async must stay in sync.** Both `flow_engine.py` and `task_engine.py` have sync and async paths. Any behavior change must be applied to both.
|
|
30
30
|
- **Event and log WebSocket subscribers are parallel implementations.** `events/clients.py::PrefectEventSubscriber` and `logging/clients.py::PrefectLogsSubscriber` duplicate the same reconnect/backoff/dedup logic, including the `reconnect_on_clean_close` option (used by `events/subscribers.py::FlowRunSubscriber` so a clean disconnect doesn't hide a terminal event). Mirror any reconnection-behavior change across both.
|
|
31
31
|
- **Flow run observers own their stream recovery.** `_internal/observers.py` observers create subscribers with `reconnection_attempts=0` and delegate polling fallback, reconnect backoff, and setup deadlines to `_internal/_observation_delivery.py::ObservationDelivery`. Subscribers close any socket left by a failed or cancelled `__aenter__`, since callers never exit a context that failed to enter.
|
|
32
|
-
- **Use `whenever` compat helpers for all datetime conversions on Python 3.13+.** `prefect-client` depends on `whenever` only on Python 3.13+, so modules it ships must keep `whenever` imports behind `sys.version_info >= (3, 13)`; only
|
|
32
|
+
- **Use `whenever` compat helpers for all datetime conversions on Python 3.13+.** `prefect-client` depends on `whenever` only on Python 3.13+, so modules it ships must keep `whenever` imports behind `sys.version_info >= (3, 13)`; only code that the client build strips may import it unconditionally (see the repo-root `client/AGENTS.md`). `types/_datetime.py` provides `now()`, `_whenever_to_stdlib()`, `_whenever_zdt_from_py()`, and `_whenever_pdt_from_py()` to abstract over API differences across supported whenever releases. Version-specific code is guarded by feature-detection flags (`_WHENEVER_NEW_API` for ≥ 0.10.0, `_SYSTEM_TZ` for ≥ 0.11), not version checks. These flags are only probed on Python 3.13+ (`_WHENEVER_NEW_API` is `False` and `_SYSTEM_TZ` is undefined on 3.11/3.12), so a helper that server-only code calls on every Python must feature-detect on the `whenever` class itself. Never call `DateTime.now()` or `pendulum.now()` directly — use `now()` from `types/_datetime.py` instead. Avoid no-argument `datetime.datetime.now()` because it returns a tz-naive datetime that raises `TypeError` when compared to the tz-aware datetimes produced by `now()`. Explicitly timezone-aware stdlib calls such as `datetime.now(ZoneInfo("UTC"))` are allowed when needed to preserve timezone information. Never call `ZonedDateTime.from_py_datetime()`, `PlainDateTime.from_py_datetime()`, or `.py_datetime()` directly — use the helpers instead. Likewise avoid `.assume_system_tz()`/`.to_system_tz()` (deprecated in 0.11; the warning fails tests under `filterwarnings = error`) — use `in_local_tz()` — and direct `DateTimeDelta` imports (removed in 0.11) — use the `Interval` alias. Violations will silently break on whichever whenever version the helpers weren't written for.
|
|
33
33
|
- **Call Pendulum-only members via `types/_datetime.py::_pendulum_call` on Python 3.11/3.12.** Prefect's `DateTime`/`Date`/`Duration` wrap Pendulum-only members (and some shared stdlib methods like `replace`) with user-facing deprecation warnings; `_pendulum_call` bypasses them so users only see warnings for their own calls. `pyproject.toml` ignores these warnings in pytest, so direct calls from Prefect code pass tests silently unless covered by the guards in `tests/test_datetime.py`.
|
|
34
34
|
- **Flow and task engines advance state differently.** The flow engine makes blocking API calls to the server to propose and advance states. The task engine emits `prefect.task_run.*` events (delivered via WebSockets) but advances state locally through `set_state` calls with polling/backoff — do not assume the two engines work the same way.
|
|
35
35
|
- **Flow state transitions go through the server.** The flow engine proposes states to the server, which accepts or rejects them via orchestration rules. The task engine, by contrast, manages state transitions locally via `set_state` and emits `prefect.task_run.*` events — it does not propose states to the server.
|
|
@@ -18,7 +18,7 @@ Does NOT define concurrency limits (server-side in `server/`). Does NOT handle t
|
|
|
18
18
|
|
|
19
19
|
**`raise_on_lease_renewal_failure` (public parameter):** Controls lease renewal failure behavior independently from `strict`. When `None` (default), falls back to the value of `strict` for backward compatibility. Set to `False` to let long-running tasks continue even if a transient renewal error occurs; set to `True` to terminate immediately on renewal failure regardless of `strict`. This means `strict=True, raise_on_lease_renewal_failure=False` gives strict slot acquisition but non-fatal renewal failures, and vice versa.
|
|
20
20
|
|
|
21
|
-
**Lease renewal:** `_leases.py` starts a daemon thread that renews immediately on entry, then waits for 75% of `lease_duration` between renewals. The renewal thread uses the standard `get_client(sync_client=True)` path and retries each renewal up to 3 times with exponential backoff. If all attempts fail, a shared failure handler either cancels execution with the existing sync/async cancel scope or logs a warning, depending on `raise_on_lease_renewal_failure`.
|
|
21
|
+
**Lease renewal:** `_leases.py` starts a daemon thread that renews immediately on entry, then waits for 75% of `lease_duration` between renewals. The renewal thread uses the standard `get_client(sync_client=True)` path and retries each renewal up to 3 times with exponential backoff. If all attempts fail, a shared failure handler either cancels execution with the existing sync/async cancel scope or logs a warning, depending on `raise_on_lease_renewal_failure`. Exception: when a `flow_run_id` is given and renewal fails with `410 Gone`, the thread reads the flow run and stops without cancelling if its server state is final, because the terminal transition releases the lease before the engine receives the proposal response.
|
|
22
22
|
|
|
23
23
|
**Sync/async lockstep invariant:** `asyncio.py`/`sync.py` and `_asyncio.py`/`_sync.py` are parallel implementations. Any behavior change to one must be mirrored in the other.
|
|
24
24
|
|
|
@@ -4,6 +4,9 @@ from contextlib import asynccontextmanager, contextmanager
|
|
|
4
4
|
from typing import TYPE_CHECKING, AsyncGenerator, Generator
|
|
5
5
|
from uuid import UUID
|
|
6
6
|
|
|
7
|
+
import httpx
|
|
8
|
+
|
|
9
|
+
from prefect._internal.compatibility.starlette import status
|
|
7
10
|
from prefect._internal.concurrency.cancellation import (
|
|
8
11
|
AsyncCancelScope,
|
|
9
12
|
WatcherThreadCancelScope,
|
|
@@ -90,6 +93,45 @@ def _lease_renewal_loop(
|
|
|
90
93
|
stop_event.wait(lease_duration * _RENEWAL_FRACTION)
|
|
91
94
|
|
|
92
95
|
|
|
96
|
+
def _lease_released_by_final_flow_run(
|
|
97
|
+
exc: BaseException, lease_id: UUID, flow_run_id: UUID | None
|
|
98
|
+
) -> bool:
|
|
99
|
+
"""
|
|
100
|
+
Check whether a lease renewal failure is explained by the flow run having
|
|
101
|
+
reached a final state on the server, which releases the lease before the
|
|
102
|
+
engine has received the response to its terminal state proposal.
|
|
103
|
+
"""
|
|
104
|
+
if flow_run_id is None or not (
|
|
105
|
+
isinstance(exc, httpx.HTTPStatusError)
|
|
106
|
+
and exc.response.status_code == status.HTTP_410_GONE
|
|
107
|
+
):
|
|
108
|
+
return False
|
|
109
|
+
|
|
110
|
+
logger = get_logger("concurrency")
|
|
111
|
+
try:
|
|
112
|
+
with get_client(sync_client=True) as client:
|
|
113
|
+
flow_run = client.read_flow_run(flow_run_id)
|
|
114
|
+
except Exception:
|
|
115
|
+
logger.debug(
|
|
116
|
+
"Failed to read flow run %s after its concurrency lease was not found",
|
|
117
|
+
flow_run_id,
|
|
118
|
+
exc_info=True,
|
|
119
|
+
)
|
|
120
|
+
return False
|
|
121
|
+
|
|
122
|
+
if flow_run.state is None or not flow_run.state.is_final():
|
|
123
|
+
return False
|
|
124
|
+
|
|
125
|
+
logger.debug(
|
|
126
|
+
"Concurrency lease %s was released because flow run %s reached final "
|
|
127
|
+
"state %s; stopping lease renewal",
|
|
128
|
+
lease_id,
|
|
129
|
+
flow_run_id,
|
|
130
|
+
flow_run.state.type.value,
|
|
131
|
+
)
|
|
132
|
+
return True
|
|
133
|
+
|
|
134
|
+
|
|
93
135
|
def _handle_lease_renewal_failure(
|
|
94
136
|
exc: BaseException,
|
|
95
137
|
lease_id: UUID,
|
|
@@ -139,6 +181,7 @@ def _start_lease_renewal_thread(
|
|
|
139
181
|
raise_on_lease_renewal_failure: bool,
|
|
140
182
|
suppress_warnings: bool,
|
|
141
183
|
cancel_scope: AsyncCancelScope | WatcherThreadCancelScope,
|
|
184
|
+
flow_run_id: UUID | None = None,
|
|
142
185
|
) -> tuple[threading.Event, threading.Thread]:
|
|
143
186
|
stop_event = threading.Event()
|
|
144
187
|
renewal_ctx = contextvars.copy_context()
|
|
@@ -152,14 +195,17 @@ def _start_lease_renewal_thread(
|
|
|
152
195
|
try:
|
|
153
196
|
_lease_renewal_loop(lease_id, lease_duration, stop_event)
|
|
154
197
|
except Exception as exc:
|
|
155
|
-
if
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
198
|
+
if stop_event.is_set() or _lease_released_by_final_flow_run(
|
|
199
|
+
exc, lease_id, flow_run_id
|
|
200
|
+
):
|
|
201
|
+
return
|
|
202
|
+
_handle_lease_renewal_failure(
|
|
203
|
+
exc,
|
|
204
|
+
lease_id,
|
|
205
|
+
raise_on_lease_renewal_failure,
|
|
206
|
+
suppress_warnings,
|
|
207
|
+
cancel_scope,
|
|
208
|
+
)
|
|
163
209
|
|
|
164
210
|
def renewal_loop() -> None:
|
|
165
211
|
renewal_ctx.run(_run_with_failure_handler)
|
|
@@ -179,6 +225,7 @@ def maintain_concurrency_lease(
|
|
|
179
225
|
lease_duration: float,
|
|
180
226
|
raise_on_lease_renewal_failure: bool = False,
|
|
181
227
|
suppress_warnings: bool = False,
|
|
228
|
+
flow_run_id: UUID | None = None,
|
|
182
229
|
) -> Generator[None, None, None]:
|
|
183
230
|
"""
|
|
184
231
|
Maintain a concurrency lease for the given lease ID.
|
|
@@ -187,6 +234,9 @@ def maintain_concurrency_lease(
|
|
|
187
234
|
lease_id: The ID of the lease to maintain.
|
|
188
235
|
lease_duration: The duration of the lease in seconds.
|
|
189
236
|
raise_on_lease_renewal_failure: A boolean specifying whether to raise an error if the lease renewal fails.
|
|
237
|
+
flow_run_id: The ID of the flow run holding the lease. When the lease is
|
|
238
|
+
not found and this flow run is final on the server, the lease was
|
|
239
|
+
released by the terminal transition and execution is not terminated.
|
|
190
240
|
"""
|
|
191
241
|
with WatcherThreadCancelScope() as cancel_scope:
|
|
192
242
|
stop_event: threading.Event | None = None
|
|
@@ -198,6 +248,7 @@ def maintain_concurrency_lease(
|
|
|
198
248
|
raise_on_lease_renewal_failure,
|
|
199
249
|
suppress_warnings,
|
|
200
250
|
cancel_scope,
|
|
251
|
+
flow_run_id,
|
|
201
252
|
)
|
|
202
253
|
yield
|
|
203
254
|
finally:
|
|
@@ -213,6 +264,7 @@ async def amaintain_concurrency_lease(
|
|
|
213
264
|
lease_duration: float,
|
|
214
265
|
raise_on_lease_renewal_failure: bool = False,
|
|
215
266
|
suppress_warnings: bool = False,
|
|
267
|
+
flow_run_id: UUID | None = None,
|
|
216
268
|
) -> AsyncGenerator[None, None]:
|
|
217
269
|
"""
|
|
218
270
|
Maintain a concurrency lease for the given lease ID.
|
|
@@ -221,6 +273,9 @@ async def amaintain_concurrency_lease(
|
|
|
221
273
|
lease_id: The ID of the lease to maintain.
|
|
222
274
|
lease_duration: The duration of the lease in seconds.
|
|
223
275
|
raise_on_lease_renewal_failure: A boolean specifying whether to raise an error if the lease renewal fails.
|
|
276
|
+
flow_run_id: The ID of the flow run holding the lease. When the lease is
|
|
277
|
+
not found and this flow run is final on the server, the lease was
|
|
278
|
+
released by the terminal transition and execution is not terminated.
|
|
224
279
|
"""
|
|
225
280
|
with AsyncCancelScope() as cancel_scope:
|
|
226
281
|
stop_event: threading.Event | None = None
|
|
@@ -231,6 +286,7 @@ async def amaintain_concurrency_lease(
|
|
|
231
286
|
raise_on_lease_renewal_failure,
|
|
232
287
|
suppress_warnings,
|
|
233
288
|
cancel_scope,
|
|
289
|
+
flow_run_id,
|
|
234
290
|
)
|
|
235
291
|
yield
|
|
236
292
|
finally:
|
|
@@ -1671,14 +1671,14 @@ async def adeploy(
|
|
|
1671
1671
|
" or specify a remote storage location for the flow with `.from_source`."
|
|
1672
1672
|
" If you are attempting to deploy a flow to a local process work pool,"
|
|
1673
1673
|
" consider using `flow.serve` instead. See the documentation for more"
|
|
1674
|
-
" information: https://www.prefect.io/docs/
|
|
1674
|
+
" information: https://www.prefect.io/docs/v3/how-to-guides/deployment_infra/run-flows-in-local-processes"
|
|
1675
1675
|
)
|
|
1676
1676
|
elif work_pool.type == "process" and not ignore_warnings:
|
|
1677
1677
|
console.print(
|
|
1678
1678
|
"Looks like you're deploying to a process work pool. If you're creating a"
|
|
1679
1679
|
" deployment for local development, calling `.serve` on your flow is a great"
|
|
1680
1680
|
" way to get started. See the documentation for more information:"
|
|
1681
|
-
" https://www.prefect.io/docs/
|
|
1681
|
+
" https://www.prefect.io/docs/v3/how-to-guides/deployment_infra/run-flows-in-local-processes "
|
|
1682
1682
|
" Set `ignore_warnings=True` to suppress this message.",
|
|
1683
1683
|
style="yellow",
|
|
1684
1684
|
)
|
|
@@ -1912,14 +1912,14 @@ def deploy(
|
|
|
1912
1912
|
" or specify a remote storage location for the flow with `.from_source`."
|
|
1913
1913
|
" If you are attempting to deploy a flow to a local process work pool,"
|
|
1914
1914
|
" consider using `flow.serve` instead. See the documentation for more"
|
|
1915
|
-
" information: https://www.prefect.io/docs/
|
|
1915
|
+
" information: https://www.prefect.io/docs/v3/how-to-guides/deployment_infra/run-flows-in-local-processes"
|
|
1916
1916
|
)
|
|
1917
1917
|
elif work_pool.type == "process" and not ignore_warnings:
|
|
1918
1918
|
console.print(
|
|
1919
1919
|
"Looks like you're deploying to a process work pool. If you're creating a"
|
|
1920
1920
|
" deployment for local development, calling `.serve` on your flow is a great"
|
|
1921
1921
|
" way to get started. See the documentation for more information:"
|
|
1922
|
-
" https://www.prefect.io/docs/
|
|
1922
|
+
" https://www.prefect.io/docs/v3/how-to-guides/deployment_infra/run-flows-in-local-processes "
|
|
1923
1923
|
" Set `ignore_warnings=True` to suppress this message.",
|
|
1924
1924
|
style="yellow",
|
|
1925
1925
|
)
|
|
@@ -1137,7 +1137,10 @@ class FlowRunEngine(BaseFlowRunEngine[P, R]):
|
|
|
1137
1137
|
if lease_id := self.state.state_details.deployment_concurrency_lease_id:
|
|
1138
1138
|
stack.enter_context(
|
|
1139
1139
|
maintain_concurrency_lease(
|
|
1140
|
-
lease_id,
|
|
1140
|
+
lease_id,
|
|
1141
|
+
300,
|
|
1142
|
+
raise_on_lease_renewal_failure=True,
|
|
1143
|
+
flow_run_id=self.flow_run.id,
|
|
1141
1144
|
)
|
|
1142
1145
|
)
|
|
1143
1146
|
|
|
@@ -1865,7 +1868,10 @@ class AsyncFlowRunEngine(BaseFlowRunEngine[P, R]):
|
|
|
1865
1868
|
if lease_id := self.state.state_details.deployment_concurrency_lease_id:
|
|
1866
1869
|
await stack.enter_async_context(
|
|
1867
1870
|
amaintain_concurrency_lease(
|
|
1868
|
-
lease_id,
|
|
1871
|
+
lease_id,
|
|
1872
|
+
300,
|
|
1873
|
+
raise_on_lease_renewal_failure=True,
|
|
1874
|
+
flow_run_id=self.flow_run.id,
|
|
1869
1875
|
)
|
|
1870
1876
|
)
|
|
1871
1877
|
|
|
@@ -133,6 +133,7 @@ async def wait_for_flow_run(
|
|
|
133
133
|
)
|
|
134
134
|
|
|
135
135
|
with anyio.move_on_after(timeout):
|
|
136
|
+
received_final_event = False
|
|
136
137
|
async with get_events_subscriber(filter=event_filter) as subscriber:
|
|
137
138
|
flow_run = await client.read_flow_run(flow_run_id)
|
|
138
139
|
if flow_run.state and flow_run.state.is_final():
|
|
@@ -151,7 +152,19 @@ async def wait_for_flow_run(
|
|
|
151
152
|
logger.info(f"Flow run is in state {state.name!r}")
|
|
152
153
|
|
|
153
154
|
if state.is_final():
|
|
154
|
-
|
|
155
|
+
received_final_event = True
|
|
156
|
+
break
|
|
157
|
+
|
|
158
|
+
if received_final_event:
|
|
159
|
+
# A final state event can be delivered before the state change is
|
|
160
|
+
# visible to API reads, so read until the run reports a final state
|
|
161
|
+
poll_delay = 0.1
|
|
162
|
+
while True:
|
|
163
|
+
flow_run = await client.read_flow_run(flow_run_id)
|
|
164
|
+
if flow_run.state and flow_run.state.is_final():
|
|
165
|
+
return flow_run
|
|
166
|
+
await anyio.sleep(poll_delay)
|
|
167
|
+
poll_delay = min(poll_delay * 2, 5)
|
|
155
168
|
|
|
156
169
|
raise FlowRunWaitTimeout(
|
|
157
170
|
f"Flow run with ID {flow_run_id} exceeded watch timeout of {timeout} seconds"
|
|
@@ -706,11 +706,11 @@ class Flow(Generic[P, R]):
|
|
|
706
706
|
from fastapi.encoders import jsonable_encoder
|
|
707
707
|
|
|
708
708
|
serialized_parameters[key] = jsonable_encoder(value)
|
|
709
|
-
except
|
|
710
|
-
# `jsonable_encoder`
|
|
711
|
-
#
|
|
712
|
-
#
|
|
713
|
-
#
|
|
709
|
+
except Exception:
|
|
710
|
+
# `jsonable_encoder` can raise arbitrary errors for values it
|
|
711
|
+
# cannot encode (e.g. `RecursionError` for self-referential
|
|
712
|
+
# objects, or any error from `__reduce__` while deep-copying a
|
|
713
|
+
# dataclass). Fall back to the placeholder below.
|
|
714
714
|
logger.debug(
|
|
715
715
|
f"Parameter {key!r} for flow {self.name!r} is unserializable. "
|
|
716
716
|
f"Type {type(value).__name__!r} and will not be stored "
|
{prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/runner/_flow_run_executor.py
RENAMED
|
@@ -51,10 +51,16 @@ class ProcessStarter(Protocol):
|
|
|
51
51
|
|
|
52
52
|
@dataclass(frozen=True)
|
|
53
53
|
class FlowRunExecutionResult:
|
|
54
|
-
"""Process handle plus the infrastructure status for a completed attempt.
|
|
54
|
+
"""Process handle plus the infrastructure status for a completed attempt.
|
|
55
|
+
|
|
56
|
+
`crash_unreported` is `True` when the process exited non-zero or failed
|
|
57
|
+
after starting, and the runner could not record a final state for the flow
|
|
58
|
+
run in its place.
|
|
59
|
+
"""
|
|
55
60
|
|
|
56
61
|
handle: ProcessHandle
|
|
57
62
|
status_code: int | None
|
|
63
|
+
crash_unreported: bool = False
|
|
58
64
|
|
|
59
65
|
|
|
60
66
|
class FlowRunExecutor:
|
|
@@ -124,6 +130,7 @@ class FlowRunExecutor:
|
|
|
124
130
|
"""
|
|
125
131
|
handle: ProcessHandle | None = None
|
|
126
132
|
attempt_conclusion: AttemptConclusion | None = None
|
|
133
|
+
process_error: Exception | None = None
|
|
127
134
|
try:
|
|
128
135
|
# Step 1a: already-cancelling precheck (runs regardless of propose_submitting)
|
|
129
136
|
if self._flow_run.state and self._flow_run.state.is_cancelling():
|
|
@@ -165,16 +172,26 @@ class FlowRunExecutor:
|
|
|
165
172
|
handle = await self._start_process(task_status)
|
|
166
173
|
|
|
167
174
|
except Exception as exc:
|
|
175
|
+
# A failure after the process exited (e.g. its output stream broke)
|
|
176
|
+
# still leaves an exit to account for. A live process stays
|
|
177
|
+
# registered so the process manager can still stop it.
|
|
178
|
+
started_handle = self._process_manager.get(self._flow_run.id)
|
|
179
|
+
if started_handle is None or started_handle.returncode is None:
|
|
180
|
+
self._logger.exception(
|
|
181
|
+
"Flow run '%s' could not start: %s",
|
|
182
|
+
self._flow_run.id,
|
|
183
|
+
exc,
|
|
184
|
+
)
|
|
185
|
+
await self._state_proposer.propose_crashed(
|
|
186
|
+
self._flow_run,
|
|
187
|
+
message=f"Flow run could not start: {exc}",
|
|
188
|
+
)
|
|
189
|
+
return
|
|
168
190
|
self._logger.exception(
|
|
169
|
-
"Flow run '%s'
|
|
170
|
-
self._flow_run.id,
|
|
171
|
-
exc,
|
|
172
|
-
)
|
|
173
|
-
await self._state_proposer.propose_crashed(
|
|
174
|
-
self._flow_run,
|
|
175
|
-
message=f"Flow run could not start: {exc}",
|
|
191
|
+
"Flow run '%s' process failed: %s", self._flow_run.id, exc
|
|
176
192
|
)
|
|
177
|
-
|
|
193
|
+
handle = started_handle
|
|
194
|
+
process_error = exc
|
|
178
195
|
finally:
|
|
179
196
|
# Step 6: snapshot terminal evidence before process cleanup unregisters
|
|
180
197
|
# the attempt control session, then remove the process handle.
|
|
@@ -199,14 +216,23 @@ class FlowRunExecutor:
|
|
|
199
216
|
info.resolution,
|
|
200
217
|
extra={"flow_run_id": self._flow_run.id},
|
|
201
218
|
)
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
if crashed_state is not None:
|
|
207
|
-
await self._hook_runner.run_crashed_hooks(self._flow_run, crashed_state)
|
|
219
|
+
elif process_error is not None:
|
|
220
|
+
msg = f"Flow run process failed: {process_error}"
|
|
221
|
+
else:
|
|
222
|
+
return FlowRunExecutionResult(handle=handle, status_code=exit_code)
|
|
208
223
|
|
|
209
|
-
|
|
224
|
+
crashed_state = await self._state_proposer.propose_crashed(
|
|
225
|
+
self._flow_run, message=msg
|
|
226
|
+
)
|
|
227
|
+
# Step 8: run crashed hooks
|
|
228
|
+
if crashed_state is not None:
|
|
229
|
+
await self._hook_runner.run_crashed_hooks(self._flow_run, crashed_state)
|
|
230
|
+
|
|
231
|
+
return FlowRunExecutionResult(
|
|
232
|
+
handle=handle,
|
|
233
|
+
status_code=exit_code,
|
|
234
|
+
crash_unreported=crashed_state is None or not crashed_state.is_final(),
|
|
235
|
+
)
|
|
210
236
|
|
|
211
237
|
async def _start_process(
|
|
212
238
|
self,
|
{prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/deployments.py
RENAMED
|
@@ -20,7 +20,7 @@ from prefect.server.api.validation import (
|
|
|
20
20
|
validate_job_variables_for_deployment,
|
|
21
21
|
validate_job_variables_for_deployment_flow_run,
|
|
22
22
|
)
|
|
23
|
-
from prefect.server.api.workers import WorkerLookups
|
|
23
|
+
from prefect.server.api.workers import WorkerLookups, schedule_readiness_update
|
|
24
24
|
from prefect.server.database import PrefectDBInterface, provide_database_interface
|
|
25
25
|
from prefect.server.exceptions import MissingVariableError, ObjectNotFoundError
|
|
26
26
|
from prefect.server.models.deployments import mark_deployments_ready
|
|
@@ -656,10 +656,16 @@ async def get_scheduled_flow_runs_for_deployments(
|
|
|
656
656
|
for orm_flow_run in orm_flow_runs
|
|
657
657
|
]
|
|
658
658
|
|
|
659
|
+
becoming_ready = await models.deployments.has_not_ready_deployments(
|
|
660
|
+
session=session, deployment_ids=deployment_ids
|
|
661
|
+
)
|
|
662
|
+
|
|
659
663
|
sorted_deployment_ids = ",".join(str(d) for d in sorted(deployment_ids))
|
|
660
|
-
await
|
|
664
|
+
await schedule_readiness_update(
|
|
665
|
+
docket,
|
|
661
666
|
mark_deployments_ready,
|
|
662
667
|
key=f"mark_deployments_ready:deployments:{sorted_deployment_ids}",
|
|
668
|
+
becoming_ready=becoming_ready,
|
|
663
669
|
)(
|
|
664
670
|
deployment_ids=deployment_ids,
|
|
665
671
|
)
|
|
@@ -11,6 +11,7 @@ from urllib.parse import quote
|
|
|
11
11
|
from uuid import UUID
|
|
12
12
|
|
|
13
13
|
import orjson
|
|
14
|
+
import pydantic_core
|
|
14
15
|
import sqlalchemy as sa
|
|
15
16
|
from docket import Depends as DocketDepends
|
|
16
17
|
from docket import Docket, Retry
|
|
@@ -69,6 +70,21 @@ logger: "logging.Logger" = get_logger("server.api")
|
|
|
69
70
|
router: PrefectRouter = PrefectRouter(prefix="/flow_runs", tags=["Flow Runs"])
|
|
70
71
|
|
|
71
72
|
|
|
73
|
+
def _json_response(content: Any) -> Response:
|
|
74
|
+
"""
|
|
75
|
+
Serialize already JSON-compatible `content` into a JSON response.
|
|
76
|
+
|
|
77
|
+
orjson is much faster than the FastAPI encoder, but it rejects integers
|
|
78
|
+
outside of the 64-bit range. Flow run parameters are arbitrary user data, so
|
|
79
|
+
fall back to pydantic-core, which supports arbitrarily large integers.
|
|
80
|
+
"""
|
|
81
|
+
try:
|
|
82
|
+
body = orjson.dumps(content)
|
|
83
|
+
except TypeError:
|
|
84
|
+
body = pydantic_core.to_json(content)
|
|
85
|
+
return Response(content=body, media_type="application/json")
|
|
86
|
+
|
|
87
|
+
|
|
72
88
|
def _get_request_docket(request: Request) -> Docket | None:
|
|
73
89
|
return getattr(request.app.state, "docket", None)
|
|
74
90
|
|
|
@@ -621,10 +637,7 @@ async def read_flow_runs(
|
|
|
621
637
|
).model_dump(mode="json")
|
|
622
638
|
for fr in db_flow_runs
|
|
623
639
|
]
|
|
624
|
-
return
|
|
625
|
-
content=orjson.dumps(encoded),
|
|
626
|
-
media_type="application/json",
|
|
627
|
-
)
|
|
640
|
+
return _json_response(encoded)
|
|
628
641
|
|
|
629
642
|
|
|
630
643
|
@router.delete("/{id:uuid}", status_code=status.HTTP_204_NO_CONTENT)
|
|
@@ -1047,10 +1060,7 @@ async def paginate_flow_runs(
|
|
|
1047
1060
|
page=page,
|
|
1048
1061
|
).model_dump(mode="json")
|
|
1049
1062
|
|
|
1050
|
-
return
|
|
1051
|
-
content=orjson.dumps(response),
|
|
1052
|
-
media_type="application/json",
|
|
1053
|
-
)
|
|
1063
|
+
return _json_response(response)
|
|
1054
1064
|
|
|
1055
1065
|
|
|
1056
1066
|
FLOW_RUN_LOGS_DOWNLOAD_PAGE_LIMIT = 1000
|
{prefect_client-3.9.1.dev7 → prefect_client-3.9.2.dev1}/src/prefect/server/api/work_queues.py
RENAMED
|
@@ -18,6 +18,7 @@ from sqlalchemy.exc import IntegrityError
|
|
|
18
18
|
import prefect.server.api.dependencies as dependencies
|
|
19
19
|
import prefect.server.models as models
|
|
20
20
|
import prefect.server.schemas as schemas
|
|
21
|
+
from prefect.server.api.workers import schedule_readiness_update
|
|
21
22
|
from prefect.server.database import (
|
|
22
23
|
PrefectDBInterface,
|
|
23
24
|
provide_database_interface,
|
|
@@ -189,19 +190,32 @@ async def read_work_queue_runs(
|
|
|
189
190
|
if x_prefect_ui:
|
|
190
191
|
return flow_runs
|
|
191
192
|
|
|
192
|
-
|
|
193
|
+
work_queue_becoming_ready = work_queue.status == WorkQueueStatus.NOT_READY
|
|
194
|
+
if work_queue_becoming_ready:
|
|
195
|
+
deployments_becoming_ready = True
|
|
196
|
+
else:
|
|
197
|
+
async with db.session_context() as session:
|
|
198
|
+
deployments_becoming_ready = (
|
|
199
|
+
await models.deployments.has_not_ready_deployments(
|
|
200
|
+
session=session, work_queue_ids=[work_queue_id]
|
|
201
|
+
)
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
await schedule_readiness_update(
|
|
205
|
+
docket,
|
|
193
206
|
mark_work_queues_ready,
|
|
194
207
|
key=f"mark_work_queues_ready:{work_queue_id}",
|
|
208
|
+
becoming_ready=work_queue_becoming_ready,
|
|
195
209
|
)(
|
|
196
210
|
polled_work_queue_ids=[work_queue_id],
|
|
197
|
-
ready_work_queue_ids=
|
|
198
|
-
[work_queue_id] if work_queue.status == WorkQueueStatus.NOT_READY else []
|
|
199
|
-
),
|
|
211
|
+
ready_work_queue_ids=[work_queue_id] if work_queue_becoming_ready else [],
|
|
200
212
|
)
|
|
201
213
|
|
|
202
|
-
await
|
|
214
|
+
await schedule_readiness_update(
|
|
215
|
+
docket,
|
|
203
216
|
mark_deployments_ready,
|
|
204
217
|
key=f"mark_deployments_ready:work_queue:{work_queue_id}",
|
|
218
|
+
becoming_ready=deployments_becoming_ready,
|
|
205
219
|
)(
|
|
206
220
|
work_queue_ids=[work_queue_id],
|
|
207
221
|
)
|
|
@@ -4,10 +4,11 @@ Routes for interacting with work queue objects.
|
|
|
4
4
|
|
|
5
5
|
from dataclasses import dataclass
|
|
6
6
|
from logging import Logger
|
|
7
|
-
from typing import TYPE_CHECKING, Any, List, Optional
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Awaitable, Callable, List, Optional, ParamSpec
|
|
8
8
|
from uuid import UUID
|
|
9
9
|
|
|
10
10
|
import sqlalchemy as sa
|
|
11
|
+
from docket import Docket, Execution
|
|
11
12
|
from fastapi import (
|
|
12
13
|
Body,
|
|
13
14
|
Depends,
|
|
@@ -67,6 +68,30 @@ router: PrefectRouter = PrefectRouter(
|
|
|
67
68
|
)
|
|
68
69
|
logger: Logger = get_logger("prefect.server.api.workers")
|
|
69
70
|
|
|
71
|
+
P = ParamSpec("P")
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def schedule_readiness_update(
|
|
75
|
+
docket: Docket,
|
|
76
|
+
function: Callable[P, Awaitable[None]],
|
|
77
|
+
key: str,
|
|
78
|
+
*,
|
|
79
|
+
becoming_ready: bool,
|
|
80
|
+
) -> Callable[P, Awaitable[Execution]]:
|
|
81
|
+
"""
|
|
82
|
+
Schedule a keyed readiness update from a poll.
|
|
83
|
+
|
|
84
|
+
Polls are deduplicated by `key` so repeated polls don't pile up tasks. When
|
|
85
|
+
the poll would move something to READY, any pending task is replaced
|
|
86
|
+
instead: a previous attempt can be left pending with its key still known
|
|
87
|
+
(for example, when a worker's claim fails during a Redis disruption) and
|
|
88
|
+
would otherwise block every later poll until docket's `redelivery_timeout`.
|
|
89
|
+
"""
|
|
90
|
+
if becoming_ready:
|
|
91
|
+
return docket.replace(function, now("UTC"), key)
|
|
92
|
+
return docket.add(function, key=key)
|
|
93
|
+
|
|
94
|
+
|
|
70
95
|
_OSS_WORKER_CHANNEL_REQUIRED_CAPABILITIES: list[WorkerChannelCapability] = [
|
|
71
96
|
WORKER_HEARTBEAT_CAPABILITY,
|
|
72
97
|
WORK_POOL_SNAPSHOT_CAPABILITY,
|
|
@@ -851,6 +876,17 @@ async def get_scheduled_flow_runs(
|
|
|
851
876
|
]
|
|
852
877
|
work_queue_ids = [wq.id for wq in work_queues]
|
|
853
878
|
|
|
879
|
+
ready_work_queue_ids = [
|
|
880
|
+
wq.id for wq in work_queues if wq.status == WorkQueueStatus.NOT_READY
|
|
881
|
+
]
|
|
882
|
+
deployments_becoming_ready = bool(ready_work_queue_ids)
|
|
883
|
+
if not deployments_becoming_ready:
|
|
884
|
+
deployments_becoming_ready = (
|
|
885
|
+
await models.deployments.has_not_ready_deployments(
|
|
886
|
+
session=session, work_queue_ids=[wq.id for wq in work_queues]
|
|
887
|
+
)
|
|
888
|
+
)
|
|
889
|
+
|
|
854
890
|
async with db.session_context(begin_transaction=True) as session:
|
|
855
891
|
queue_response = await models.workers.get_scheduled_flow_runs(
|
|
856
892
|
session=session,
|
|
@@ -861,21 +897,29 @@ async def get_scheduled_flow_runs(
|
|
|
861
897
|
limit=limit,
|
|
862
898
|
)
|
|
863
899
|
|
|
864
|
-
|
|
900
|
+
# Filtered polls only carry their own queues, so scope their keys to those
|
|
901
|
+
# queues; otherwise a poll for one subset could replace another's update.
|
|
902
|
+
key_scope = f"work_pool:{work_pool_id}"
|
|
903
|
+
if work_queue_ids is not None:
|
|
904
|
+
key_scope += ":" + ",".join(sorted(str(id) for id in set(work_queue_ids)))
|
|
905
|
+
|
|
906
|
+
await schedule_readiness_update(
|
|
907
|
+
docket,
|
|
865
908
|
mark_work_queues_ready,
|
|
866
|
-
key=f"mark_work_queues_ready:
|
|
909
|
+
key=f"mark_work_queues_ready:{key_scope}",
|
|
910
|
+
becoming_ready=bool(ready_work_queue_ids),
|
|
867
911
|
)(
|
|
868
912
|
polled_work_queue_ids=[
|
|
869
913
|
wq.id for wq in work_queues if wq.status != WorkQueueStatus.NOT_READY
|
|
870
914
|
],
|
|
871
|
-
ready_work_queue_ids=
|
|
872
|
-
wq.id for wq in work_queues if wq.status == WorkQueueStatus.NOT_READY
|
|
873
|
-
],
|
|
915
|
+
ready_work_queue_ids=ready_work_queue_ids,
|
|
874
916
|
)
|
|
875
917
|
|
|
876
|
-
await
|
|
918
|
+
await schedule_readiness_update(
|
|
919
|
+
docket,
|
|
877
920
|
mark_deployments_ready,
|
|
878
|
-
key=f"mark_deployments_ready:
|
|
921
|
+
key=f"mark_deployments_ready:{key_scope}",
|
|
922
|
+
becoming_ready=deployments_becoming_ready,
|
|
879
923
|
)(
|
|
880
924
|
work_queue_ids=[wq.id for wq in work_queues],
|
|
881
925
|
)
|