prefect-client 3.6.30.dev2__tar.gz → 3.6.30.dev3__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.6.30.dev2 → prefect_client-3.6.30.dev3}/.gitignore +2 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/PKG-INFO +1 -1
- prefect_client-3.6.30.dev3/hatch_build.py +61 -0
- prefect_client-3.6.30.dev3/src/prefect/_build_info.py +5 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/__init__.py +42 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/routes.py +1 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/schemas/objects.py +18 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/deployments/AGENTS.md +2 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/deployments/steps/core.py +43 -0
- prefect_client-3.6.30.dev3/src/prefect/locking/_filelock.py +242 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/AGENTS.md +16 -1
- prefect_client-3.6.30.dev3/src/prefect/runner/_workspace_resolver.py +360 -0
- prefect_client-3.6.30.dev3/src/prefect/runner/_workspace_starter.py +217 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/storage.py +17 -0
- prefect_client-3.6.30.dev3/src/prefect/server/api/admin.py +85 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/server.py +252 -60
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/ui.py +1 -1
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/templating/__init__.py +64 -39
- prefect_client-3.6.30.dev2/src/prefect/_build_info.py +0 -5
- prefect_client-3.6.30.dev2/src/prefect/server/api/admin.py +0 -25
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/LICENSE +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/README.md +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/pyproject.toml +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/.prefectignore +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/AGENTS.md +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/__main__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/_launchers.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/bundles/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/bundles/_file_collector.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/bundles/_ignore_filter.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/bundles/_path_resolver.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/bundles/_zip_builder.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/bundles/_zip_extractor.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/bundles/execute.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/plugins/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/plugins/apply.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/plugins/diagnostics.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/plugins/manager.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/plugins/spec.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/sla/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/sla/client.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/sla/objects.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/_logging.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/ci_detection.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/client.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/device_id.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/emit.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/enabled.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/events.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/milestones.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/notice.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/service.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/compatibility/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/compatibility/async_dispatch.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/compatibility/backports.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/compatibility/blocks.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/compatibility/deprecated.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/compatibility/migration.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/compatibility/starlette.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/api.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/calls.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/cancellation.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/event_loop.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/inspection.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/primitives.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/services.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/threads.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/waiters.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/control_listener.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/installation.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/integrations.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/lazy.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/observability.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/pydantic/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/pydantic/schemas.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/pydantic/v1_schema.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/pydantic/v2_schema.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/pydantic/validated_func.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/pytz.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/retries.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/schemas/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/schemas/bases.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/schemas/fields.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/schemas/serializers.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/schemas/validators.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/send_entrypoint_logs.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/testing.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/urls.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/uuid7.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_internal/websockets.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_observers.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_result_records.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/fetcher.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/generator.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/models.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/naming.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/renderer.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/schema_converter.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/templates/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/templates/sdk.py.jinja +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/types.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/unions.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_states.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_vendor/croniter/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_vendor/croniter/croniter.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_versioning.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/_waiters.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/agent.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/analytics/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/artifacts.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/assets/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/assets/core.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/assets/materialize.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/automations.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/blocks/AGENTS.md +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/blocks/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/blocks/abstract.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/blocks/core.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/blocks/fields.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/blocks/notifications.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/blocks/redis.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/blocks/system.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/blocks/webhook.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/cache_policies.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/AGENTS.md +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/_version_checking.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/attribution.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/base.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/cloud.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/collections.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/constants.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_artifacts/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_artifacts/client.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_automations/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_automations/client.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_blocks_documents/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_blocks_documents/client.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_blocks_schemas/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_blocks_schemas/client.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_blocks_types/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_blocks_types/client.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_concurrency_limits/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_concurrency_limits/client.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_deployments/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_deployments/client.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_events/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_events/client.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_flow_runs/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_flow_runs/client.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_flows/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_flows/client.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_logs/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_logs/client.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_variables/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_variables/client.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_work_pools/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_work_pools/client.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/base.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/schemas/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/schemas/actions.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/schemas/events.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/schemas/filters.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/schemas/responses.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/schemas/schedules.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/schemas/sorting.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/subscriptions.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/types/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/types/flexible_schedule_list.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/utilities.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/AGENTS.md +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/_asyncio.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/_events.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/_leases.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/_sync.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/asyncio.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/context.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/services.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/sync.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/v1/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/v1/_asyncio.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/v1/_events.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/v1/asyncio.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/v1/context.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/v1/services.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/v1/sync.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/context.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/deployments/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/deployments/base.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/deployments/deployments.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/deployments/flow_runs.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/deployments/runner.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/deployments/schedules.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/deployments/steps/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/deployments/steps/pull.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/deployments/steps/utility.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/docker/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/docker/_buildx.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/docker/docker_image.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/engine.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/events/AGENTS.md +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/events/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/events/actions.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/events/clients.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/events/filters.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/events/related.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/events/schemas/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/events/schemas/automations.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/events/schemas/deployment_triggers.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/events/schemas/events.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/events/schemas/labelling.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/events/subscribers.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/events/utilities.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/events/worker.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/exceptions.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/filesystems.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/flow_engine.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/flow_runs.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/flows.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/futures.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/infrastructure/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/infrastructure/base.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/infrastructure/provisioners/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/infrastructure/provisioners/cloud_run.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/infrastructure/provisioners/coiled.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/infrastructure/provisioners/container_instance.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/infrastructure/provisioners/ecs.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/infrastructure/provisioners/modal.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/input/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/input/actions.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/input/run_input.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/locking/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/locking/filesystem.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/locking/memory.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/locking/protocol.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/logging/AGENTS.md +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/logging/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/logging/clients.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/logging/configuration.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/logging/filters.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/logging/formatters.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/logging/handlers.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/logging/highlighters.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/logging/loggers.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/logging/logging.yml +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/main.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/plugins.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/py.typed +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/results.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/_cancel_finalizer.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/_cancellation_manager.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/_control_channel.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/_deployment_registry.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/_event_emitter.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/_flow_resolver.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/_flow_run_executor.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/_hook_runner.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/_limit_manager.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/_process_manager.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/_scheduled_run_poller.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/_starter_bundle.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/_starter_direct.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/_starter_engine.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/_state_proposer.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/runner.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runner/server.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runtime/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runtime/deployment.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runtime/flow_run.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/runtime/task_run.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/schedules.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/serializers.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/artifacts.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/automations.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/background_workers.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/block_capabilities.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/block_documents.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/block_schemas.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/block_types.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/clients.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/collections.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/collections_data/views/aggregate-worker-metadata.json +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/concurrency_limits.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/concurrency_limits_v2.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/csrf_token.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/dependencies.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/deployments.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/events.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/flow_run_states.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/flow_runs.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/flows.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/logs.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/middleware.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/root.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/run_history.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/saved_searches.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/static/prefect-logo-mark-gradient.png +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/task_run_states.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/task_runs.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/task_workers.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/templates.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/ui/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/ui/flow_runs.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/ui/flows.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/ui/schemas.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/ui/task_runs.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/validation.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/variables.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/work_queues.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/server/api/workers.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/AGENTS.md +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/base.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/constants.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/context.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/legacy.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/_defaults.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/api.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/cli.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/client.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/cloud.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/deployments.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/events.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/experiments.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/flows.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/internal.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/logging.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/results.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/root.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/runner.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/api.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/concurrency.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/database.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/deployments.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/docket.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/ephemeral.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/events.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/flow_run_graph.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/logs.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/root.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/services.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/tasks.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/tasks.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/telemetry.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/testing.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/worker.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/profiles.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/profiles.toml +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/settings/sources.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/states.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/task_engine.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/task_runners.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/task_runs.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/task_worker.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/tasks.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/telemetry/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/telemetry/_metrics.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/telemetry/run_telemetry.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/transactions.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/types/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/types/_concurrency.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/types/_datetime.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/types/_schema.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/types/entrypoint.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/types/names.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/AGENTS.md +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/_ast.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/_deprecated.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/_engine.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/_git.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/_infrastructure_exit_codes.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/annotations.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/asyncutils/AGENTS.md +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/asyncutils/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/callables/AGENTS.md +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/callables/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/collections.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/compat.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/context.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/dispatch.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/dockerutils.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/engine/AGENTS.md +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/engine/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/filesystem/AGENTS.md +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/filesystem/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/generics.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/hashing.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/importtools.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/math.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/names.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/processutils/AGENTS.md +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/processutils/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/pydantic.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/render_swagger.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/schema_tools/AGENTS.md +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/schema_tools/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/schema_tools/hydration.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/schema_tools/validation.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/services.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/slugify.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/templating/AGENTS.md +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/text.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/timeout.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/urls.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/utilities/visualization.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/variables.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/workers/AGENTS.md +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/workers/__init__.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/workers/base.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/workers/block.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/workers/cloud.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/workers/process.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/workers/server.py +0 -0
- {prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/workers/utilities.py +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
|
9
|
+
except ModuleNotFoundError: # pragma: no cover - only used when testing helpers
|
|
10
|
+
|
|
11
|
+
class BuildHookInterface: # type: ignore[no-redef]
|
|
12
|
+
root: str
|
|
13
|
+
target_name: str
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
PACKAGED_UI_INDEX_FILES = (
|
|
17
|
+
Path("src/prefect/server/ui/index.html"),
|
|
18
|
+
Path("src/prefect/server/ui-v2/index.html"),
|
|
19
|
+
)
|
|
20
|
+
REQUIRE_PACKAGED_UI_ENV_VAR = "PREFECT_REQUIRE_PACKAGED_UI_BUNDLES"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _truthy_env_var(name: str) -> bool:
|
|
24
|
+
return os.environ.get(name, "").lower() not in {"", "0", "false", "no", "off"}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def should_validate_packaged_ui_index_files(root: str | Path) -> bool:
|
|
28
|
+
if _truthy_env_var(REQUIRE_PACKAGED_UI_ENV_VAR):
|
|
29
|
+
return True
|
|
30
|
+
|
|
31
|
+
root_path = Path(root)
|
|
32
|
+
return any(
|
|
33
|
+
(root_path / index_file.parent).exists()
|
|
34
|
+
for index_file in PACKAGED_UI_INDEX_FILES
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def validate_packaged_ui_index_files(root: str | Path) -> None:
|
|
39
|
+
root_path = Path(root)
|
|
40
|
+
missing_index_files = [
|
|
41
|
+
str(index_file)
|
|
42
|
+
for index_file in PACKAGED_UI_INDEX_FILES
|
|
43
|
+
if not (root_path / index_file).is_file()
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
if missing_index_files:
|
|
47
|
+
raise RuntimeError(
|
|
48
|
+
"Prefect package builds require both UI bundles to be built. "
|
|
49
|
+
"Missing index.html files: "
|
|
50
|
+
f"{', '.join(missing_index_files)}"
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class CustomBuildHook(BuildHookInterface):
|
|
55
|
+
def initialize(self, version: str, build_data: dict[str, Any]) -> None:
|
|
56
|
+
if (
|
|
57
|
+
version != "editable"
|
|
58
|
+
and self.target_name in {"sdist", "wheel"}
|
|
59
|
+
and should_validate_packaged_ui_index_files(self.root)
|
|
60
|
+
):
|
|
61
|
+
validate_packaged_ui_index_files(self.root)
|
|
@@ -110,6 +110,8 @@ from prefect.client.schemas.objects import (
|
|
|
110
110
|
FlowRunResult,
|
|
111
111
|
Parameter,
|
|
112
112
|
Constant,
|
|
113
|
+
ServerDefaultResultStorage,
|
|
114
|
+
ServerDefaultResultStorageUpdate,
|
|
113
115
|
TaskRunPolicy,
|
|
114
116
|
WorkQueue,
|
|
115
117
|
WorkQueueStatusDetail,
|
|
@@ -1079,6 +1081,27 @@ class PrefectClient(
|
|
|
1079
1081
|
res = await self._client.get("/admin/version")
|
|
1080
1082
|
return res.json()
|
|
1081
1083
|
|
|
1084
|
+
async def read_server_default_result_storage(
|
|
1085
|
+
self,
|
|
1086
|
+
) -> ServerDefaultResultStorage:
|
|
1087
|
+
response = await self._client.get("/admin/storage")
|
|
1088
|
+
return ServerDefaultResultStorage.model_validate(response.json())
|
|
1089
|
+
|
|
1090
|
+
async def update_server_default_result_storage(
|
|
1091
|
+
self,
|
|
1092
|
+
default_result_storage_block_id: UUID,
|
|
1093
|
+
) -> ServerDefaultResultStorage:
|
|
1094
|
+
response = await self._client.put(
|
|
1095
|
+
"/admin/storage",
|
|
1096
|
+
json=ServerDefaultResultStorageUpdate(
|
|
1097
|
+
default_result_storage_block_id=default_result_storage_block_id
|
|
1098
|
+
).model_dump(mode="json"),
|
|
1099
|
+
)
|
|
1100
|
+
return ServerDefaultResultStorage.model_validate(response.json())
|
|
1101
|
+
|
|
1102
|
+
async def clear_server_default_result_storage(self) -> None:
|
|
1103
|
+
await self._client.delete("/admin/storage")
|
|
1104
|
+
|
|
1082
1105
|
def client_version(self) -> str:
|
|
1083
1106
|
return prefect.__version__
|
|
1084
1107
|
|
|
@@ -1451,6 +1474,25 @@ class SyncPrefectClient(
|
|
|
1451
1474
|
res = self._client.get("/admin/version")
|
|
1452
1475
|
return res.json()
|
|
1453
1476
|
|
|
1477
|
+
def read_server_default_result_storage(self) -> ServerDefaultResultStorage:
|
|
1478
|
+
response = self._client.get("/admin/storage")
|
|
1479
|
+
return ServerDefaultResultStorage.model_validate(response.json())
|
|
1480
|
+
|
|
1481
|
+
def update_server_default_result_storage(
|
|
1482
|
+
self,
|
|
1483
|
+
default_result_storage_block_id: UUID,
|
|
1484
|
+
) -> ServerDefaultResultStorage:
|
|
1485
|
+
response = self._client.put(
|
|
1486
|
+
"/admin/storage",
|
|
1487
|
+
json=ServerDefaultResultStorageUpdate(
|
|
1488
|
+
default_result_storage_block_id=default_result_storage_block_id
|
|
1489
|
+
).model_dump(mode="json"),
|
|
1490
|
+
)
|
|
1491
|
+
return ServerDefaultResultStorage.model_validate(response.json())
|
|
1492
|
+
|
|
1493
|
+
def clear_server_default_result_storage(self) -> None:
|
|
1494
|
+
self._client.delete("/admin/storage")
|
|
1495
|
+
|
|
1454
1496
|
def client_version(self) -> str:
|
|
1455
1497
|
return prefect.__version__
|
|
1456
1498
|
|
{prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/client/schemas/objects.py
RENAMED
|
@@ -1550,6 +1550,24 @@ class WorkPoolStorageConfiguration(PrefectBaseModel):
|
|
|
1550
1550
|
)
|
|
1551
1551
|
|
|
1552
1552
|
|
|
1553
|
+
class ServerDefaultResultStorage(PrefectBaseModel):
|
|
1554
|
+
"""Server-side default result storage configuration."""
|
|
1555
|
+
|
|
1556
|
+
default_result_storage_block_id: Optional[UUID] = Field(
|
|
1557
|
+
default=None,
|
|
1558
|
+
description="The block document ID of the server default result storage block.",
|
|
1559
|
+
)
|
|
1560
|
+
|
|
1561
|
+
|
|
1562
|
+
class ServerDefaultResultStorageUpdate(PrefectBaseModel):
|
|
1563
|
+
"""Request payload for setting the server default result storage block."""
|
|
1564
|
+
|
|
1565
|
+
default_result_storage_block_id: UUID = Field(
|
|
1566
|
+
default=...,
|
|
1567
|
+
description="The block document ID of the server default result storage block.",
|
|
1568
|
+
)
|
|
1569
|
+
|
|
1570
|
+
|
|
1553
1571
|
class WorkPool(ObjectBaseModel):
|
|
1554
1572
|
"""An ORM representation of a work pool"""
|
|
1555
1573
|
|
|
@@ -23,6 +23,8 @@ Built-in steps:
|
|
|
23
23
|
- `steps/pull.py` — `git_clone`, `set_working_directory`, `pull_from_remote_storage`
|
|
24
24
|
- `steps/utility.py` — `run_shell_script`, `pip_install_requirements`
|
|
25
25
|
|
|
26
|
+
**Step observer**: `run_steps` does not accept a step completion callback as a parameter by design — inject one via `_observe_step_completion(callback)` context manager from `steps/core.py`. The callback receives `(step, output, cwd_before, cwd_after)` after each step; either CWD arg is `None` when the directory becomes inaccessible (e.g., the step deleted its working directory).
|
|
27
|
+
|
|
26
28
|
## Entrypoint Formats
|
|
27
29
|
|
|
28
30
|
`runner.py`'s `from_storage` / `afrom_storage` (and `Flow.from_source`) support two entrypoint formats:
|
{prefect_client-3.6.30.dev2 → prefect_client-3.6.30.dev3}/src/prefect/deployments/steps/core.py
RENAMED
|
@@ -17,8 +17,12 @@ import os
|
|
|
17
17
|
import re
|
|
18
18
|
import subprocess
|
|
19
19
|
import warnings
|
|
20
|
+
from collections.abc import Callable, Iterator
|
|
21
|
+
from contextlib import contextmanager
|
|
22
|
+
from contextvars import ContextVar
|
|
20
23
|
from copy import deepcopy
|
|
21
24
|
from importlib import import_module
|
|
25
|
+
from pathlib import Path
|
|
22
26
|
from typing import Any
|
|
23
27
|
from uuid import UUID
|
|
24
28
|
|
|
@@ -39,6 +43,15 @@ from prefect.utilities.templating import (
|
|
|
39
43
|
|
|
40
44
|
RESERVED_KEYWORDS = {"id", "requires"}
|
|
41
45
|
|
|
46
|
+
_StepCompletionObserver = Callable[
|
|
47
|
+
[dict[str, Any], Any, Path | None, Path | None],
|
|
48
|
+
None,
|
|
49
|
+
]
|
|
50
|
+
_STEP_COMPLETION_OBSERVER: ContextVar[_StepCompletionObserver | None] = ContextVar(
|
|
51
|
+
"step_completion_observer",
|
|
52
|
+
default=None,
|
|
53
|
+
)
|
|
54
|
+
|
|
42
55
|
|
|
43
56
|
class StepExecutionError(Exception):
|
|
44
57
|
"""
|
|
@@ -46,6 +59,22 @@ class StepExecutionError(Exception):
|
|
|
46
59
|
"""
|
|
47
60
|
|
|
48
61
|
|
|
62
|
+
def _safe_current_working_directory() -> Path | None:
|
|
63
|
+
try:
|
|
64
|
+
return Path.cwd().resolve()
|
|
65
|
+
except OSError:
|
|
66
|
+
return None
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@contextmanager
|
|
70
|
+
def _observe_step_completion(callback: _StepCompletionObserver) -> Iterator[None]:
|
|
71
|
+
token = _STEP_COMPLETION_OBSERVER.set(callback)
|
|
72
|
+
try:
|
|
73
|
+
yield
|
|
74
|
+
finally:
|
|
75
|
+
_STEP_COMPLETION_OBSERVER.reset(token)
|
|
76
|
+
|
|
77
|
+
|
|
49
78
|
def _strip_version(requirement: str) -> str:
|
|
50
79
|
"""
|
|
51
80
|
Strips the version from a requirement string.
|
|
@@ -152,6 +181,7 @@ async def run_steps(
|
|
|
152
181
|
logger: Any | None = None,
|
|
153
182
|
) -> dict[str, Any]:
|
|
154
183
|
upstream_outputs = deepcopy(upstream_outputs) if upstream_outputs else {}
|
|
184
|
+
step_completion_observer = _STEP_COMPLETION_OBSERVER.get()
|
|
155
185
|
for step_index, step in enumerate(steps):
|
|
156
186
|
if not step:
|
|
157
187
|
continue
|
|
@@ -177,6 +207,11 @@ async def run_steps(
|
|
|
177
207
|
|
|
178
208
|
try:
|
|
179
209
|
# catch warnings to ensure deprecation warnings are printed
|
|
210
|
+
step_start_cwd = (
|
|
211
|
+
_safe_current_working_directory()
|
|
212
|
+
if step_completion_observer is not None
|
|
213
|
+
else None
|
|
214
|
+
)
|
|
180
215
|
with warnings.catch_warnings(record=True) as w:
|
|
181
216
|
warnings.simplefilter(
|
|
182
217
|
"always",
|
|
@@ -201,6 +236,14 @@ async def run_steps(
|
|
|
201
236
|
print_function(message)
|
|
202
237
|
printed_messages.append(message)
|
|
203
238
|
|
|
239
|
+
if step_completion_observer is not None:
|
|
240
|
+
step_completion_observer(
|
|
241
|
+
step,
|
|
242
|
+
step_output,
|
|
243
|
+
step_start_cwd,
|
|
244
|
+
_safe_current_working_directory(),
|
|
245
|
+
)
|
|
246
|
+
|
|
204
247
|
if not isinstance(step_output, dict):
|
|
205
248
|
if PREFECT_DEBUG_MODE:
|
|
206
249
|
get_logger().warning(
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
"""Internal cross-platform file lock using lock file creation.
|
|
2
|
+
|
|
3
|
+
Uses the existence of a lock file to indicate the lock is held, following
|
|
4
|
+
the same pattern as FileSystemLockManager. The lock file is created
|
|
5
|
+
atomically and removed on release. No OS-specific locking primitives are
|
|
6
|
+
required.
|
|
7
|
+
|
|
8
|
+
The owning process's PID is written to the lock file so that stale locks
|
|
9
|
+
left behind by crashed processes can be detected and recovered.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import asyncio
|
|
13
|
+
import os
|
|
14
|
+
import sys
|
|
15
|
+
import tempfile
|
|
16
|
+
import time
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _is_pid_alive(pid: int) -> bool:
|
|
21
|
+
"""Check whether a process with the given PID is still running.
|
|
22
|
+
|
|
23
|
+
Uses `os.kill(pid, 0)` on Unix (harmless signal-0 probe). On Windows
|
|
24
|
+
`os.kill` terminates the target process, so we use
|
|
25
|
+
`kernel32.OpenProcess` instead.
|
|
26
|
+
"""
|
|
27
|
+
if sys.platform == "win32":
|
|
28
|
+
import ctypes
|
|
29
|
+
|
|
30
|
+
_PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
|
|
31
|
+
handle = ctypes.windll.kernel32.OpenProcess( # type: ignore[attr-defined]
|
|
32
|
+
_PROCESS_QUERY_LIMITED_INFORMATION, False, pid
|
|
33
|
+
)
|
|
34
|
+
if handle:
|
|
35
|
+
ctypes.windll.kernel32.CloseHandle(handle) # type: ignore[attr-defined]
|
|
36
|
+
return True
|
|
37
|
+
return False
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
os.kill(pid, 0)
|
|
41
|
+
except ProcessLookupError:
|
|
42
|
+
return False
|
|
43
|
+
except OSError:
|
|
44
|
+
# PermissionError means the process exists but we can't signal it
|
|
45
|
+
return True
|
|
46
|
+
return True
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
_STALE_EMPTY_THRESHOLD = 5 # seconds before an empty/malformed lock is stale
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _remove_stale_lock(path: Path) -> None:
|
|
53
|
+
"""Remove the lock file if the owning process is no longer alive.
|
|
54
|
+
|
|
55
|
+
For empty or malformed lock files (e.g. from a writer that crashed
|
|
56
|
+
between creating the file and writing the PID), the file's mtime is
|
|
57
|
+
checked: if it was last modified more than _STALE_EMPTY_THRESHOLD
|
|
58
|
+
seconds ago the writer must have crashed, so the file is removed.
|
|
59
|
+
If the mtime is recent the writer may still be running, so the file
|
|
60
|
+
is left alone and the poll loop will retry.
|
|
61
|
+
|
|
62
|
+
To avoid a TOCTOU race where another waiter removes the stale file
|
|
63
|
+
and acquires a new lock between our read and our unlink, we record
|
|
64
|
+
the file's inode before deciding it is stale and verify it has not
|
|
65
|
+
changed before unlinking.
|
|
66
|
+
"""
|
|
67
|
+
try:
|
|
68
|
+
st = os.stat(str(path))
|
|
69
|
+
contents = path.read_text().strip()
|
|
70
|
+
except (FileNotFoundError, OSError):
|
|
71
|
+
return
|
|
72
|
+
|
|
73
|
+
original_ino = st.st_ino
|
|
74
|
+
|
|
75
|
+
if not contents:
|
|
76
|
+
# Empty file -- check mtime to decide if the writer crashed.
|
|
77
|
+
_remove_if_same(path, original_ino, st.st_mtime)
|
|
78
|
+
return
|
|
79
|
+
|
|
80
|
+
try:
|
|
81
|
+
pid = int(contents)
|
|
82
|
+
except ValueError:
|
|
83
|
+
# Malformed content -- check mtime to decide if the writer crashed.
|
|
84
|
+
_remove_if_same(path, original_ino, st.st_mtime)
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
if not _is_pid_alive(pid):
|
|
88
|
+
_unlink_if_same_inode(path, original_ino)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _remove_if_same(path: Path, original_ino: int, mtime: float) -> None:
|
|
92
|
+
"""Remove *path* if mtime is stale and the inode has not changed."""
|
|
93
|
+
if time.time() - mtime > _STALE_EMPTY_THRESHOLD:
|
|
94
|
+
_unlink_if_same_inode(path, original_ino)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _unlink_if_same_inode(path: Path, expected_ino: int) -> None:
|
|
98
|
+
"""Unlink *path* only if its current inode matches *expected_ino*.
|
|
99
|
+
|
|
100
|
+
This prevents removing a fresh lock file that was created by another
|
|
101
|
+
process between our staleness check and the unlink call.
|
|
102
|
+
"""
|
|
103
|
+
try:
|
|
104
|
+
current_st = os.stat(str(path))
|
|
105
|
+
except (FileNotFoundError, OSError):
|
|
106
|
+
return
|
|
107
|
+
if current_st.st_ino == expected_ino:
|
|
108
|
+
path.unlink(missing_ok=True)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _write_lock(path: Path) -> None:
|
|
112
|
+
"""Atomically create the lock file with the current PID.
|
|
113
|
+
|
|
114
|
+
Writes the PID to a temporary file in the same directory and then
|
|
115
|
+
uses `os.rename` (atomic on POSIX, atomic on Windows for same
|
|
116
|
+
volume) to move it into place. This guarantees the lock file is
|
|
117
|
+
never visible in an empty or partial state, which prevents a
|
|
118
|
+
concurrent `_remove_stale_lock` from falsely treating it as stale.
|
|
119
|
+
|
|
120
|
+
Raises `FileExistsError` if the lock file already exists (via
|
|
121
|
+
`os.link` on POSIX for true atomic create-or-fail, or
|
|
122
|
+
`os.open(O_CREAT | O_EXCL)` as a fallback on filesystems without
|
|
123
|
+
hard-link support).
|
|
124
|
+
"""
|
|
125
|
+
# Ensure the parent directory exists so that mkstemp and the lock
|
|
126
|
+
# file can be created even when the storage base path is fresh.
|
|
127
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
128
|
+
|
|
129
|
+
# Write PID to a temp file in the same directory so rename stays
|
|
130
|
+
# on the same filesystem.
|
|
131
|
+
fd, tmp = tempfile.mkstemp(dir=str(path.parent), prefix=".lock_")
|
|
132
|
+
try:
|
|
133
|
+
os.write(fd, str(os.getpid()).encode())
|
|
134
|
+
os.close(fd)
|
|
135
|
+
fd = -1 # mark as closed
|
|
136
|
+
# Use os.link (hard link) to atomically claim the lock path.
|
|
137
|
+
# If the target already exists, this raises FileExistsError.
|
|
138
|
+
try:
|
|
139
|
+
os.link(tmp, str(path))
|
|
140
|
+
except FileExistsError:
|
|
141
|
+
raise
|
|
142
|
+
except OSError:
|
|
143
|
+
# Fallback for filesystems that don't support hard links
|
|
144
|
+
# (e.g. some Windows or network mounts): use O_CREAT|O_EXCL
|
|
145
|
+
# which is atomic on all POSIX and Windows filesystems.
|
|
146
|
+
try:
|
|
147
|
+
excl_fd = os.open(str(path), os.O_CREAT | os.O_EXCL | os.O_WRONLY)
|
|
148
|
+
except FileExistsError:
|
|
149
|
+
raise
|
|
150
|
+
try:
|
|
151
|
+
os.write(excl_fd, str(os.getpid()).encode())
|
|
152
|
+
finally:
|
|
153
|
+
os.close(excl_fd)
|
|
154
|
+
return
|
|
155
|
+
finally:
|
|
156
|
+
if fd >= 0:
|
|
157
|
+
os.close(fd)
|
|
158
|
+
# Always clean up the temp file (link created a second entry)
|
|
159
|
+
try:
|
|
160
|
+
os.unlink(tmp)
|
|
161
|
+
except FileNotFoundError:
|
|
162
|
+
pass
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class FileLock:
|
|
166
|
+
"""A cross-platform file lock using lock file existence.
|
|
167
|
+
|
|
168
|
+
Can be used as a synchronous context manager or with the async
|
|
169
|
+
aacquire/release pair. The lock file stores the owning process's
|
|
170
|
+
PID so that stale locks from crashed processes are automatically
|
|
171
|
+
recovered.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
path: Path to the lock file.
|
|
175
|
+
timeout: Maximum seconds to wait for lock acquisition.
|
|
176
|
+
Use -1 to wait indefinitely. Defaults to -1.
|
|
177
|
+
poll_interval: Seconds between lock attempts.
|
|
178
|
+
Defaults to 0.1.
|
|
179
|
+
"""
|
|
180
|
+
|
|
181
|
+
def __init__(
|
|
182
|
+
self,
|
|
183
|
+
path: str | Path,
|
|
184
|
+
timeout: float = -1,
|
|
185
|
+
poll_interval: float = 0.1,
|
|
186
|
+
) -> None:
|
|
187
|
+
self._path = Path(path)
|
|
188
|
+
self._timeout = timeout
|
|
189
|
+
self._poll_interval = poll_interval
|
|
190
|
+
self._locked = False
|
|
191
|
+
|
|
192
|
+
def acquire(self) -> None:
|
|
193
|
+
"""Acquire the file lock, blocking until available or timeout."""
|
|
194
|
+
start = time.monotonic()
|
|
195
|
+
while True:
|
|
196
|
+
try:
|
|
197
|
+
_write_lock(self._path)
|
|
198
|
+
self._locked = True
|
|
199
|
+
return
|
|
200
|
+
except FileExistsError:
|
|
201
|
+
_remove_stale_lock(self._path)
|
|
202
|
+
elapsed = time.monotonic() - start
|
|
203
|
+
if self._timeout >= 0 and elapsed >= self._timeout:
|
|
204
|
+
raise TimeoutError(
|
|
205
|
+
f"Failed to acquire lock on {str(self._path)!r}"
|
|
206
|
+
f" within {self._timeout}s"
|
|
207
|
+
)
|
|
208
|
+
time.sleep(self._poll_interval)
|
|
209
|
+
|
|
210
|
+
async def aacquire(self) -> None:
|
|
211
|
+
"""Acquire the file lock without blocking the event loop."""
|
|
212
|
+
start = time.monotonic()
|
|
213
|
+
while True:
|
|
214
|
+
try:
|
|
215
|
+
_write_lock(self._path)
|
|
216
|
+
self._locked = True
|
|
217
|
+
return
|
|
218
|
+
except FileExistsError:
|
|
219
|
+
_remove_stale_lock(self._path)
|
|
220
|
+
elapsed = time.monotonic() - start
|
|
221
|
+
if self._timeout >= 0 and elapsed >= self._timeout:
|
|
222
|
+
raise TimeoutError(
|
|
223
|
+
f"Failed to acquire lock on {str(self._path)!r}"
|
|
224
|
+
f" within {self._timeout}s"
|
|
225
|
+
)
|
|
226
|
+
await asyncio.sleep(self._poll_interval)
|
|
227
|
+
|
|
228
|
+
def release(self) -> None:
|
|
229
|
+
"""Release the file lock."""
|
|
230
|
+
if self._locked:
|
|
231
|
+
self._path.unlink(missing_ok=True)
|
|
232
|
+
self._locked = False
|
|
233
|
+
|
|
234
|
+
def __enter__(self) -> "FileLock":
|
|
235
|
+
self.acquire()
|
|
236
|
+
return self
|
|
237
|
+
|
|
238
|
+
def __exit__(self, *args: object) -> None:
|
|
239
|
+
self.release()
|
|
240
|
+
|
|
241
|
+
def __del__(self) -> None:
|
|
242
|
+
self.release()
|
|
@@ -23,6 +23,7 @@ Thin facade over single-responsibility extracted classes. New behavior belongs i
|
|
|
23
23
|
| FlowRunExecutorContext | _flow_run_executor.py | Async context manager for one-shot execution outside Runner (CLI, bundles) |
|
|
24
24
|
| DirectSubprocessStarter | _starter_direct.py | Runs Flow object via run_flow_in_subprocess |
|
|
25
25
|
| EngineCommandStarter | _starter_engine.py | Spawns `python -m prefect.engine` subprocess |
|
|
26
|
+
| WorkspaceResolvingEngineCommandStarter | _workspace_starter.py | Resolves workspace (pull steps) via `_workspace_resolver` subprocess then delegates to EngineCommandStarter; used by `prefect flow-run execute` |
|
|
26
27
|
| BundleExecutionStarter | _starter_bundle.py | Executes serialized bundle in SpawnProcess |
|
|
27
28
|
|
|
28
29
|
## Key Contracts
|
|
@@ -40,7 +41,7 @@ Thin facade over single-responsibility extracted classes. New behavior belongs i
|
|
|
40
41
|
- `_flow_run_process_map` dict -- replaced by ProcessManager
|
|
41
42
|
- `_kill_process()` -- replaced by ProcessManager.kill()
|
|
42
43
|
- `_run_on_crashed_hooks()` / `_run_on_cancellation_hooks()` -- replaced by HookRunner
|
|
43
|
-
- `execute_flow_run()` -- deprecated (Mar 2026); use `FlowRunExecutorContext` + `
|
|
44
|
+
- `execute_flow_run()` -- deprecated (Mar 2026); use `FlowRunExecutorContext` + `WorkspaceResolvingEngineCommandStarter`
|
|
44
45
|
- `execute_bundle()` -- deprecated (Mar 2026); use `execute_bundle()` from `prefect._experimental.bundles.execute`
|
|
45
46
|
- `reschedule_current_flow_runs()` -- deprecated (Mar 2026); SIGTERM rescheduling is now handled inline by the CLI execute path
|
|
46
47
|
|
|
@@ -123,6 +124,20 @@ This matters because `get_directory` typically calls `shutil.copytree(..., dirs_
|
|
|
123
124
|
|
|
124
125
|
These validations exist to prevent git argument injection. Do not bypass them when constructing `GitRepository` programmatically.
|
|
125
126
|
|
|
127
|
+
## GitRepository Concurrent Pull Protection
|
|
128
|
+
|
|
129
|
+
`GitRepository.pull_code()` serializes concurrent calls via a `FileLock` (`prefect.locking._filelock`). The lock file sits adjacent to the destination: `destination.parent / (destination.name + ".lock")`. Stale locks from crashed processes are recovered automatically via PID check. Tests that broadly monkeypatch `pathlib.Path.exists` must account for this lock file being created next to the destination.
|
|
130
|
+
|
|
131
|
+
## Workspace Resolver Subprocess
|
|
132
|
+
|
|
133
|
+
`_workspace_resolver.py` prepares a flow run workspace in an isolated subprocess (storage pull, pull steps, CWD/env/sys.path capture). Runs as `python -m prefect.runner._workspace_resolver`.
|
|
134
|
+
|
|
135
|
+
**Stdout is reserved for the JSON `PreparedWorkspaceResult` payload only.** Pull step output (including inherited stdout from child processes) is redirected to stderr. Parse `process.stdout` for the result, `process.stderr` for diagnostics. Violating this breaks callers silently.
|
|
136
|
+
|
|
137
|
+
**Caller-facing API:** Use `WorkspaceResolvingEngineCommandStarter` (`_workspace_starter.py`) rather than calling the resolver directly. It wraps the subprocess call, memoizes the resolved workspace (one subprocess call per starter instance), and provides `resolve_flow()` that loads the flow inside the resolved workspace context. Pass `starter.resolve_flow` as the `resolve_flow` argument to `FlowRunExecutorContext.create_executor()` — using a separate lambda bypasses the workspace context and will fail to find the flow.
|
|
138
|
+
|
|
139
|
+
**Env/sys.path isolation:** `_prepared_workspace_context` mutates `os.environ` and `sys.path` in the caller process but does NOT change `os.getcwd()`. The parent working directory is preserved.
|
|
140
|
+
|
|
126
141
|
## Reference
|
|
127
142
|
|
|
128
143
|
Full refactor design and rationale: plans/completed/2026-02-18-runner-refactor.md
|