prefect-client 3.1.1__tar.gz → 3.1.3__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.1.1/src/prefect_client.egg-info → prefect-client-3.1.3}/PKG-INFO +1 -1
- {prefect-client-3.1.1 → prefect-client-3.1.3}/requirements-client.txt +2 -1
- {prefect-client-3.1.1 → prefect-client-3.1.3}/requirements.txt +0 -1
- prefect-client-3.1.3/src/prefect/_internal/compatibility/async_dispatch.py +63 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_version.py +3 -3
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/blocks/notifications.py +1 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/cache_policies.py +13 -2
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/client/cloud.py +21 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/client/orchestration.py +1 -1
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/client/schemas/objects.py +13 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/events/filters.py +13 -9
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/exceptions.py +4 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/flow_engine.py +56 -1
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/logging/handlers.py +5 -4
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/base.py +22 -3
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/experiments.py +0 -5
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/sources.py +79 -8
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/states.py +5 -2
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/telemetry/processors.py +2 -2
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/filesystem.py +35 -8
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/hashing.py +28 -7
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/urls.py +17 -2
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/workers/base.py +65 -27
- {prefect-client-3.1.1 → prefect-client-3.1.3/src/prefect_client.egg-info}/PKG-INFO +1 -1
- prefect-client-3.1.3/src/prefect_client.egg-info/dependency_links.txt +1 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect_client.egg-info/requires.txt +2 -1
- prefect-client-3.1.1/src/prefect/_internal/compatibility/async_dispatch.py +0 -73
- prefect-client-3.1.1/src/prefect/utilities/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/LICENSE +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/MANIFEST.in +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/README.md +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/requirements-dev.txt +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/setup.cfg +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/setup.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/.prefectignore +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/_logging.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/compatibility/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/compatibility/deprecated.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/compatibility/migration.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/concurrency/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/concurrency/api.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/concurrency/calls.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/concurrency/cancellation.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/concurrency/event_loop.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/concurrency/inspection.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/concurrency/primitives.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/concurrency/services.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/concurrency/threads.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/concurrency/waiters.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/integrations.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/pydantic/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/pydantic/annotations/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/pydantic/annotations/pendulum.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/pydantic/schemas.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/pydantic/v1_schema.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/pydantic/v2_schema.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/pydantic/v2_validated_func.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/pytz.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/retries.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/schemas/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/schemas/bases.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/schemas/fields.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/schemas/serializers.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/_internal/schemas/validators.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/agent.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/artifacts.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/automations.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/blocks/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/blocks/abstract.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/blocks/core.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/blocks/fields.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/blocks/redis.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/blocks/system.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/blocks/webhook.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/client/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/client/base.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/client/collections.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/client/constants.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/client/schemas/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/client/schemas/actions.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/client/schemas/filters.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/client/schemas/responses.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/client/schemas/schedules.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/client/schemas/sorting.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/client/subscriptions.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/client/types/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/client/types/flexible_schedule_list.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/client/utilities.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/concurrency/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/concurrency/asyncio.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/concurrency/context.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/concurrency/events.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/concurrency/services.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/concurrency/sync.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/concurrency/v1/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/concurrency/v1/asyncio.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/concurrency/v1/context.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/concurrency/v1/events.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/concurrency/v1/services.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/concurrency/v1/sync.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/context.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/deployments/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/deployments/base.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/deployments/deployments.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/deployments/flow_runs.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/deployments/runner.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/deployments/schedules.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/deployments/steps/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/deployments/steps/core.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/deployments/steps/pull.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/deployments/steps/utility.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/docker/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/docker/docker_image.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/engine.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/events/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/events/actions.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/events/cli/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/events/cli/automations.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/events/clients.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/events/related.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/events/schemas/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/events/schemas/automations.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/events/schemas/deployment_triggers.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/events/schemas/events.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/events/schemas/labelling.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/events/utilities.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/events/worker.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/filesystems.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/flow_runs.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/flows.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/futures.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/infrastructure/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/infrastructure/base.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/infrastructure/provisioners/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/infrastructure/provisioners/cloud_run.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/infrastructure/provisioners/container_instance.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/infrastructure/provisioners/ecs.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/infrastructure/provisioners/modal.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/input/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/input/actions.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/input/run_input.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/locking/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/locking/filesystem.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/locking/memory.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/locking/protocol.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/logging/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/logging/configuration.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/logging/filters.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/logging/formatters.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/logging/highlighters.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/logging/loggers.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/logging/logging.yml +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/main.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/plugins.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/py.typed +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/records/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/records/base.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/records/filesystem.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/records/memory.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/records/result_store.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/results.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/runner/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/runner/runner.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/runner/server.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/runner/storage.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/runner/submit.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/runner/utils.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/runtime/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/runtime/deployment.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/runtime/flow_run.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/runtime/task_run.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/serializers.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/server/api/collections_data/views/aggregate-worker-metadata.json +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/server/api/static/prefect-logo-mark-gradient.png +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/constants.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/context.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/legacy.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/api.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/cli.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/client.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/cloud.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/deployments.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/flows.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/internal.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/logging.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/results.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/root.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/runner.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/server/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/server/api.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/server/database.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/server/deployments.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/server/ephemeral.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/server/events.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/server/flow_run_graph.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/server/root.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/server/services.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/server/tasks.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/server/ui.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/tasks.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/testing.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/models/worker.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/profiles.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/settings/profiles.toml +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/task_engine.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/task_runners.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/task_runs.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/task_worker.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/tasks.py +0 -0
- /prefect-client-3.1.1/src/prefect_client.egg-info/dependency_links.txt → /prefect-client-3.1.3/src/prefect/telemetry/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/telemetry/bootstrap.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/telemetry/instrumentation.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/telemetry/logging.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/transactions.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/types/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/types/entrypoint.py +0 -0
- {prefect-client-3.1.1/src/prefect/telemetry → prefect-client-3.1.3/src/prefect/utilities}/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/annotations.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/asyncutils.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/callables.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/collections.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/compat.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/context.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/dispatch.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/dockerutils.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/engine.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/importtools.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/math.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/names.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/processutils.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/pydantic.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/render_swagger.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/schema_tools/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/schema_tools/hydration.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/schema_tools/validation.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/services.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/slugify.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/templating.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/text.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/timeout.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/utilities/visualization.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/variables.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/workers/__init__.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/workers/block.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/workers/cloud.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/workers/process.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/workers/server.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect/workers/utilities.py +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect_client.egg-info/SOURCES.txt +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/src/prefect_client.egg-info/top_level.txt +0 -0
- {prefect-client-3.1.1 → prefect-client-3.1.3}/versioneer.py +0 -0
@@ -3,7 +3,7 @@ asgi-lifespan >= 1.0, < 3.0
|
|
3
3
|
cachetools >= 5.3, < 6.0
|
4
4
|
cloudpickle >= 2.0, < 4.0
|
5
5
|
coolname >= 1.0.4, < 3.0.0
|
6
|
-
croniter >= 1.0.12, <
|
6
|
+
croniter >= 1.0.12, < 6.0.0
|
7
7
|
exceptiongroup >= 1.0.0
|
8
8
|
fastapi >= 0.111.0, < 1.0.0
|
9
9
|
fsspec >= 2022.5.0
|
@@ -14,6 +14,7 @@ httpx[http2] >= 0.23, != 0.23.2
|
|
14
14
|
importlib_metadata >= 4.4; python_version < '3.10'
|
15
15
|
jsonpatch >= 1.32, < 2.0
|
16
16
|
jsonschema >= 4.0.0, < 5.0.0
|
17
|
+
opentelemetry-api >= 1.27.0, < 2.0.0
|
17
18
|
orjson >= 3.7, < 4.0
|
18
19
|
packaging >= 21.3, < 24.3
|
19
20
|
pathspec >= 0.8.0
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import asyncio
|
2
|
+
import inspect
|
3
|
+
from functools import wraps
|
4
|
+
from typing import Any, Callable, Coroutine, Optional, TypeVar, Union
|
5
|
+
|
6
|
+
from typing_extensions import ParamSpec
|
7
|
+
|
8
|
+
from prefect.tasks import Task
|
9
|
+
|
10
|
+
R = TypeVar("R")
|
11
|
+
P = ParamSpec("P")
|
12
|
+
|
13
|
+
|
14
|
+
def is_in_async_context() -> bool:
|
15
|
+
"""
|
16
|
+
Returns True if called from within an async context (coroutine or running event loop)
|
17
|
+
"""
|
18
|
+
try:
|
19
|
+
asyncio.get_running_loop()
|
20
|
+
return True
|
21
|
+
except RuntimeError:
|
22
|
+
return False
|
23
|
+
|
24
|
+
|
25
|
+
def _is_acceptable_callable(obj: Union[Callable, Task]) -> bool:
|
26
|
+
if inspect.iscoroutinefunction(obj):
|
27
|
+
return True
|
28
|
+
if isinstance(obj, Task) and inspect.iscoroutinefunction(obj.fn):
|
29
|
+
return True
|
30
|
+
return False
|
31
|
+
|
32
|
+
|
33
|
+
def async_dispatch(
|
34
|
+
async_impl: Callable[P, Coroutine[Any, Any, R]],
|
35
|
+
) -> Callable[[Callable[P, R]], Callable[P, Union[R, Coroutine[Any, Any, R]]]]:
|
36
|
+
"""
|
37
|
+
Decorator that dispatches to either sync or async implementation based on context.
|
38
|
+
|
39
|
+
Args:
|
40
|
+
async_impl: The async implementation to dispatch to when in async context
|
41
|
+
"""
|
42
|
+
|
43
|
+
def decorator(
|
44
|
+
sync_fn: Callable[P, R],
|
45
|
+
) -> Callable[P, Union[R, Coroutine[Any, Any, R]]]:
|
46
|
+
if not _is_acceptable_callable(async_impl):
|
47
|
+
raise TypeError("async_impl must be an async function")
|
48
|
+
|
49
|
+
@wraps(sync_fn)
|
50
|
+
def wrapper(
|
51
|
+
*args: P.args,
|
52
|
+
_sync: Optional[bool] = None, # type: ignore
|
53
|
+
**kwargs: P.kwargs,
|
54
|
+
) -> Union[R, Coroutine[Any, Any, R]]:
|
55
|
+
should_run_sync = _sync if _sync is not None else not is_in_async_context()
|
56
|
+
|
57
|
+
if should_run_sync:
|
58
|
+
return sync_fn(*args, **kwargs)
|
59
|
+
return async_impl(*args, **kwargs)
|
60
|
+
|
61
|
+
return wrapper # type: ignore
|
62
|
+
|
63
|
+
return decorator
|
@@ -8,11 +8,11 @@ import json
|
|
8
8
|
|
9
9
|
version_json = '''
|
10
10
|
{
|
11
|
-
"date": "2024-11-
|
11
|
+
"date": "2024-11-19T15:25:34-0600",
|
12
12
|
"dirty": true,
|
13
13
|
"error": null,
|
14
|
-
"full-revisionid": "
|
15
|
-
"version": "3.1.
|
14
|
+
"full-revisionid": "39b6028cea9f2b0437546ba13cc08bb3bf6d94a4",
|
15
|
+
"version": "3.1.3"
|
16
16
|
}
|
17
17
|
''' # END VERSION_JSON
|
18
18
|
|
@@ -7,6 +7,7 @@ from typing import TYPE_CHECKING, Any, Callable, Dict, List, Literal, Optional,
|
|
7
7
|
from typing_extensions import Self
|
8
8
|
|
9
9
|
from prefect.context import TaskRunContext
|
10
|
+
from prefect.exceptions import HashError
|
10
11
|
from prefect.utilities.hashing import hash_objects
|
11
12
|
|
12
13
|
if TYPE_CHECKING:
|
@@ -223,7 +224,6 @@ class TaskSource(CachePolicy):
|
|
223
224
|
lines = task_ctx.task.fn.__code__.co_code
|
224
225
|
else:
|
225
226
|
raise
|
226
|
-
|
227
227
|
return hash_objects(lines, raise_on_failure=True)
|
228
228
|
|
229
229
|
|
@@ -293,7 +293,18 @@ class Inputs(CachePolicy):
|
|
293
293
|
if key not in exclude:
|
294
294
|
hashed_inputs[key] = val
|
295
295
|
|
296
|
-
|
296
|
+
try:
|
297
|
+
return hash_objects(hashed_inputs, raise_on_failure=True)
|
298
|
+
except HashError as exc:
|
299
|
+
msg = (
|
300
|
+
f"{exc}\n\n"
|
301
|
+
"This often occurs when task inputs contain objects that cannot be cached "
|
302
|
+
"like locks, file handles, or other system resources.\n\n"
|
303
|
+
"To resolve this, you can:\n"
|
304
|
+
" 1. Exclude these arguments by defining a custom `cache_key_fn`\n"
|
305
|
+
" 2. Disable caching by passing `cache_policy=NONE`\n"
|
306
|
+
)
|
307
|
+
raise ValueError(msg) from exc
|
297
308
|
|
298
309
|
def __sub__(self, other: str) -> "CachePolicy":
|
299
310
|
if not isinstance(other, str):
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import re
|
2
2
|
from typing import Any, Dict, List, Optional, cast
|
3
|
+
from uuid import UUID
|
3
4
|
|
4
5
|
import anyio
|
5
6
|
import httpx
|
@@ -12,6 +13,7 @@ from prefect.client.base import PrefectHttpxAsyncClient
|
|
12
13
|
from prefect.client.schemas.objects import (
|
13
14
|
IPAllowlist,
|
14
15
|
IPAllowlistMyAccessResponse,
|
16
|
+
KeyValueLabels,
|
15
17
|
Workspace,
|
16
18
|
)
|
17
19
|
from prefect.exceptions import ObjectNotFound, PrefectException
|
@@ -151,6 +153,25 @@ class CloudClient:
|
|
151
153
|
response = await self.get(f"{self.account_base_url}/ip_allowlist/my_access")
|
152
154
|
return IPAllowlistMyAccessResponse.model_validate(response)
|
153
155
|
|
156
|
+
async def update_flow_run_labels(
|
157
|
+
self, flow_run_id: UUID, labels: KeyValueLabels
|
158
|
+
) -> httpx.Response:
|
159
|
+
"""
|
160
|
+
Update the labels for a flow run.
|
161
|
+
|
162
|
+
Args:
|
163
|
+
flow_run_id: The identifier for the flow run to update.
|
164
|
+
labels: A dictionary of labels to update for the flow run.
|
165
|
+
|
166
|
+
Returns:
|
167
|
+
an `httpx.Response` object from the PATCH request
|
168
|
+
"""
|
169
|
+
|
170
|
+
return await self._client.patch(
|
171
|
+
f"{self.workspace_base_url}/flow_runs/{flow_run_id}/labels",
|
172
|
+
json=labels,
|
173
|
+
)
|
174
|
+
|
154
175
|
async def __aenter__(self):
|
155
176
|
await self._client.__aenter__()
|
156
177
|
return self
|
@@ -2613,7 +2613,7 @@ class PrefectClient:
|
|
2613
2613
|
"heartbeat_interval_seconds": heartbeat_interval_seconds,
|
2614
2614
|
}
|
2615
2615
|
if worker_metadata:
|
2616
|
-
params["
|
2616
|
+
params["metadata"] = worker_metadata.model_dump(mode="json")
|
2617
2617
|
if get_worker_id:
|
2618
2618
|
params["return_id"] = get_worker_id
|
2619
2619
|
|
@@ -23,6 +23,9 @@ from pydantic import (
|
|
23
23
|
HttpUrl,
|
24
24
|
IPvAnyNetwork,
|
25
25
|
SerializationInfo,
|
26
|
+
StrictBool,
|
27
|
+
StrictFloat,
|
28
|
+
StrictInt,
|
26
29
|
Tag,
|
27
30
|
field_validator,
|
28
31
|
model_serializer,
|
@@ -68,6 +71,8 @@ if TYPE_CHECKING:
|
|
68
71
|
|
69
72
|
R = TypeVar("R", default=Any)
|
70
73
|
|
74
|
+
KeyValueLabels = dict[str, Union[StrictBool, StrictInt, StrictFloat, str]]
|
75
|
+
|
71
76
|
|
72
77
|
DEFAULT_BLOCK_SCHEMA_VERSION = "non-versioned"
|
73
78
|
DEFAULT_AGENT_WORK_POOL_NAME = "default-agent-pool"
|
@@ -492,6 +497,9 @@ class FlowRunPolicy(PrefectBaseModel):
|
|
492
497
|
resuming: Optional[bool] = Field(
|
493
498
|
default=False, description="Indicates if this run is resuming from a pause."
|
494
499
|
)
|
500
|
+
retry_type: Optional[Literal["in_process", "reschedule"]] = Field(
|
501
|
+
default=None, description="The type of retry this run is undergoing."
|
502
|
+
)
|
495
503
|
|
496
504
|
@model_validator(mode="before")
|
497
505
|
@classmethod
|
@@ -555,6 +563,11 @@ class FlowRun(ObjectBaseModel):
|
|
555
563
|
description="A list of tags on the flow run",
|
556
564
|
examples=[["tag-1", "tag-2"]],
|
557
565
|
)
|
566
|
+
labels: KeyValueLabels = Field(
|
567
|
+
default_factory=dict,
|
568
|
+
description="Prefect Cloud: A dictionary of key-value labels. Values can be strings, numbers, or booleans.",
|
569
|
+
examples=[{"key": "value1", "key2": 42}],
|
570
|
+
)
|
558
571
|
parent_task_run_id: Optional[UUID] = Field(
|
559
572
|
default=None,
|
560
573
|
description=(
|
@@ -83,17 +83,18 @@ class EventOccurredFilter(EventDataFilter):
|
|
83
83
|
|
84
84
|
class EventNameFilter(EventDataFilter):
|
85
85
|
prefix: Optional[List[str]] = Field(
|
86
|
-
None, description="Only include events matching one of these prefixes"
|
86
|
+
default=None, description="Only include events matching one of these prefixes"
|
87
87
|
)
|
88
88
|
exclude_prefix: Optional[List[str]] = Field(
|
89
|
-
None, description="Exclude events matching one of these prefixes"
|
89
|
+
default=None, description="Exclude events matching one of these prefixes"
|
90
90
|
)
|
91
91
|
|
92
92
|
name: Optional[List[str]] = Field(
|
93
|
-
None,
|
93
|
+
default=None,
|
94
|
+
description="Only include events matching one of these names exactly",
|
94
95
|
)
|
95
96
|
exclude_name: Optional[List[str]] = Field(
|
96
|
-
None, description="Exclude events matching one of these names exactly"
|
97
|
+
default=None, description="Exclude events matching one of these names exactly"
|
97
98
|
)
|
98
99
|
|
99
100
|
def includes(self, event: Event) -> bool:
|
@@ -230,17 +231,20 @@ class EventFilter(EventDataFilter):
|
|
230
231
|
description="Filter criteria for when the events occurred",
|
231
232
|
)
|
232
233
|
event: Optional[EventNameFilter] = Field(
|
233
|
-
None,
|
234
|
+
default=None,
|
234
235
|
description="Filter criteria for the event name",
|
235
236
|
)
|
236
237
|
any_resource: Optional[EventAnyResourceFilter] = Field(
|
237
|
-
None,
|
238
|
+
default=None,
|
239
|
+
description="Filter criteria for any resource involved in the event",
|
238
240
|
)
|
239
241
|
resource: Optional[EventResourceFilter] = Field(
|
240
|
-
None,
|
242
|
+
default=None,
|
243
|
+
description="Filter criteria for the resource of the event",
|
241
244
|
)
|
242
245
|
related: Optional[EventRelatedFilter] = Field(
|
243
|
-
None,
|
246
|
+
default=None,
|
247
|
+
description="Filter criteria for the related resources of the event",
|
244
248
|
)
|
245
249
|
id: EventIDFilter = Field(
|
246
250
|
default_factory=lambda: EventIDFilter(id=[]),
|
@@ -248,6 +252,6 @@ class EventFilter(EventDataFilter):
|
|
248
252
|
)
|
249
253
|
|
250
254
|
order: EventOrder = Field(
|
251
|
-
EventOrder.DESC,
|
255
|
+
default=EventOrder.DESC,
|
252
256
|
description="The order to return filtered events",
|
253
257
|
)
|
@@ -22,8 +22,11 @@ from typing import (
|
|
22
22
|
)
|
23
23
|
from uuid import UUID
|
24
24
|
|
25
|
+
from opentelemetry import trace
|
26
|
+
from opentelemetry.trace import Tracer, get_tracer
|
25
27
|
from typing_extensions import ParamSpec
|
26
28
|
|
29
|
+
import prefect
|
27
30
|
from prefect import Task
|
28
31
|
from prefect.client.orchestration import SyncPrefectClient, get_client
|
29
32
|
from prefect.client.schemas import FlowRun, TaskRun
|
@@ -124,6 +127,10 @@ class FlowRunEngine(Generic[P, R]):
|
|
124
127
|
_client: Optional[SyncPrefectClient] = None
|
125
128
|
short_circuit: bool = False
|
126
129
|
_flow_run_name_set: bool = False
|
130
|
+
_tracer: Tracer = field(
|
131
|
+
default_factory=lambda: get_tracer("prefect", prefect.__version__)
|
132
|
+
)
|
133
|
+
_span: Optional[trace.Span] = None
|
127
134
|
|
128
135
|
def __post_init__(self):
|
129
136
|
if self.flow is None and self.flow_run_id is None:
|
@@ -233,6 +240,17 @@ class FlowRunEngine(Generic[P, R]):
|
|
233
240
|
self.flow_run.state = state # type: ignore
|
234
241
|
self.flow_run.state_name = state.name # type: ignore
|
235
242
|
self.flow_run.state_type = state.type # type: ignore
|
243
|
+
|
244
|
+
if self._span:
|
245
|
+
self._span.add_event(
|
246
|
+
state.name,
|
247
|
+
{
|
248
|
+
"prefect.state.message": state.message or "",
|
249
|
+
"prefect.state.type": state.type,
|
250
|
+
"prefect.state.name": state.name or state.type,
|
251
|
+
"prefect.state.id": str(state.id),
|
252
|
+
},
|
253
|
+
)
|
236
254
|
return state
|
237
255
|
|
238
256
|
def result(self, raise_on_failure: bool = True) -> "Union[R, State, None]":
|
@@ -281,6 +299,9 @@ class FlowRunEngine(Generic[P, R]):
|
|
281
299
|
)
|
282
300
|
self.set_state(terminal_state)
|
283
301
|
self._return_value = resolved_result
|
302
|
+
|
303
|
+
self._end_span_on_success()
|
304
|
+
|
284
305
|
return result
|
285
306
|
|
286
307
|
def handle_exception(
|
@@ -311,6 +332,9 @@ class FlowRunEngine(Generic[P, R]):
|
|
311
332
|
)
|
312
333
|
state = self.set_state(Running())
|
313
334
|
self._raised = exc
|
335
|
+
|
336
|
+
self._end_span_on_error(exc, state.message)
|
337
|
+
|
314
338
|
return state
|
315
339
|
|
316
340
|
def handle_timeout(self, exc: TimeoutError) -> None:
|
@@ -329,6 +353,8 @@ class FlowRunEngine(Generic[P, R]):
|
|
329
353
|
self.set_state(state)
|
330
354
|
self._raised = exc
|
331
355
|
|
356
|
+
self._end_span_on_error(exc, message)
|
357
|
+
|
332
358
|
def handle_crash(self, exc: BaseException) -> None:
|
333
359
|
state = run_coro_as_sync(exception_to_crashed_state(exc))
|
334
360
|
self.logger.error(f"Crash detected! {state.message}")
|
@@ -336,6 +362,23 @@ class FlowRunEngine(Generic[P, R]):
|
|
336
362
|
self.set_state(state, force=True)
|
337
363
|
self._raised = exc
|
338
364
|
|
365
|
+
self._end_span_on_error(exc, state.message)
|
366
|
+
|
367
|
+
def _end_span_on_success(self):
|
368
|
+
if not self._span:
|
369
|
+
return
|
370
|
+
self._span.set_status(trace.Status(trace.StatusCode.OK))
|
371
|
+
self._span.end(time.time_ns())
|
372
|
+
self._span = None
|
373
|
+
|
374
|
+
def _end_span_on_error(self, exc: BaseException, description: Optional[str]):
|
375
|
+
if not self._span:
|
376
|
+
return
|
377
|
+
self._span.record_exception(exc)
|
378
|
+
self._span.set_status(trace.Status(trace.StatusCode.ERROR, description))
|
379
|
+
self._span.end(time.time_ns())
|
380
|
+
self._span = None
|
381
|
+
|
339
382
|
def load_subflow_run(
|
340
383
|
self,
|
341
384
|
parent_task_run: TaskRun,
|
@@ -578,6 +621,18 @@ class FlowRunEngine(Generic[P, R]):
|
|
578
621
|
flow_version=self.flow.version,
|
579
622
|
empirical_policy=self.flow_run.empirical_policy,
|
580
623
|
)
|
624
|
+
|
625
|
+
self._span = self._tracer.start_span(
|
626
|
+
name=self.flow_run.name,
|
627
|
+
attributes={
|
628
|
+
**self.flow_run.labels,
|
629
|
+
"prefect.run.type": "flow",
|
630
|
+
"prefect.run.id": str(self.flow_run.id),
|
631
|
+
"prefect.tags": self.flow_run.tags,
|
632
|
+
"prefect.flow.name": self.flow.name,
|
633
|
+
},
|
634
|
+
)
|
635
|
+
|
581
636
|
try:
|
582
637
|
yield self
|
583
638
|
|
@@ -632,7 +687,7 @@ class FlowRunEngine(Generic[P, R]):
|
|
632
687
|
|
633
688
|
@contextmanager
|
634
689
|
def start(self) -> Generator[None, None, None]:
|
635
|
-
with self.initialize_run():
|
690
|
+
with self.initialize_run(), trace.use_span(self._span):
|
636
691
|
self.begin_run()
|
637
692
|
|
638
693
|
if self.state.is_running():
|
@@ -32,7 +32,6 @@ from prefect.settings import (
|
|
32
32
|
PREFECT_LOGGING_TO_API_BATCH_SIZE,
|
33
33
|
PREFECT_LOGGING_TO_API_MAX_LOG_SIZE,
|
34
34
|
PREFECT_LOGGING_TO_API_WHEN_MISSING_FLOW,
|
35
|
-
get_current_settings,
|
36
35
|
)
|
37
36
|
|
38
37
|
|
@@ -241,10 +240,12 @@ class APILogHandler(logging.Handler):
|
|
241
240
|
|
242
241
|
class WorkerAPILogHandler(APILogHandler):
|
243
242
|
def emit(self, record: logging.LogRecord):
|
244
|
-
|
245
|
-
|
246
|
-
|
243
|
+
# Open-source API servers do not currently support worker logs, and
|
244
|
+
# worker logs only have an associated worker ID when connected to Cloud,
|
245
|
+
# so we won't send worker logs to the API unless they have a worker ID.
|
246
|
+
if not getattr(record, "worker_id", None):
|
247
247
|
return
|
248
|
+
super().emit(record)
|
248
249
|
|
249
250
|
def prepare(self, record: logging.LogRecord) -> Dict[str, Any]:
|
250
251
|
"""
|
@@ -17,6 +17,7 @@ from pydantic_settings import (
|
|
17
17
|
|
18
18
|
from prefect.settings.sources import (
|
19
19
|
EnvFilterSettingsSource,
|
20
|
+
FilteredDotEnvSettingsSource,
|
20
21
|
PrefectTomlConfigSettingsSource,
|
21
22
|
ProfileSettingsTomlLoader,
|
22
23
|
PyprojectTomlConfigSettingsSource,
|
@@ -43,13 +44,14 @@ class PrefectBaseSettings(BaseSettings):
|
|
43
44
|
See https://docs.pydantic.dev/latest/concepts/pydantic_settings/#customise-settings-sources
|
44
45
|
"""
|
45
46
|
env_filter = set()
|
46
|
-
for field in settings_cls.model_fields.
|
47
|
+
for field_name, field in settings_cls.model_fields.items():
|
47
48
|
if field.validation_alias is not None and isinstance(
|
48
49
|
field.validation_alias, AliasChoices
|
49
50
|
):
|
50
51
|
for alias in field.validation_alias.choices:
|
51
52
|
if isinstance(alias, AliasPath) and len(alias.path) > 0:
|
52
53
|
env_filter.add(alias.path[0])
|
54
|
+
env_filter.add(field_name)
|
53
55
|
return (
|
54
56
|
init_settings,
|
55
57
|
EnvFilterSettingsSource(
|
@@ -62,7 +64,18 @@ class PrefectBaseSettings(BaseSettings):
|
|
62
64
|
env_parse_enums=cls.model_config.get("env_parse_enums"),
|
63
65
|
env_filter=list(env_filter),
|
64
66
|
),
|
65
|
-
|
67
|
+
FilteredDotEnvSettingsSource(
|
68
|
+
settings_cls,
|
69
|
+
env_file=cls.model_config.get("env_file"),
|
70
|
+
env_file_encoding=cls.model_config.get("env_file_encoding"),
|
71
|
+
case_sensitive=cls.model_config.get("case_sensitive"),
|
72
|
+
env_prefix=cls.model_config.get("env_prefix"),
|
73
|
+
env_nested_delimiter=cls.model_config.get("env_nested_delimiter"),
|
74
|
+
env_ignore_empty=cls.model_config.get("env_ignore_empty"),
|
75
|
+
env_parse_none_str=cls.model_config.get("env_parse_none_str"),
|
76
|
+
env_parse_enums=cls.model_config.get("env_parse_enums"),
|
77
|
+
env_blacklist=list(env_filter),
|
78
|
+
),
|
66
79
|
file_secret_settings,
|
67
80
|
PrefectTomlConfigSettingsSource(settings_cls),
|
68
81
|
PyprojectTomlConfigSettingsSource(settings_cls),
|
@@ -92,7 +105,7 @@ class PrefectBaseSettings(BaseSettings):
|
|
92
105
|
elif (value := env.get(key)) is not None:
|
93
106
|
env_variables[
|
94
107
|
f"{self.model_config.get('env_prefix')}{key.upper()}"
|
95
|
-
] =
|
108
|
+
] = _to_environment_variable_value(value)
|
96
109
|
return env_variables
|
97
110
|
|
98
111
|
@model_serializer(
|
@@ -191,3 +204,9 @@ def _build_settings_config(
|
|
191
204
|
pyproject_toml_table_header=("tool", "prefect", *path),
|
192
205
|
json_schema_extra=_add_environment_variables,
|
193
206
|
)
|
207
|
+
|
208
|
+
|
209
|
+
def _to_environment_variable_value(value: Any) -> str:
|
210
|
+
if isinstance(value, (list, set, tuple)):
|
211
|
+
return ",".join(str(v) for v in value)
|
212
|
+
return str(value)
|
@@ -18,11 +18,6 @@ class ExperimentsSettings(PrefectBaseSettings):
|
|
18
18
|
),
|
19
19
|
)
|
20
20
|
|
21
|
-
worker_logging_to_api_enabled: bool = Field(
|
22
|
-
default=False,
|
23
|
-
description="Enables the logging of worker logs to Prefect Cloud.",
|
24
|
-
)
|
25
|
-
|
26
21
|
telemetry_enabled: bool = Field(
|
27
22
|
default=False,
|
28
23
|
description="Enables sending telemetry to Prefect Cloud.",
|
@@ -10,10 +10,15 @@ from pydantic import AliasChoices
|
|
10
10
|
from pydantic.fields import FieldInfo
|
11
11
|
from pydantic_settings import (
|
12
12
|
BaseSettings,
|
13
|
+
DotEnvSettingsSource,
|
13
14
|
EnvSettingsSource,
|
14
15
|
PydanticBaseSettingsSource,
|
15
16
|
)
|
16
|
-
from pydantic_settings.sources import
|
17
|
+
from pydantic_settings.sources import (
|
18
|
+
ENV_FILE_SENTINEL,
|
19
|
+
ConfigFileSourceMixin,
|
20
|
+
DotenvType,
|
21
|
+
)
|
17
22
|
|
18
23
|
from prefect.settings.constants import DEFAULT_PREFECT_HOME, DEFAULT_PROFILES_PATH
|
19
24
|
from prefect.utilities.collections import get_from_dict
|
@@ -61,6 +66,44 @@ class EnvFilterSettingsSource(EnvSettingsSource):
|
|
61
66
|
}
|
62
67
|
|
63
68
|
|
69
|
+
class FilteredDotEnvSettingsSource(DotEnvSettingsSource):
|
70
|
+
def __init__(
|
71
|
+
self,
|
72
|
+
settings_cls: type[BaseSettings],
|
73
|
+
env_file: Optional[DotenvType] = ENV_FILE_SENTINEL,
|
74
|
+
env_file_encoding: Optional[str] = None,
|
75
|
+
case_sensitive: Optional[bool] = None,
|
76
|
+
env_prefix: Optional[str] = None,
|
77
|
+
env_nested_delimiter: Optional[str] = None,
|
78
|
+
env_ignore_empty: Optional[bool] = None,
|
79
|
+
env_parse_none_str: Optional[str] = None,
|
80
|
+
env_parse_enums: Optional[bool] = None,
|
81
|
+
env_blacklist: Optional[List[str]] = None,
|
82
|
+
) -> None:
|
83
|
+
super().__init__(
|
84
|
+
settings_cls,
|
85
|
+
env_file,
|
86
|
+
env_file_encoding,
|
87
|
+
case_sensitive,
|
88
|
+
env_prefix,
|
89
|
+
env_nested_delimiter,
|
90
|
+
env_ignore_empty,
|
91
|
+
env_parse_none_str,
|
92
|
+
env_parse_enums,
|
93
|
+
)
|
94
|
+
self.env_blacklist = env_blacklist
|
95
|
+
if self.env_blacklist:
|
96
|
+
if isinstance(self.env_vars, dict):
|
97
|
+
for key in self.env_blacklist:
|
98
|
+
self.env_vars.pop(key, None)
|
99
|
+
else:
|
100
|
+
self.env_vars = {
|
101
|
+
key: value
|
102
|
+
for key, value in self.env_vars.items() # type: ignore
|
103
|
+
if key.lower() not in env_blacklist
|
104
|
+
}
|
105
|
+
|
106
|
+
|
64
107
|
class ProfileSettingsTomlLoader(PydanticBaseSettingsSource):
|
65
108
|
"""
|
66
109
|
Custom pydantic settings source to load profile settings from a toml file.
|
@@ -111,21 +154,34 @@ class ProfileSettingsTomlLoader(PydanticBaseSettingsSource):
|
|
111
154
|
) -> Tuple[Any, str, bool]:
|
112
155
|
"""Concrete implementation to get the field value from the profile settings"""
|
113
156
|
if field.validation_alias:
|
157
|
+
# Use validation alias as the key to ensure profile value does not
|
158
|
+
# higher priority sources. Lower priority sources that use the
|
159
|
+
# field name can override higher priority sources that use the
|
160
|
+
# validation alias as seen in https://github.com/PrefectHQ/prefect/issues/15981
|
114
161
|
if isinstance(field.validation_alias, str):
|
115
162
|
value = self.profile_settings.get(field.validation_alias.upper())
|
116
163
|
if value is not None:
|
117
|
-
return value,
|
164
|
+
return value, field.validation_alias, self.field_is_complex(field)
|
118
165
|
elif isinstance(field.validation_alias, AliasChoices):
|
166
|
+
value = None
|
167
|
+
lowest_priority_alias = next(
|
168
|
+
choice
|
169
|
+
for choice in reversed(field.validation_alias.choices)
|
170
|
+
if isinstance(choice, str)
|
171
|
+
)
|
119
172
|
for alias in field.validation_alias.choices:
|
120
173
|
if not isinstance(alias, str):
|
121
174
|
continue
|
122
175
|
value = self.profile_settings.get(alias.upper())
|
123
176
|
if value is not None:
|
124
|
-
return
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
177
|
+
return (
|
178
|
+
value,
|
179
|
+
lowest_priority_alias,
|
180
|
+
self.field_is_complex(field),
|
181
|
+
)
|
182
|
+
|
183
|
+
name = f"{self.config.get('env_prefix','')}{field_name.upper()}"
|
184
|
+
value = self.profile_settings.get(name)
|
129
185
|
return value, field_name, self.field_is_complex(field)
|
130
186
|
|
131
187
|
def __call__(self) -> Dict[str, Any]:
|
@@ -164,7 +220,22 @@ class TomlConfigSettingsSourceBase(PydanticBaseSettingsSource, ConfigFileSourceM
|
|
164
220
|
# if the value is a dict, it is likely a nested settings object and a nested
|
165
221
|
# source will handle it
|
166
222
|
value = None
|
167
|
-
|
223
|
+
name = field_name
|
224
|
+
# Use validation alias as the key to ensure profile value does not
|
225
|
+
# higher priority sources. Lower priority sources that use the
|
226
|
+
# field name can override higher priority sources that use the
|
227
|
+
# validation alias as seen in https://github.com/PrefectHQ/prefect/issues/15981
|
228
|
+
if value is not None:
|
229
|
+
if field.validation_alias and isinstance(field.validation_alias, str):
|
230
|
+
name = field.validation_alias
|
231
|
+
elif field.validation_alias and isinstance(
|
232
|
+
field.validation_alias, AliasChoices
|
233
|
+
):
|
234
|
+
for alias in reversed(field.validation_alias.choices):
|
235
|
+
if isinstance(alias, str):
|
236
|
+
name = alias
|
237
|
+
break
|
238
|
+
return value, name, self.field_is_complex(field)
|
168
239
|
|
169
240
|
def __call__(self) -> Dict[str, Any]:
|
170
241
|
"""Called by pydantic to get the settings from our custom source"""
|