prefect-client 2.14.10__tar.gz → 2.14.11__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-2.14.10 → prefect-client-2.14.11}/PKG-INFO +1 -1
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/pydantic/v2_schema.py +9 -2
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/client/orchestration.py +50 -2
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/client/schemas/objects.py +16 -1
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/deployments/runner.py +29 -2
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/engine.py +128 -16
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/flows.py +16 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/infrastructure/kubernetes.py +64 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/infrastructure/provisioners/cloud_run.py +199 -33
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/infrastructure/provisioners/container_instance.py +398 -115
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/infrastructure/provisioners/ecs.py +483 -48
- prefect-client-2.14.11/src/prefect/input/__init__.py +11 -0
- prefect-client-2.14.11/src/prefect/input/actions.py +88 -0
- prefect-client-2.14.11/src/prefect/input/run_input.py +107 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/runner/runner.py +5 -0
- prefect-client-2.14.11/src/prefect/runner/server.py +162 -0
- prefect-client-2.14.11/src/prefect/runner/utils.py +92 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/settings.py +34 -9
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/dockerutils.py +31 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/processutils.py +5 -2
- prefect-client-2.14.11/src/prefect/utilities/validation.py +63 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/workers/utilities.py +0 -1
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect_client.egg-info/PKG-INFO +1 -1
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect_client.egg-info/SOURCES.txt +5 -0
- prefect-client-2.14.10/src/prefect/runner/server.py +0 -78
- {prefect-client-2.14.10 → prefect-client-2.14.11}/LICENSE +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/MANIFEST.in +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/README.md +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/requirements-client.txt +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/requirements-dev.txt +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/requirements.txt +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/setup.cfg +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/setup.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/.prefectignore +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/_logging.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/compatibility/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/compatibility/deprecated.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/compatibility/experimental.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/concurrency/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/concurrency/api.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/concurrency/calls.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/concurrency/cancellation.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/concurrency/event_loop.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/concurrency/inspection.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/concurrency/primitives.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/concurrency/services.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/concurrency/threads.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/concurrency/waiters.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/pydantic/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/pydantic/annotations/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/pydantic/annotations/pendulum.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/pydantic/schemas.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/pydantic/v2_validated_func.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/pytz.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/schemas/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/schemas/bases.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/schemas/fields.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/schemas/serializers.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/schemas/transformations.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/schemas/validators.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/applications.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/background.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/concurrency.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/datastructures.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/dependencies/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/dependencies/models.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/dependencies/utils.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/encoders.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/exception_handlers.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/exceptions.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/logger.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/middleware/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/middleware/asyncexitstack.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/middleware/cors.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/middleware/gzip.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/middleware/httpsredirect.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/middleware/trustedhost.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/middleware/wsgi.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/openapi/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/openapi/constants.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/openapi/docs.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/openapi/models.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/openapi/utils.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/param_functions.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/params.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/requests.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/responses.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/routing.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/security/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/security/api_key.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/security/base.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/security/http.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/security/oauth2.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/security/open_id_connect_url.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/security/utils.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/staticfiles.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/templating.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/testclient.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/types.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/utils.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_vendor/fastapi/websockets.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_version.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/agent.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/blocks/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/blocks/abstract.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/blocks/core.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/blocks/fields.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/blocks/kubernetes.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/blocks/notifications.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/blocks/system.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/blocks/webhook.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/client/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/client/base.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/client/cloud.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/client/collections.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/client/constants.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/client/schemas/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/client/schemas/actions.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/client/schemas/filters.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/client/schemas/responses.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/client/schemas/schedules.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/client/schemas/sorting.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/client/utilities.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/concurrency/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/concurrency/asyncio.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/concurrency/common.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/concurrency/events.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/concurrency/services.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/concurrency/sync.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/context.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/deployments/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/deployments/base.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/deployments/deployments.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/deployments/steps/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/deployments/steps/core.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/deployments/steps/pull.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/deployments/steps/utility.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/deprecated/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/deprecated/data_documents.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/events/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/events/actions.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/events/clients.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/events/filters.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/events/instrument.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/events/related.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/events/schemas.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/events/utilities.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/events/worker.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/exceptions.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/filesystems.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/futures.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/infrastructure/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/infrastructure/base.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/infrastructure/container.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/infrastructure/process.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/infrastructure/provisioners/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/logging/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/logging/configuration.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/logging/formatters.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/logging/handlers.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/logging/highlighters.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/logging/loggers.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/logging/logging.yml +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/manifests.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/packaging/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/packaging/base.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/packaging/docker.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/packaging/file.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/packaging/orion.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/packaging/serializers.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/plugins.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/profiles.toml +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/py.typed +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/results.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/runner/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/runner/storage.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/runtime/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/runtime/deployment.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/runtime/flow_run.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/runtime/task_run.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/serializers.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/server/api/static/prefect-logo-mark-gradient.png +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/software/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/software/base.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/software/conda.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/software/pip.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/software/python.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/states.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/task_runners.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/tasks.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/annotations.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/asyncutils.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/callables.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/collections.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/compat.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/context.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/dispatch.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/filesystem.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/hashing.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/importtools.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/math.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/names.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/pydantic.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/render_swagger.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/services.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/slugify.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/templating.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/text.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/utilities/visualization.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/variables.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/workers/__init__.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/workers/base.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/workers/block.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/workers/process.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/workers/server.py +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect_client.egg-info/dependency_links.txt +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect_client.egg-info/requires.txt +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect_client.egg-info/top_level.txt +0 -0
- {prefect-client-2.14.10 → prefect-client-2.14.11}/versioneer.py +0 -0
{prefect-client-2.14.10 → prefect-client-2.14.11}/src/prefect/_internal/pydantic/v2_schema.py
RENAMED
@@ -82,11 +82,18 @@ def process_v2_params(
|
|
82
82
|
return name, type_, field
|
83
83
|
|
84
84
|
|
85
|
-
def create_v2_schema(
|
85
|
+
def create_v2_schema(
|
86
|
+
name_: str,
|
87
|
+
model_cfg: t.Optional[ConfigDict] = None,
|
88
|
+
model_base: t.Optional[t.Type[V2BaseModel]] = None,
|
89
|
+
**model_fields
|
90
|
+
):
|
86
91
|
"""
|
87
92
|
Create a pydantic v2 model and craft a v1 compatible schema from it.
|
88
93
|
"""
|
89
|
-
model = create_model(
|
94
|
+
model = create_model(
|
95
|
+
name_, __config__=model_cfg, __base__=model_base, **model_fields
|
96
|
+
)
|
90
97
|
adapter = TypeAdapter(model)
|
91
98
|
|
92
99
|
# root model references under #definitions
|
@@ -80,6 +80,7 @@ from prefect.client.schemas.objects import (
|
|
80
80
|
Constant,
|
81
81
|
Deployment,
|
82
82
|
Flow,
|
83
|
+
FlowRunInput,
|
83
84
|
FlowRunNotificationPolicy,
|
84
85
|
FlowRunPolicy,
|
85
86
|
Log,
|
@@ -1780,18 +1781,23 @@ class PrefectClient:
|
|
1780
1781
|
raise
|
1781
1782
|
return FlowRun.parse_obj(response.json())
|
1782
1783
|
|
1783
|
-
async def resume_flow_run(
|
1784
|
+
async def resume_flow_run(
|
1785
|
+
self, flow_run_id: UUID, run_input: Optional[Dict] = None
|
1786
|
+
) -> OrchestrationResult:
|
1784
1787
|
"""
|
1785
1788
|
Resumes a paused flow run.
|
1786
1789
|
|
1787
1790
|
Args:
|
1788
1791
|
flow_run_id: the flow run ID of interest
|
1792
|
+
run_input: the input to resume the flow run with
|
1789
1793
|
|
1790
1794
|
Returns:
|
1791
1795
|
an OrchestrationResult model representation of state orchestration output
|
1792
1796
|
"""
|
1793
1797
|
try:
|
1794
|
-
response = await self._client.post(
|
1798
|
+
response = await self._client.post(
|
1799
|
+
f"/flow_runs/{flow_run_id}/resume", json={"run_input": run_input}
|
1800
|
+
)
|
1795
1801
|
except httpx.HTTPStatusError:
|
1796
1802
|
raise
|
1797
1803
|
|
@@ -2688,6 +2694,48 @@ class PrefectClient:
|
|
2688
2694
|
},
|
2689
2695
|
)
|
2690
2696
|
|
2697
|
+
async def create_flow_run_input(self, flow_run_id: UUID, key: str, value: str):
|
2698
|
+
"""
|
2699
|
+
Creates a flow run input.
|
2700
|
+
|
2701
|
+
Args:
|
2702
|
+
flow_run_id: The flow run id.
|
2703
|
+
key: The input key.
|
2704
|
+
value: The input value.
|
2705
|
+
"""
|
2706
|
+
|
2707
|
+
# Initialize the input to ensure that the key is valid.
|
2708
|
+
FlowRunInput(flow_run_id=flow_run_id, key=key, value=value)
|
2709
|
+
|
2710
|
+
response = await self._client.post(
|
2711
|
+
f"/flow_runs/{flow_run_id}/input",
|
2712
|
+
json={"key": key, "value": value},
|
2713
|
+
)
|
2714
|
+
response.raise_for_status()
|
2715
|
+
|
2716
|
+
async def read_flow_run_input(self, flow_run_id: UUID, key: str) -> str:
|
2717
|
+
"""
|
2718
|
+
Reads a flow run input.
|
2719
|
+
|
2720
|
+
Args:
|
2721
|
+
flow_run_id: The flow run id.
|
2722
|
+
key: The input key.
|
2723
|
+
"""
|
2724
|
+
response = await self._client.get(f"/flow_runs/{flow_run_id}/input/{key}")
|
2725
|
+
response.raise_for_status()
|
2726
|
+
return response.content.decode()
|
2727
|
+
|
2728
|
+
async def delete_flow_run_input(self, flow_run_id: UUID, key: str):
|
2729
|
+
"""
|
2730
|
+
Deletes a flow run input.
|
2731
|
+
|
2732
|
+
Args:
|
2733
|
+
flow_run_id: The flow run id.
|
2734
|
+
key: The input key.
|
2735
|
+
"""
|
2736
|
+
response = await self._client.delete(f"/flow_runs/{flow_run_id}/input/{key}")
|
2737
|
+
response.raise_for_status()
|
2738
|
+
|
2691
2739
|
async def __aenter__(self):
|
2692
2740
|
"""
|
2693
2741
|
Start the client.
|
@@ -25,7 +25,10 @@ from typing_extensions import Literal
|
|
25
25
|
|
26
26
|
from prefect._internal.schemas.bases import ObjectBaseModel, PrefectBaseModel
|
27
27
|
from prefect._internal.schemas.fields import CreatedBy, DateTimeTZ, UpdatedBy
|
28
|
-
from prefect._internal.schemas.validators import
|
28
|
+
from prefect._internal.schemas.validators import (
|
29
|
+
raise_on_name_alphanumeric_dashes_only,
|
30
|
+
raise_on_name_with_banned_characters,
|
31
|
+
)
|
29
32
|
from prefect.client.schemas.schedules import SCHEDULE_TYPES
|
30
33
|
from prefect.settings import PREFECT_CLOUD_API_URL
|
31
34
|
from prefect.utilities.collections import AutoEnum, listrepr
|
@@ -105,6 +108,7 @@ class StateDetails(PrefectBaseModel):
|
|
105
108
|
pause_timeout: DateTimeTZ = None
|
106
109
|
pause_reschedule: bool = False
|
107
110
|
pause_key: str = None
|
111
|
+
run_input_keyset: Optional[Dict[str, str]] = None
|
108
112
|
refresh_cache: bool = None
|
109
113
|
|
110
114
|
|
@@ -1523,3 +1527,14 @@ class Variable(ObjectBaseModel):
|
|
1523
1527
|
description="A list of variable tags",
|
1524
1528
|
example=["tag-1", "tag-2"],
|
1525
1529
|
)
|
1530
|
+
|
1531
|
+
|
1532
|
+
class FlowRunInput(ObjectBaseModel):
|
1533
|
+
flow_run_id: UUID = Field(description="The flow run ID associated with the input.")
|
1534
|
+
key: str = Field(description="The key of the input.")
|
1535
|
+
value: str = Field(description="The value of the input.")
|
1536
|
+
|
1537
|
+
@validator("key", check_fields=False)
|
1538
|
+
def validate_name_characters(cls, v):
|
1539
|
+
raise_on_name_alphanumeric_dashes_only(v)
|
1540
|
+
return v
|
@@ -44,7 +44,11 @@ from rich.table import Table
|
|
44
44
|
from prefect._internal.concurrency.api import create_call, from_async
|
45
45
|
from prefect._internal.pydantic import HAS_PYDANTIC_V2
|
46
46
|
from prefect.runner.storage import RunnerStorage
|
47
|
-
from prefect.settings import
|
47
|
+
from prefect.settings import (
|
48
|
+
PREFECT_DEFAULT_DOCKER_BUILD_NAMESPACE,
|
49
|
+
PREFECT_DEFAULT_WORK_POOL_NAME,
|
50
|
+
PREFECT_UI_URL,
|
51
|
+
)
|
48
52
|
from prefect.utilities.collections import get_from_dict
|
49
53
|
|
50
54
|
if HAS_PYDANTIC_V2:
|
@@ -70,6 +74,7 @@ from prefect.utilities.dockerutils import (
|
|
70
74
|
docker_client,
|
71
75
|
generate_default_dockerfile,
|
72
76
|
parse_image_tag,
|
77
|
+
split_repository_path,
|
73
78
|
)
|
74
79
|
from prefect.utilities.slugify import slugify
|
75
80
|
|
@@ -356,6 +361,7 @@ class RunnerDeployment(BaseModel):
|
|
356
361
|
cron: Optional[str] = None,
|
357
362
|
rrule: Optional[str] = None,
|
358
363
|
schedule: Optional[SCHEDULE_TYPES] = None,
|
364
|
+
is_schedule_active: Optional[bool] = None,
|
359
365
|
parameters: Optional[dict] = None,
|
360
366
|
triggers: Optional[List[DeploymentTrigger]] = None,
|
361
367
|
description: Optional[str] = None,
|
@@ -378,6 +384,9 @@ class RunnerDeployment(BaseModel):
|
|
378
384
|
rrule: An rrule schedule of when to execute runs of this flow.
|
379
385
|
schedule: A schedule object of when to execute runs of this flow. Used for
|
380
386
|
advanced scheduling options like timezone.
|
387
|
+
is_schedule_active: Whether or not to set the schedule for this deployment as active. If
|
388
|
+
not provided when creating a deployment, the schedule will be set as active. If not
|
389
|
+
provided when updating a deployment, the schedule's activation will not be changed.
|
381
390
|
triggers: A list of triggers that should kick of a run of this flow.
|
382
391
|
parameters: A dictionary of default parameter values to pass to runs of this flow.
|
383
392
|
description: A description for the created deployment. Defaults to the flow's
|
@@ -404,6 +413,7 @@ class RunnerDeployment(BaseModel):
|
|
404
413
|
name=Path(name).stem,
|
405
414
|
flow_name=flow.name,
|
406
415
|
schedule=schedule,
|
416
|
+
is_schedule_active=is_schedule_active,
|
407
417
|
tags=tags or [],
|
408
418
|
triggers=triggers or [],
|
409
419
|
parameters=parameters or {},
|
@@ -461,6 +471,7 @@ class RunnerDeployment(BaseModel):
|
|
461
471
|
cron: Optional[str] = None,
|
462
472
|
rrule: Optional[str] = None,
|
463
473
|
schedule: Optional[SCHEDULE_TYPES] = None,
|
474
|
+
is_schedule_active: Optional[bool] = None,
|
464
475
|
parameters: Optional[dict] = None,
|
465
476
|
triggers: Optional[List[DeploymentTrigger]] = None,
|
466
477
|
description: Optional[str] = None,
|
@@ -484,6 +495,9 @@ class RunnerDeployment(BaseModel):
|
|
484
495
|
rrule: An rrule schedule of when to execute runs of this flow.
|
485
496
|
schedule: A schedule object of when to execute runs of this flow. Used for
|
486
497
|
advanced scheduling options like timezone.
|
498
|
+
is_schedule_active: Whether or not to set the schedule for this deployment as active. If
|
499
|
+
not provided when creating a deployment, the schedule will be set as active. If not
|
500
|
+
provided when updating a deployment, the schedule's activation will not be changed.
|
487
501
|
triggers: A list of triggers that should kick of a run of this flow.
|
488
502
|
parameters: A dictionary of default parameter values to pass to runs of this flow.
|
489
503
|
description: A description for the created deployment. Defaults to the flow's
|
@@ -516,6 +530,7 @@ class RunnerDeployment(BaseModel):
|
|
516
530
|
name=Path(name).stem,
|
517
531
|
flow_name=flow.name,
|
518
532
|
schedule=schedule,
|
533
|
+
is_schedule_active=is_schedule_active,
|
519
534
|
tags=tags or [],
|
520
535
|
triggers=triggers or [],
|
521
536
|
parameters=parameters or {},
|
@@ -544,6 +559,7 @@ class RunnerDeployment(BaseModel):
|
|
544
559
|
cron: Optional[str] = None,
|
545
560
|
rrule: Optional[str] = None,
|
546
561
|
schedule: Optional[SCHEDULE_TYPES] = None,
|
562
|
+
is_schedule_active: Optional[bool] = None,
|
547
563
|
parameters: Optional[dict] = None,
|
548
564
|
triggers: Optional[List[DeploymentTrigger]] = None,
|
549
565
|
description: Optional[str] = None,
|
@@ -570,6 +586,9 @@ class RunnerDeployment(BaseModel):
|
|
570
586
|
rrule: An rrule schedule of when to execute runs of this flow.
|
571
587
|
schedule: A schedule object of when to execute runs of this flow. Used for
|
572
588
|
advanced scheduling options like timezone.
|
589
|
+
is_schedule_active: Whether or not to set the schedule for this deployment as active. If
|
590
|
+
not provided when creating a deployment, the schedule will be set as active. If not
|
591
|
+
provided when updating a deployment, the schedule's activation will not be changed.
|
573
592
|
triggers: A list of triggers that should kick of a run of this flow.
|
574
593
|
parameters: A dictionary of default parameter values to pass to runs of this flow.
|
575
594
|
description: A description for the created deployment. Defaults to the flow's
|
@@ -606,6 +625,7 @@ class RunnerDeployment(BaseModel):
|
|
606
625
|
name=Path(name).stem,
|
607
626
|
flow_name=flow.name,
|
608
627
|
schedule=schedule,
|
628
|
+
is_schedule_active=is_schedule_active,
|
609
629
|
tags=tags or [],
|
610
630
|
triggers=triggers or [],
|
611
631
|
parameters=parameters or {},
|
@@ -650,7 +670,14 @@ class DeploymentImage:
|
|
650
670
|
f"Only one tag can be provided - both {image_tag!r} and {tag!r} were"
|
651
671
|
" provided as tags."
|
652
672
|
)
|
653
|
-
|
673
|
+
namespace, repository = split_repository_path(image_name)
|
674
|
+
# if the provided image name does not include a namespace (registry URL or user/org name),
|
675
|
+
# use the default namespace
|
676
|
+
if not namespace:
|
677
|
+
namespace = PREFECT_DEFAULT_DOCKER_BUILD_NAMESPACE.value()
|
678
|
+
# join the namespace and repository to create the full image name
|
679
|
+
# ignore namespace if it is None
|
680
|
+
self.name = "/".join(filter(None, [namespace, repository]))
|
654
681
|
self.tag = tag or image_tag or slugify(pendulum.now("utc").isoformat())
|
655
682
|
self.dockerfile = dockerfile
|
656
683
|
self.build_kwargs = build_kwargs
|
@@ -100,8 +100,10 @@ from typing import (
|
|
100
100
|
List,
|
101
101
|
Optional,
|
102
102
|
Set,
|
103
|
+
Type,
|
103
104
|
TypeVar,
|
104
105
|
Union,
|
106
|
+
overload,
|
105
107
|
)
|
106
108
|
from uuid import UUID, uuid4
|
107
109
|
|
@@ -114,6 +116,7 @@ import prefect
|
|
114
116
|
import prefect.context
|
115
117
|
import prefect.plugins
|
116
118
|
from prefect._internal.compatibility.deprecated import deprecated_parameter
|
119
|
+
from prefect._internal.compatibility.experimental import experimental_parameter
|
117
120
|
from prefect._internal.concurrency.api import create_call, from_async, from_sync
|
118
121
|
from prefect._internal.concurrency.calls import get_current_call
|
119
122
|
from prefect._internal.concurrency.cancellation import CancelledError, get_deadline
|
@@ -152,6 +155,7 @@ from prefect.exceptions import (
|
|
152
155
|
)
|
153
156
|
from prefect.flows import Flow
|
154
157
|
from prefect.futures import PrefectFuture, call_repr, resolve_futures_to_states
|
158
|
+
from prefect.input import RunInput, keyset_from_paused_state
|
155
159
|
from prefect.logging.configuration import setup_logging
|
156
160
|
from prefect.logging.handlers import APILogHandler
|
157
161
|
from prefect.logging.loggers import (
|
@@ -204,6 +208,7 @@ from prefect.utilities.pydantic import PartialModel
|
|
204
208
|
from prefect.utilities.text import truncated_to
|
205
209
|
|
206
210
|
R = TypeVar("R")
|
211
|
+
T = TypeVar("T", bound=RunInput)
|
207
212
|
EngineReturnType = Literal["future", "state", "result"]
|
208
213
|
|
209
214
|
|
@@ -943,6 +948,30 @@ async def orchestrate_flow_run(
|
|
943
948
|
return state
|
944
949
|
|
945
950
|
|
951
|
+
@overload
|
952
|
+
async def pause_flow_run(
|
953
|
+
wait_for_input: None = None,
|
954
|
+
flow_run_id: UUID = None,
|
955
|
+
timeout: int = 300,
|
956
|
+
poll_interval: int = 10,
|
957
|
+
reschedule: bool = False,
|
958
|
+
key: str = None,
|
959
|
+
) -> None:
|
960
|
+
...
|
961
|
+
|
962
|
+
|
963
|
+
@overload
|
964
|
+
async def pause_flow_run(
|
965
|
+
wait_for_input: Type[T],
|
966
|
+
flow_run_id: UUID = None,
|
967
|
+
timeout: int = 300,
|
968
|
+
poll_interval: int = 10,
|
969
|
+
reschedule: bool = False,
|
970
|
+
key: str = None,
|
971
|
+
) -> T:
|
972
|
+
...
|
973
|
+
|
974
|
+
|
946
975
|
@sync_compatible
|
947
976
|
@deprecated_parameter(
|
948
977
|
"flow_run_id", start_date="Dec 2023", help="Use `suspend_flow_run` instead."
|
@@ -953,7 +982,11 @@ async def orchestrate_flow_run(
|
|
953
982
|
when=lambda p: p is True,
|
954
983
|
help="Use `suspend_flow_run` instead.",
|
955
984
|
)
|
985
|
+
@experimental_parameter(
|
986
|
+
"wait_for_input", group="flow_run_input", when=lambda y: y is not None
|
987
|
+
)
|
956
988
|
async def pause_flow_run(
|
989
|
+
wait_for_input: Optional[Type[T]] = None,
|
957
990
|
flow_run_id: UUID = None,
|
958
991
|
timeout: int = 300,
|
959
992
|
poll_interval: int = 10,
|
@@ -990,8 +1023,16 @@ async def pause_flow_run(
|
|
990
1023
|
the number of pauses observed by the flow so far, and prevents pauses that
|
991
1024
|
use the "reschedule" option from running the same pause twice. A custom key
|
992
1025
|
can be supplied for custom pausing behavior.
|
1026
|
+
wait_for_input: a subclass of `RunInput`. If provided when the flow pauses, the
|
1027
|
+
flow will wait for the input to be provided before resuming. If the flow is
|
1028
|
+
resumed without providing the input, the flow will fail. If the flow is
|
1029
|
+
resumed with the input, the flow will resume and the input will be loaded
|
1030
|
+
and returned from this function.
|
993
1031
|
"""
|
994
1032
|
if flow_run_id:
|
1033
|
+
if wait_for_input is not None:
|
1034
|
+
raise RuntimeError("Cannot wait for input when pausing out of process.")
|
1035
|
+
|
995
1036
|
return await _out_of_process_pause(
|
996
1037
|
flow_run_id=flow_run_id,
|
997
1038
|
timeout=timeout,
|
@@ -1000,18 +1041,26 @@ async def pause_flow_run(
|
|
1000
1041
|
)
|
1001
1042
|
else:
|
1002
1043
|
return await _in_process_pause(
|
1003
|
-
timeout=timeout,
|
1044
|
+
timeout=timeout,
|
1045
|
+
poll_interval=poll_interval,
|
1046
|
+
reschedule=reschedule,
|
1047
|
+
key=key,
|
1048
|
+
wait_for_input=wait_for_input,
|
1004
1049
|
)
|
1005
1050
|
|
1006
1051
|
|
1007
1052
|
@inject_client
|
1053
|
+
@experimental_parameter(
|
1054
|
+
"wait_for_input", group="flow_run_input", when=lambda y: y is not None
|
1055
|
+
)
|
1008
1056
|
async def _in_process_pause(
|
1009
1057
|
timeout: int = 300,
|
1010
1058
|
poll_interval: int = 10,
|
1011
1059
|
reschedule=False,
|
1012
1060
|
key: str = None,
|
1013
1061
|
client=None,
|
1014
|
-
|
1062
|
+
wait_for_input: Optional[Type[RunInput]] = None,
|
1063
|
+
) -> Optional[RunInput]:
|
1015
1064
|
if TaskRunContext.get():
|
1016
1065
|
raise RuntimeError("Cannot pause task runs.")
|
1017
1066
|
|
@@ -1026,12 +1075,18 @@ async def _in_process_pause(
|
|
1026
1075
|
|
1027
1076
|
logger.info("Pausing flow, execution will continue when this flow run is resumed.")
|
1028
1077
|
|
1078
|
+
proposed_state = Paused(
|
1079
|
+
timeout_seconds=timeout, reschedule=reschedule, pause_key=pause_key
|
1080
|
+
)
|
1081
|
+
|
1082
|
+
if wait_for_input:
|
1083
|
+
run_input_keyset = keyset_from_paused_state(proposed_state)
|
1084
|
+
proposed_state.state_details.run_input_keyset = run_input_keyset
|
1085
|
+
|
1029
1086
|
try:
|
1030
1087
|
state = await propose_state(
|
1031
1088
|
client=client,
|
1032
|
-
state=
|
1033
|
-
timeout_seconds=timeout, reschedule=reschedule, pause_key=pause_key
|
1034
|
-
),
|
1089
|
+
state=proposed_state,
|
1035
1090
|
flow_run_id=context.flow_run.id,
|
1036
1091
|
)
|
1037
1092
|
except Abort as exc:
|
@@ -1039,7 +1094,14 @@ async def _in_process_pause(
|
|
1039
1094
|
raise RuntimeError(f"Flow run cannot be paused: {exc}")
|
1040
1095
|
|
1041
1096
|
if state.is_running():
|
1042
|
-
# The orchestrator
|
1097
|
+
# The orchestrator rejected the paused state which means that this
|
1098
|
+
# pause has happened before (via reschedule) and the flow run has
|
1099
|
+
# been resumed.
|
1100
|
+
if wait_for_input:
|
1101
|
+
# The flow run wanted input, so we need to load it and return it
|
1102
|
+
# to the user.
|
1103
|
+
await wait_for_input.load(run_input_keyset)
|
1104
|
+
|
1043
1105
|
return
|
1044
1106
|
|
1045
1107
|
if not state.is_paused():
|
@@ -1048,6 +1110,13 @@ async def _in_process_pause(
|
|
1048
1110
|
f"Flow run cannot be paused. Received non-paused state from API: {state}"
|
1049
1111
|
)
|
1050
1112
|
|
1113
|
+
if wait_for_input:
|
1114
|
+
# We're now in a paused state and the flow run is waiting for input.
|
1115
|
+
# Save the schema of the users `RunInput` subclass, stored in
|
1116
|
+
# `wait_for_input`, so the UI can display the form and we can validate
|
1117
|
+
# the input when the flow is resumed.
|
1118
|
+
await wait_for_input.save(run_input_keyset)
|
1119
|
+
|
1051
1120
|
if reschedule:
|
1052
1121
|
# If a rescheduled pause, exit this process so the run can be resubmitted later
|
1053
1122
|
raise Pause(state=state)
|
@@ -1057,22 +1126,21 @@ async def _in_process_pause(
|
|
1057
1126
|
# attempt to check if a flow has resumed at least once
|
1058
1127
|
initial_sleep = min(timeout / 2, poll_interval)
|
1059
1128
|
await anyio.sleep(initial_sleep)
|
1060
|
-
flow_run = await client.read_flow_run(context.flow_run.id)
|
1061
|
-
if flow_run.state.is_running():
|
1062
|
-
logger.info("Resuming flow run execution!")
|
1063
|
-
return
|
1064
|
-
|
1065
1129
|
while True:
|
1066
|
-
await anyio.sleep(poll_interval)
|
1067
1130
|
flow_run = await client.read_flow_run(context.flow_run.id)
|
1068
1131
|
if flow_run.state.is_running():
|
1069
1132
|
logger.info("Resuming flow run execution!")
|
1133
|
+
if wait_for_input:
|
1134
|
+
return await wait_for_input.load(run_input_keyset)
|
1070
1135
|
return
|
1136
|
+
await anyio.sleep(poll_interval)
|
1071
1137
|
|
1072
1138
|
# check one last time before failing the flow
|
1073
1139
|
flow_run = await client.read_flow_run(context.flow_run.id)
|
1074
1140
|
if flow_run.state.is_running():
|
1075
1141
|
logger.info("Resuming flow run execution!")
|
1142
|
+
if wait_for_input:
|
1143
|
+
return await wait_for_input.load(run_input_keyset)
|
1076
1144
|
return
|
1077
1145
|
|
1078
1146
|
raise FlowPauseTimeout("Flow run was paused and never resumed.")
|
@@ -1100,9 +1168,32 @@ async def _out_of_process_pause(
|
|
1100
1168
|
raise RuntimeError(response.details.reason)
|
1101
1169
|
|
1102
1170
|
|
1171
|
+
@overload
|
1172
|
+
async def suspend_flow_run(
|
1173
|
+
wait_for_input: None = None,
|
1174
|
+
flow_run_id: Optional[UUID] = None,
|
1175
|
+
timeout: Optional[int] = 300,
|
1176
|
+
key: Optional[str] = None,
|
1177
|
+
client: PrefectClient = None,
|
1178
|
+
) -> None:
|
1179
|
+
...
|
1180
|
+
|
1181
|
+
|
1182
|
+
@overload
|
1183
|
+
async def suspend_flow_run(
|
1184
|
+
wait_for_input: Type[T],
|
1185
|
+
flow_run_id: Optional[UUID] = None,
|
1186
|
+
timeout: Optional[int] = 300,
|
1187
|
+
key: Optional[str] = None,
|
1188
|
+
client: PrefectClient = None,
|
1189
|
+
) -> T:
|
1190
|
+
...
|
1191
|
+
|
1192
|
+
|
1103
1193
|
@sync_compatible
|
1104
1194
|
@inject_client
|
1105
1195
|
async def suspend_flow_run(
|
1196
|
+
wait_for_input: Optional[Type[T]] = None,
|
1106
1197
|
flow_run_id: Optional[UUID] = None,
|
1107
1198
|
timeout: Optional[int] = 300,
|
1108
1199
|
key: Optional[str] = None,
|
@@ -1130,6 +1221,12 @@ async def suspend_flow_run(
|
|
1130
1221
|
defaults to a random string and prevents suspends from running the
|
1131
1222
|
same suspend twice. A custom key can be supplied for custom
|
1132
1223
|
suspending behavior.
|
1224
|
+
wait_for_input: a subclass of `RunInput`. If provided when the flow
|
1225
|
+
suspends, the flow will wait for the input to be provided before
|
1226
|
+
resuming. If the flow is resumed without providing the input, the
|
1227
|
+
flow will fail. If the flow is resumed with the input, the flow
|
1228
|
+
will resume and the input will be loaded and returned from this
|
1229
|
+
function.
|
1133
1230
|
"""
|
1134
1231
|
context = FlowRunContext.get()
|
1135
1232
|
|
@@ -1159,10 +1256,16 @@ async def suspend_flow_run(
|
|
1159
1256
|
suspending_current_flow_run = False
|
1160
1257
|
pause_key = key or str(uuid4())
|
1161
1258
|
|
1259
|
+
proposed_state = Suspended(timeout_seconds=timeout, pause_key=pause_key)
|
1260
|
+
|
1261
|
+
if wait_for_input:
|
1262
|
+
run_input_keyset = keyset_from_paused_state(proposed_state)
|
1263
|
+
proposed_state.state_details.run_input_keyset = run_input_keyset
|
1264
|
+
|
1162
1265
|
try:
|
1163
1266
|
state = await propose_state(
|
1164
1267
|
client=client,
|
1165
|
-
state=
|
1268
|
+
state=proposed_state,
|
1166
1269
|
flow_run_id=flow_run_id,
|
1167
1270
|
)
|
1168
1271
|
except Abort as exc:
|
@@ -1170,7 +1273,12 @@ async def suspend_flow_run(
|
|
1170
1273
|
raise RuntimeError(f"Flow run cannot be suspended: {exc}")
|
1171
1274
|
|
1172
1275
|
if state.is_running():
|
1173
|
-
# The orchestrator
|
1276
|
+
# The orchestrator rejected the suspended state which means that this
|
1277
|
+
# suspend has happened before and the flow run has been resumed.
|
1278
|
+
if wait_for_input:
|
1279
|
+
# The flow run wanted input, so we need to load it and return it
|
1280
|
+
# to the user.
|
1281
|
+
return await wait_for_input.load(run_input_keyset)
|
1174
1282
|
return
|
1175
1283
|
|
1176
1284
|
if not state.is_paused():
|
@@ -1179,18 +1287,22 @@ async def suspend_flow_run(
|
|
1179
1287
|
f"Flow run cannot be suspended. Received unexpected state from API: {state}"
|
1180
1288
|
)
|
1181
1289
|
|
1290
|
+
if wait_for_input:
|
1291
|
+
await wait_for_input.save(run_input_keyset)
|
1292
|
+
|
1182
1293
|
if suspending_current_flow_run:
|
1183
1294
|
# Exit this process so the run can be resubmitted later
|
1184
1295
|
raise Pause()
|
1185
1296
|
|
1186
1297
|
|
1187
1298
|
@sync_compatible
|
1188
|
-
async def resume_flow_run(flow_run_id):
|
1299
|
+
async def resume_flow_run(flow_run_id, run_input: Optional[Dict] = None):
|
1189
1300
|
"""
|
1190
1301
|
Resumes a paused flow.
|
1191
1302
|
|
1192
1303
|
Args:
|
1193
1304
|
flow_run_id: the flow_run_id to resume
|
1305
|
+
run_input: a dictionary of inputs to provide to the flow run.
|
1194
1306
|
"""
|
1195
1307
|
client = get_client()
|
1196
1308
|
flow_run = await client.read_flow_run(flow_run_id)
|
@@ -1198,7 +1310,7 @@ async def resume_flow_run(flow_run_id):
|
|
1198
1310
|
if not flow_run.state.is_paused():
|
1199
1311
|
raise NotPausedError("Cannot resume a run that isn't paused!")
|
1200
1312
|
|
1201
|
-
response = await client.resume_flow_run(flow_run_id)
|
1313
|
+
response = await client.resume_flow_run(flow_run_id, run_input=run_input)
|
1202
1314
|
|
1203
1315
|
if response.status == SetStateStatus.REJECT:
|
1204
1316
|
if response.state.type == StateType.FAILED:
|
@@ -556,6 +556,7 @@ class Flow(Generic[P, R]):
|
|
556
556
|
cron: Optional[str] = None,
|
557
557
|
rrule: Optional[str] = None,
|
558
558
|
schedule: Optional[SCHEDULE_TYPES] = None,
|
559
|
+
is_schedule_active: Optional[bool] = None,
|
559
560
|
parameters: Optional[dict] = None,
|
560
561
|
triggers: Optional[List[DeploymentTrigger]] = None,
|
561
562
|
description: Optional[str] = None,
|
@@ -578,6 +579,9 @@ class Flow(Generic[P, R]):
|
|
578
579
|
timezone: A timezone to use for the schedule. Defaults to UTC.
|
579
580
|
triggers: A list of triggers that will kick off runs of this deployment.
|
580
581
|
schedule: A schedule object defining when to execute runs of this deployment.
|
582
|
+
is_schedule_active: Whether or not to set the schedule for this deployment as active. If
|
583
|
+
not provided when creating a deployment, the schedule will be set as active. If not
|
584
|
+
provided when updating a deployment, the schedule's activation will not be changed.
|
581
585
|
parameters: A dictionary of default parameter values to pass to runs of this deployment.
|
582
586
|
description: A description for the created deployment. Defaults to the flow's
|
583
587
|
description if not provided.
|
@@ -623,6 +627,7 @@ class Flow(Generic[P, R]):
|
|
623
627
|
cron=cron,
|
624
628
|
rrule=rrule,
|
625
629
|
schedule=schedule,
|
630
|
+
is_schedule_active=is_schedule_active,
|
626
631
|
tags=tags,
|
627
632
|
triggers=triggers,
|
628
633
|
parameters=parameters or {},
|
@@ -641,6 +646,7 @@ class Flow(Generic[P, R]):
|
|
641
646
|
cron=cron,
|
642
647
|
rrule=rrule,
|
643
648
|
schedule=schedule,
|
649
|
+
is_schedule_active=is_schedule_active,
|
644
650
|
tags=tags,
|
645
651
|
triggers=triggers,
|
646
652
|
parameters=parameters or {},
|
@@ -660,6 +666,7 @@ class Flow(Generic[P, R]):
|
|
660
666
|
cron: Optional[str] = None,
|
661
667
|
rrule: Optional[str] = None,
|
662
668
|
schedule: Optional[SCHEDULE_TYPES] = None,
|
669
|
+
is_schedule_active: Optional[bool] = None,
|
663
670
|
triggers: Optional[List[DeploymentTrigger]] = None,
|
664
671
|
parameters: Optional[dict] = None,
|
665
672
|
description: Optional[str] = None,
|
@@ -682,6 +689,9 @@ class Flow(Generic[P, R]):
|
|
682
689
|
triggers: A list of triggers that will kick off runs of this deployment.
|
683
690
|
schedule: A schedule object defining when to execute runs of this deployment. Used to
|
684
691
|
define additional scheduling options like `timezone`.
|
692
|
+
is_schedule_active: Whether or not to set the schedule for this deployment as active. If
|
693
|
+
not provided when creating a deployment, the schedule will be set as active. If not
|
694
|
+
provided when updating a deployment, the schedule's activation will not be changed.
|
685
695
|
parameters: A dictionary of default parameter values to pass to runs of this deployment.
|
686
696
|
description: A description for the created deployment. Defaults to the flow's
|
687
697
|
description if not provided.
|
@@ -738,6 +748,7 @@ class Flow(Generic[P, R]):
|
|
738
748
|
cron=cron,
|
739
749
|
rrule=rrule,
|
740
750
|
schedule=schedule,
|
751
|
+
is_schedule_active=is_schedule_active,
|
741
752
|
parameters=parameters,
|
742
753
|
description=description,
|
743
754
|
tags=tags,
|
@@ -852,6 +863,7 @@ class Flow(Generic[P, R]):
|
|
852
863
|
cron: Optional[str] = None,
|
853
864
|
rrule: Optional[str] = None,
|
854
865
|
schedule: Optional[SCHEDULE_TYPES] = None,
|
866
|
+
is_schedule_active: Optional[bool] = None,
|
855
867
|
triggers: Optional[List[DeploymentTrigger]] = None,
|
856
868
|
parameters: Optional[dict] = None,
|
857
869
|
description: Optional[str] = None,
|
@@ -891,6 +903,9 @@ class Flow(Generic[P, R]):
|
|
891
903
|
triggers: A list of triggers that will kick off runs of this deployment.
|
892
904
|
schedule: A schedule object defining when to execute runs of this deployment. Used to
|
893
905
|
define additional scheduling options like `timezone`.
|
906
|
+
is_schedule_active: Whether or not to set the schedule for this deployment as active. If
|
907
|
+
not provided when creating a deployment, the schedule will be set as active. If not
|
908
|
+
provided when updating a deployment, the schedule's activation will not be changed.
|
894
909
|
parameters: A dictionary of default parameter values to pass to runs of this deployment.
|
895
910
|
description: A description for the created deployment. Defaults to the flow's
|
896
911
|
description if not provided.
|
@@ -956,6 +971,7 @@ class Flow(Generic[P, R]):
|
|
956
971
|
cron=cron,
|
957
972
|
rrule=rrule,
|
958
973
|
schedule=schedule,
|
974
|
+
is_schedule_active=is_schedule_active,
|
959
975
|
triggers=triggers,
|
960
976
|
parameters=parameters,
|
961
977
|
description=description,
|