prefect-client 2.20.4__py3-none-any.whl → 3.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- prefect/__init__.py +74 -110
- prefect/_internal/compatibility/deprecated.py +6 -115
- prefect/_internal/compatibility/experimental.py +4 -79
- prefect/_internal/compatibility/migration.py +166 -0
- prefect/_internal/concurrency/__init__.py +2 -2
- prefect/_internal/concurrency/api.py +1 -35
- prefect/_internal/concurrency/calls.py +0 -6
- prefect/_internal/concurrency/cancellation.py +0 -3
- prefect/_internal/concurrency/event_loop.py +0 -20
- prefect/_internal/concurrency/inspection.py +3 -3
- prefect/_internal/concurrency/primitives.py +1 -0
- prefect/_internal/concurrency/services.py +23 -0
- prefect/_internal/concurrency/threads.py +35 -0
- prefect/_internal/concurrency/waiters.py +0 -28
- prefect/_internal/integrations.py +7 -0
- prefect/_internal/pydantic/__init__.py +0 -45
- prefect/_internal/pydantic/annotations/pendulum.py +2 -2
- prefect/_internal/pydantic/v1_schema.py +21 -22
- prefect/_internal/pydantic/v2_schema.py +0 -2
- prefect/_internal/pydantic/v2_validated_func.py +18 -23
- prefect/_internal/pytz.py +1 -1
- prefect/_internal/retries.py +61 -0
- prefect/_internal/schemas/bases.py +45 -177
- prefect/_internal/schemas/fields.py +1 -43
- prefect/_internal/schemas/validators.py +47 -233
- prefect/agent.py +3 -695
- prefect/artifacts.py +173 -14
- prefect/automations.py +39 -4
- prefect/blocks/abstract.py +1 -1
- prefect/blocks/core.py +405 -153
- prefect/blocks/fields.py +2 -57
- prefect/blocks/notifications.py +43 -28
- prefect/blocks/redis.py +168 -0
- prefect/blocks/system.py +67 -20
- prefect/blocks/webhook.py +2 -9
- prefect/cache_policies.py +239 -0
- prefect/client/__init__.py +4 -0
- prefect/client/base.py +33 -27
- prefect/client/cloud.py +65 -20
- prefect/client/collections.py +1 -1
- prefect/client/orchestration.py +650 -442
- prefect/client/schemas/actions.py +115 -100
- prefect/client/schemas/filters.py +46 -52
- prefect/client/schemas/objects.py +228 -178
- prefect/client/schemas/responses.py +18 -36
- prefect/client/schemas/schedules.py +55 -36
- prefect/client/schemas/sorting.py +2 -0
- prefect/client/subscriptions.py +8 -7
- prefect/client/types/flexible_schedule_list.py +11 -0
- prefect/client/utilities.py +9 -6
- prefect/concurrency/asyncio.py +60 -11
- prefect/concurrency/context.py +24 -0
- prefect/concurrency/events.py +2 -2
- prefect/concurrency/services.py +46 -16
- prefect/concurrency/sync.py +51 -7
- prefect/concurrency/v1/asyncio.py +143 -0
- prefect/concurrency/v1/context.py +27 -0
- prefect/concurrency/v1/events.py +61 -0
- prefect/concurrency/v1/services.py +116 -0
- prefect/concurrency/v1/sync.py +92 -0
- prefect/context.py +246 -149
- prefect/deployments/__init__.py +33 -18
- prefect/deployments/base.py +10 -15
- prefect/deployments/deployments.py +2 -1048
- prefect/deployments/flow_runs.py +178 -0
- prefect/deployments/runner.py +72 -173
- prefect/deployments/schedules.py +31 -25
- prefect/deployments/steps/__init__.py +0 -1
- prefect/deployments/steps/core.py +7 -0
- prefect/deployments/steps/pull.py +15 -21
- prefect/deployments/steps/utility.py +2 -1
- prefect/docker/__init__.py +20 -0
- prefect/docker/docker_image.py +82 -0
- prefect/engine.py +15 -2475
- prefect/events/actions.py +17 -23
- prefect/events/cli/automations.py +20 -7
- prefect/events/clients.py +142 -80
- prefect/events/filters.py +14 -18
- prefect/events/related.py +74 -75
- prefect/events/schemas/__init__.py +0 -5
- prefect/events/schemas/automations.py +55 -46
- prefect/events/schemas/deployment_triggers.py +7 -197
- prefect/events/schemas/events.py +46 -65
- prefect/events/schemas/labelling.py +10 -14
- prefect/events/utilities.py +4 -5
- prefect/events/worker.py +23 -8
- prefect/exceptions.py +15 -0
- prefect/filesystems.py +30 -529
- prefect/flow_engine.py +827 -0
- prefect/flow_runs.py +379 -7
- prefect/flows.py +470 -360
- prefect/futures.py +382 -331
- prefect/infrastructure/__init__.py +5 -26
- prefect/infrastructure/base.py +3 -320
- prefect/infrastructure/provisioners/__init__.py +5 -3
- prefect/infrastructure/provisioners/cloud_run.py +13 -8
- prefect/infrastructure/provisioners/container_instance.py +14 -9
- prefect/infrastructure/provisioners/ecs.py +10 -8
- prefect/infrastructure/provisioners/modal.py +8 -5
- prefect/input/__init__.py +4 -0
- prefect/input/actions.py +2 -4
- prefect/input/run_input.py +9 -9
- prefect/logging/formatters.py +2 -4
- prefect/logging/handlers.py +9 -14
- prefect/logging/loggers.py +5 -5
- prefect/main.py +72 -0
- prefect/plugins.py +2 -64
- prefect/profiles.toml +16 -2
- prefect/records/__init__.py +1 -0
- prefect/records/base.py +223 -0
- prefect/records/filesystem.py +207 -0
- prefect/records/memory.py +178 -0
- prefect/records/result_store.py +64 -0
- prefect/results.py +577 -504
- prefect/runner/runner.py +117 -47
- prefect/runner/server.py +32 -34
- prefect/runner/storage.py +3 -12
- prefect/runner/submit.py +2 -10
- prefect/runner/utils.py +2 -2
- prefect/runtime/__init__.py +1 -0
- prefect/runtime/deployment.py +1 -0
- prefect/runtime/flow_run.py +40 -5
- prefect/runtime/task_run.py +1 -0
- prefect/serializers.py +28 -39
- prefect/server/api/collections_data/views/aggregate-worker-metadata.json +5 -14
- prefect/settings.py +209 -332
- prefect/states.py +160 -63
- prefect/task_engine.py +1478 -57
- prefect/task_runners.py +383 -287
- prefect/task_runs.py +240 -0
- prefect/task_worker.py +463 -0
- prefect/tasks.py +684 -374
- prefect/transactions.py +410 -0
- prefect/types/__init__.py +72 -86
- prefect/types/entrypoint.py +13 -0
- prefect/utilities/annotations.py +4 -3
- prefect/utilities/asyncutils.py +227 -148
- prefect/utilities/callables.py +137 -45
- prefect/utilities/collections.py +134 -86
- prefect/utilities/dispatch.py +27 -14
- prefect/utilities/dockerutils.py +11 -4
- prefect/utilities/engine.py +186 -32
- prefect/utilities/filesystem.py +4 -5
- prefect/utilities/importtools.py +26 -27
- prefect/utilities/pydantic.py +128 -38
- prefect/utilities/schema_tools/hydration.py +18 -1
- prefect/utilities/schema_tools/validation.py +30 -0
- prefect/utilities/services.py +35 -9
- prefect/utilities/templating.py +12 -2
- prefect/utilities/timeout.py +20 -5
- prefect/utilities/urls.py +195 -0
- prefect/utilities/visualization.py +1 -0
- prefect/variables.py +78 -59
- prefect/workers/__init__.py +0 -1
- prefect/workers/base.py +237 -244
- prefect/workers/block.py +5 -226
- prefect/workers/cloud.py +6 -0
- prefect/workers/process.py +265 -12
- prefect/workers/server.py +29 -11
- {prefect_client-2.20.4.dist-info → prefect_client-3.0.0.dist-info}/METADATA +28 -24
- prefect_client-3.0.0.dist-info/RECORD +201 -0
- {prefect_client-2.20.4.dist-info → prefect_client-3.0.0.dist-info}/WHEEL +1 -1
- prefect/_internal/pydantic/_base_model.py +0 -51
- prefect/_internal/pydantic/_compat.py +0 -82
- prefect/_internal/pydantic/_flags.py +0 -20
- prefect/_internal/pydantic/_types.py +0 -8
- prefect/_internal/pydantic/utilities/config_dict.py +0 -72
- prefect/_internal/pydantic/utilities/field_validator.py +0 -150
- prefect/_internal/pydantic/utilities/model_construct.py +0 -56
- prefect/_internal/pydantic/utilities/model_copy.py +0 -55
- prefect/_internal/pydantic/utilities/model_dump.py +0 -136
- prefect/_internal/pydantic/utilities/model_dump_json.py +0 -112
- prefect/_internal/pydantic/utilities/model_fields.py +0 -50
- prefect/_internal/pydantic/utilities/model_fields_set.py +0 -29
- prefect/_internal/pydantic/utilities/model_json_schema.py +0 -82
- prefect/_internal/pydantic/utilities/model_rebuild.py +0 -80
- prefect/_internal/pydantic/utilities/model_validate.py +0 -75
- prefect/_internal/pydantic/utilities/model_validate_json.py +0 -68
- prefect/_internal/pydantic/utilities/model_validator.py +0 -87
- prefect/_internal/pydantic/utilities/type_adapter.py +0 -71
- prefect/_vendor/fastapi/__init__.py +0 -25
- prefect/_vendor/fastapi/applications.py +0 -946
- prefect/_vendor/fastapi/background.py +0 -3
- prefect/_vendor/fastapi/concurrency.py +0 -44
- prefect/_vendor/fastapi/datastructures.py +0 -58
- prefect/_vendor/fastapi/dependencies/__init__.py +0 -0
- prefect/_vendor/fastapi/dependencies/models.py +0 -64
- prefect/_vendor/fastapi/dependencies/utils.py +0 -877
- prefect/_vendor/fastapi/encoders.py +0 -177
- prefect/_vendor/fastapi/exception_handlers.py +0 -40
- prefect/_vendor/fastapi/exceptions.py +0 -46
- prefect/_vendor/fastapi/logger.py +0 -3
- prefect/_vendor/fastapi/middleware/__init__.py +0 -1
- prefect/_vendor/fastapi/middleware/asyncexitstack.py +0 -25
- prefect/_vendor/fastapi/middleware/cors.py +0 -3
- prefect/_vendor/fastapi/middleware/gzip.py +0 -3
- prefect/_vendor/fastapi/middleware/httpsredirect.py +0 -3
- prefect/_vendor/fastapi/middleware/trustedhost.py +0 -3
- prefect/_vendor/fastapi/middleware/wsgi.py +0 -3
- prefect/_vendor/fastapi/openapi/__init__.py +0 -0
- prefect/_vendor/fastapi/openapi/constants.py +0 -2
- prefect/_vendor/fastapi/openapi/docs.py +0 -203
- prefect/_vendor/fastapi/openapi/models.py +0 -480
- prefect/_vendor/fastapi/openapi/utils.py +0 -485
- prefect/_vendor/fastapi/param_functions.py +0 -340
- prefect/_vendor/fastapi/params.py +0 -453
- prefect/_vendor/fastapi/py.typed +0 -0
- prefect/_vendor/fastapi/requests.py +0 -4
- prefect/_vendor/fastapi/responses.py +0 -40
- prefect/_vendor/fastapi/routing.py +0 -1331
- prefect/_vendor/fastapi/security/__init__.py +0 -15
- prefect/_vendor/fastapi/security/api_key.py +0 -98
- prefect/_vendor/fastapi/security/base.py +0 -6
- prefect/_vendor/fastapi/security/http.py +0 -172
- prefect/_vendor/fastapi/security/oauth2.py +0 -227
- prefect/_vendor/fastapi/security/open_id_connect_url.py +0 -34
- prefect/_vendor/fastapi/security/utils.py +0 -10
- prefect/_vendor/fastapi/staticfiles.py +0 -1
- prefect/_vendor/fastapi/templating.py +0 -3
- prefect/_vendor/fastapi/testclient.py +0 -1
- prefect/_vendor/fastapi/types.py +0 -3
- prefect/_vendor/fastapi/utils.py +0 -235
- prefect/_vendor/fastapi/websockets.py +0 -7
- prefect/_vendor/starlette/__init__.py +0 -1
- prefect/_vendor/starlette/_compat.py +0 -28
- prefect/_vendor/starlette/_exception_handler.py +0 -80
- prefect/_vendor/starlette/_utils.py +0 -88
- prefect/_vendor/starlette/applications.py +0 -261
- prefect/_vendor/starlette/authentication.py +0 -159
- prefect/_vendor/starlette/background.py +0 -43
- prefect/_vendor/starlette/concurrency.py +0 -59
- prefect/_vendor/starlette/config.py +0 -151
- prefect/_vendor/starlette/convertors.py +0 -87
- prefect/_vendor/starlette/datastructures.py +0 -707
- prefect/_vendor/starlette/endpoints.py +0 -130
- prefect/_vendor/starlette/exceptions.py +0 -60
- prefect/_vendor/starlette/formparsers.py +0 -276
- prefect/_vendor/starlette/middleware/__init__.py +0 -17
- prefect/_vendor/starlette/middleware/authentication.py +0 -52
- prefect/_vendor/starlette/middleware/base.py +0 -220
- prefect/_vendor/starlette/middleware/cors.py +0 -176
- prefect/_vendor/starlette/middleware/errors.py +0 -265
- prefect/_vendor/starlette/middleware/exceptions.py +0 -74
- prefect/_vendor/starlette/middleware/gzip.py +0 -113
- prefect/_vendor/starlette/middleware/httpsredirect.py +0 -19
- prefect/_vendor/starlette/middleware/sessions.py +0 -82
- prefect/_vendor/starlette/middleware/trustedhost.py +0 -64
- prefect/_vendor/starlette/middleware/wsgi.py +0 -147
- prefect/_vendor/starlette/py.typed +0 -0
- prefect/_vendor/starlette/requests.py +0 -328
- prefect/_vendor/starlette/responses.py +0 -347
- prefect/_vendor/starlette/routing.py +0 -933
- prefect/_vendor/starlette/schemas.py +0 -154
- prefect/_vendor/starlette/staticfiles.py +0 -248
- prefect/_vendor/starlette/status.py +0 -199
- prefect/_vendor/starlette/templating.py +0 -231
- prefect/_vendor/starlette/testclient.py +0 -804
- prefect/_vendor/starlette/types.py +0 -30
- prefect/_vendor/starlette/websockets.py +0 -193
- prefect/blocks/kubernetes.py +0 -119
- prefect/deprecated/__init__.py +0 -0
- prefect/deprecated/data_documents.py +0 -350
- prefect/deprecated/packaging/__init__.py +0 -12
- prefect/deprecated/packaging/base.py +0 -96
- prefect/deprecated/packaging/docker.py +0 -146
- prefect/deprecated/packaging/file.py +0 -92
- prefect/deprecated/packaging/orion.py +0 -80
- prefect/deprecated/packaging/serializers.py +0 -171
- prefect/events/instrument.py +0 -135
- prefect/infrastructure/container.py +0 -824
- prefect/infrastructure/kubernetes.py +0 -920
- prefect/infrastructure/process.py +0 -289
- prefect/manifests.py +0 -20
- prefect/new_flow_engine.py +0 -449
- prefect/new_task_engine.py +0 -423
- prefect/pydantic/__init__.py +0 -76
- prefect/pydantic/main.py +0 -39
- prefect/software/__init__.py +0 -2
- prefect/software/base.py +0 -50
- prefect/software/conda.py +0 -199
- prefect/software/pip.py +0 -122
- prefect/software/python.py +0 -52
- prefect/task_server.py +0 -322
- prefect_client-2.20.4.dist-info/RECORD +0 -294
- /prefect/{_internal/pydantic/utilities → client/types}/__init__.py +0 -0
- /prefect/{_vendor → concurrency/v1}/__init__.py +0 -0
- {prefect_client-2.20.4.dist-info → prefect_client-3.0.0.dist-info}/LICENSE +0 -0
- {prefect_client-2.20.4.dist-info → prefect_client-3.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,195 @@
|
|
1
|
+
import inspect
|
2
|
+
import urllib.parse
|
3
|
+
from typing import Any, Literal, Optional, Union
|
4
|
+
from uuid import UUID
|
5
|
+
|
6
|
+
from pydantic import BaseModel
|
7
|
+
|
8
|
+
from prefect import settings
|
9
|
+
from prefect.blocks.core import Block
|
10
|
+
from prefect.events.schemas.automations import Automation
|
11
|
+
from prefect.events.schemas.events import ReceivedEvent, Resource
|
12
|
+
from prefect.futures import PrefectFuture
|
13
|
+
from prefect.logging.loggers import get_logger
|
14
|
+
from prefect.variables import Variable
|
15
|
+
|
16
|
+
logger = get_logger("utilities.urls")
|
17
|
+
|
18
|
+
# The following objects are excluded from UI URL generation because we lack a
|
19
|
+
# directly-addressable URL:
|
20
|
+
# worker
|
21
|
+
# artifact
|
22
|
+
# variable
|
23
|
+
# saved-search
|
24
|
+
UI_URL_FORMATS = {
|
25
|
+
"flow": "flows/flow/{obj_id}",
|
26
|
+
"flow-run": "runs/flow-run/{obj_id}",
|
27
|
+
"task-run": "runs/task-run/{obj_id}",
|
28
|
+
"block": "blocks/block/{obj_id}",
|
29
|
+
"block-document": "blocks/block/{obj_id}",
|
30
|
+
"work-pool": "work-pools/work-pool/{obj_id}",
|
31
|
+
"work-queue": "work-queues/work-queue/{obj_id}",
|
32
|
+
"concurrency-limit": "concurrency-limits/concurrency-limit/{obj_id}",
|
33
|
+
"deployment": "deployments/deployment/{obj_id}",
|
34
|
+
"automation": "automations/automation/{obj_id}",
|
35
|
+
"received-event": "events/event/{occurred}/{obj_id}",
|
36
|
+
}
|
37
|
+
|
38
|
+
# The following objects are excluded from API URL generation because we lack a
|
39
|
+
# directly-addressable URL:
|
40
|
+
# worker
|
41
|
+
# artifact
|
42
|
+
# saved-search
|
43
|
+
# received-event
|
44
|
+
API_URL_FORMATS = {
|
45
|
+
"flow": "flows/{obj_id}",
|
46
|
+
"flow-run": "flow_runs/{obj_id}",
|
47
|
+
"task-run": "task_runs/{obj_id}",
|
48
|
+
"variable": "variables/name/{obj_id}",
|
49
|
+
"block": "blocks/{obj_id}",
|
50
|
+
"work-pool": "work_pools/{obj_id}",
|
51
|
+
"work-queue": "work_queues/{obj_id}",
|
52
|
+
"concurrency-limit": "concurrency_limits/{obj_id}",
|
53
|
+
"deployment": "deployments/{obj_id}",
|
54
|
+
"automation": "automations/{obj_id}",
|
55
|
+
}
|
56
|
+
|
57
|
+
URLType = Literal["ui", "api"]
|
58
|
+
RUN_TYPES = {"flow-run", "task-run"}
|
59
|
+
|
60
|
+
|
61
|
+
def convert_class_to_name(obj: Any) -> str:
|
62
|
+
"""
|
63
|
+
Convert CamelCase class name to dash-separated lowercase name
|
64
|
+
"""
|
65
|
+
cls = obj if inspect.isclass(obj) else obj.__class__
|
66
|
+
name = cls.__name__
|
67
|
+
return "".join(["-" + i.lower() if i.isupper() else i for i in name]).lstrip("-")
|
68
|
+
|
69
|
+
|
70
|
+
def url_for(
|
71
|
+
obj: Union[
|
72
|
+
PrefectFuture,
|
73
|
+
Block,
|
74
|
+
Variable,
|
75
|
+
Automation,
|
76
|
+
Resource,
|
77
|
+
ReceivedEvent,
|
78
|
+
BaseModel,
|
79
|
+
str,
|
80
|
+
],
|
81
|
+
obj_id: Optional[Union[str, UUID]] = None,
|
82
|
+
url_type: URLType = "ui",
|
83
|
+
default_base_url: Optional[str] = None,
|
84
|
+
) -> Optional[str]:
|
85
|
+
"""
|
86
|
+
Returns the URL for a Prefect object.
|
87
|
+
|
88
|
+
Pass in a supported object directly or provide an object name and ID.
|
89
|
+
|
90
|
+
Args:
|
91
|
+
obj (Union[PrefectFuture, Block, Variable, Automation, Resource, ReceivedEvent, BaseModel, str]):
|
92
|
+
A Prefect object to get the URL for, or its URL name and ID.
|
93
|
+
obj_id (Union[str, UUID], optional):
|
94
|
+
The UUID of the object.
|
95
|
+
url_type (Literal["ui", "api"], optional):
|
96
|
+
Whether to return the URL for the UI (default) or API.
|
97
|
+
default_base_url (str, optional):
|
98
|
+
The default base URL to use if no URL is configured.
|
99
|
+
|
100
|
+
Returns:
|
101
|
+
Optional[str]: The URL for the given object or None if the object is not supported.
|
102
|
+
|
103
|
+
Examples:
|
104
|
+
url_for(my_flow_run)
|
105
|
+
url_for(obj=my_flow_run)
|
106
|
+
url_for("flow-run", obj_id="123e4567-e89b-12d3-a456-426614174000")
|
107
|
+
"""
|
108
|
+
if isinstance(obj, PrefectFuture):
|
109
|
+
name = "task-run"
|
110
|
+
elif isinstance(obj, Block):
|
111
|
+
name = "block"
|
112
|
+
elif isinstance(obj, Automation):
|
113
|
+
name = "automation"
|
114
|
+
elif isinstance(obj, ReceivedEvent):
|
115
|
+
name = "received-event"
|
116
|
+
elif isinstance(obj, Resource):
|
117
|
+
if obj.id.startswith("prefect."):
|
118
|
+
name = obj.id.split(".")[1]
|
119
|
+
else:
|
120
|
+
logger.debug(f"No URL known for resource with ID: {obj.id}")
|
121
|
+
return None
|
122
|
+
elif isinstance(obj, str):
|
123
|
+
name = obj
|
124
|
+
else:
|
125
|
+
name = convert_class_to_name(obj)
|
126
|
+
|
127
|
+
# Can't do an isinstance check here because the client build
|
128
|
+
# doesn't have access to that server schema.
|
129
|
+
if name == "work-queue-with-status":
|
130
|
+
name = "work-queue"
|
131
|
+
|
132
|
+
if url_type != "ui" and url_type != "api":
|
133
|
+
raise ValueError(f"Invalid URL type: {url_type}. Use 'ui' or 'api'.")
|
134
|
+
|
135
|
+
if url_type == "ui" and name not in UI_URL_FORMATS:
|
136
|
+
logger.debug("No UI URL known for this object: %s", name)
|
137
|
+
return None
|
138
|
+
elif url_type == "api" and name not in API_URL_FORMATS:
|
139
|
+
logger.debug("No API URL known for this object: %s", name)
|
140
|
+
return None
|
141
|
+
|
142
|
+
if isinstance(obj, str) and not obj_id:
|
143
|
+
raise ValueError(
|
144
|
+
"If passing an object name, you must also provide an object ID."
|
145
|
+
)
|
146
|
+
|
147
|
+
base_url = (
|
148
|
+
settings.PREFECT_UI_URL.value()
|
149
|
+
if url_type == "ui"
|
150
|
+
else settings.PREFECT_API_URL.value()
|
151
|
+
)
|
152
|
+
base_url = base_url or default_base_url
|
153
|
+
|
154
|
+
if not base_url:
|
155
|
+
logger.debug(
|
156
|
+
f"No URL found for the Prefect {'UI' if url_type == 'ui' else 'API'}, "
|
157
|
+
f"and no default base path provided."
|
158
|
+
)
|
159
|
+
return None
|
160
|
+
|
161
|
+
if not obj_id:
|
162
|
+
# We treat PrefectFuture as if it was the underlying task run,
|
163
|
+
# so we need to check the object type here instead of name.
|
164
|
+
if isinstance(obj, PrefectFuture):
|
165
|
+
obj_id = getattr(obj, "task_run_id", None)
|
166
|
+
elif name == "block":
|
167
|
+
# Blocks are client-side objects whose API representation is a
|
168
|
+
# BlockDocument.
|
169
|
+
obj_id = obj._block_document_id
|
170
|
+
elif name in ("variable", "work-pool"):
|
171
|
+
obj_id = obj.name
|
172
|
+
elif isinstance(obj, Resource):
|
173
|
+
obj_id = obj.id.rpartition(".")[2]
|
174
|
+
else:
|
175
|
+
obj_id = getattr(obj, "id", None)
|
176
|
+
if not obj_id:
|
177
|
+
logger.debug(
|
178
|
+
"An ID is required to build a URL, but object did not have one: %s", obj
|
179
|
+
)
|
180
|
+
return ""
|
181
|
+
|
182
|
+
url_format = (
|
183
|
+
UI_URL_FORMATS.get(name) if url_type == "ui" else API_URL_FORMATS.get(name)
|
184
|
+
)
|
185
|
+
|
186
|
+
if isinstance(obj, ReceivedEvent):
|
187
|
+
url = url_format.format(
|
188
|
+
occurred=obj.occurred.strftime("%Y-%m-%d"), obj_id=obj_id
|
189
|
+
)
|
190
|
+
else:
|
191
|
+
url = url_format.format(obj_id=obj_id)
|
192
|
+
|
193
|
+
if not base_url.endswith("/"):
|
194
|
+
base_url += "/"
|
195
|
+
return urllib.parse.urljoin(base_url, url)
|
prefect/variables.py
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
from typing import List, Optional
|
2
2
|
|
3
|
-
from prefect._internal.compatibility.
|
3
|
+
from prefect._internal.compatibility.migration import getattr_migration
|
4
4
|
from prefect.client.schemas.actions import VariableCreate as VariableRequest
|
5
5
|
from prefect.client.schemas.actions import VariableUpdate as VariableUpdateRequest
|
6
6
|
from prefect.client.utilities import get_or_create_client
|
7
|
+
from prefect.exceptions import ObjectNotFound
|
8
|
+
from prefect.types import StrictVariableValue
|
7
9
|
from prefect.utilities.asyncutils import sync_compatible
|
8
10
|
|
9
11
|
|
@@ -23,92 +25,109 @@ class Variable(VariableRequest):
|
|
23
25
|
async def set(
|
24
26
|
cls,
|
25
27
|
name: str,
|
26
|
-
value:
|
28
|
+
value: StrictVariableValue,
|
27
29
|
tags: Optional[List[str]] = None,
|
28
30
|
overwrite: bool = False,
|
29
|
-
) ->
|
31
|
+
) -> "Variable":
|
30
32
|
"""
|
31
|
-
Sets a new variable. If one exists with the same name,
|
32
|
-
```
|
33
|
-
from prefect.variables import Variable
|
33
|
+
Sets a new variable. If one exists with the same name, must pass `overwrite=True`
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
35
|
+
Returns the newly set variable object.
|
36
|
+
|
37
|
+
Args:
|
38
|
+
- name: The name of the variable to set.
|
39
|
+
- value: The value of the variable to set.
|
40
|
+
- tags: An optional list of strings to associate with the variable.
|
41
|
+
- overwrite: Whether to overwrite the variable if it already exists.
|
42
|
+
|
43
|
+
Example:
|
44
|
+
Set a new variable and overwrite it if it already exists.
|
45
|
+
```
|
41
46
|
from prefect.variables import Variable
|
42
47
|
|
43
48
|
@flow
|
44
|
-
|
45
|
-
|
46
|
-
|
49
|
+
def my_flow():
|
50
|
+
Variable.set(name="my_var",value="test_value", tags=["hi", "there"], overwrite=True)
|
51
|
+
```
|
47
52
|
"""
|
48
53
|
client, _ = get_or_create_client()
|
49
|
-
|
50
|
-
var_dict = {"name": name, "value": value}
|
51
|
-
|
52
|
-
if
|
54
|
+
variable_exists = await client.read_variable_by_name(name)
|
55
|
+
var_dict = {"name": name, "value": value, "tags": tags or []}
|
56
|
+
|
57
|
+
if variable_exists:
|
53
58
|
if not overwrite:
|
54
59
|
raise ValueError(
|
55
|
-
"
|
60
|
+
f"Variable {name!r} already exists. Use `overwrite=True` to update it."
|
56
61
|
)
|
57
|
-
|
58
|
-
await client.update_variable(variable=var)
|
62
|
+
await client.update_variable(variable=VariableUpdateRequest(**var_dict))
|
59
63
|
variable = await client.read_variable_by_name(name)
|
60
64
|
else:
|
61
|
-
|
62
|
-
|
65
|
+
variable = await client.create_variable(
|
66
|
+
variable=VariableRequest(**var_dict)
|
67
|
+
)
|
63
68
|
|
64
|
-
return variable
|
69
|
+
return variable
|
65
70
|
|
66
71
|
@classmethod
|
67
72
|
@sync_compatible
|
68
|
-
async def get(
|
73
|
+
async def get(
|
74
|
+
cls,
|
75
|
+
name: str,
|
76
|
+
default: StrictVariableValue = None,
|
77
|
+
) -> StrictVariableValue:
|
69
78
|
"""
|
70
|
-
Get a variable by name.
|
71
|
-
|
79
|
+
Get a variable's value by name.
|
80
|
+
|
81
|
+
If the variable does not exist, return the default value.
|
82
|
+
|
83
|
+
Args:
|
84
|
+
- name: The name of the variable value to get.
|
85
|
+
- default: The default value to return if the variable does not exist.
|
86
|
+
|
87
|
+
Example:
|
88
|
+
Get a variable's value by name.
|
89
|
+
```python
|
90
|
+
from prefect import flow
|
72
91
|
from prefect.variables import Variable
|
73
92
|
|
74
93
|
@flow
|
75
94
|
def my_flow():
|
76
95
|
var = Variable.get("my_var")
|
77
|
-
|
78
|
-
|
79
|
-
|
96
|
+
```
|
97
|
+
"""
|
98
|
+
client, _ = get_or_create_client()
|
99
|
+
variable = await client.read_variable_by_name(name)
|
100
|
+
|
101
|
+
return variable.value if variable else default
|
102
|
+
|
103
|
+
@classmethod
|
104
|
+
@sync_compatible
|
105
|
+
async def unset(cls, name: str) -> bool:
|
106
|
+
"""
|
107
|
+
Unset a variable by name.
|
108
|
+
|
109
|
+
Args:
|
110
|
+
- name: The name of the variable to unset.
|
111
|
+
|
112
|
+
Returns `True` if the variable was deleted, `False` if the variable did not exist.
|
113
|
+
|
114
|
+
Example:
|
115
|
+
Unset a variable by name.
|
116
|
+
```python
|
117
|
+
from prefect import flow
|
80
118
|
from prefect.variables import Variable
|
81
119
|
|
82
120
|
@flow
|
83
|
-
|
84
|
-
|
85
|
-
|
121
|
+
def my_flow():
|
122
|
+
Variable.unset("my_var")
|
123
|
+
```
|
86
124
|
"""
|
87
125
|
client, _ = get_or_create_client()
|
88
|
-
|
89
|
-
|
126
|
+
try:
|
127
|
+
await client.delete_variable_by_name(name=name)
|
128
|
+
return True
|
129
|
+
except ObjectNotFound:
|
130
|
+
return False
|
90
131
|
|
91
132
|
|
92
|
-
|
93
|
-
@sync_compatible
|
94
|
-
async def get(name: str, default: Optional[str] = None) -> Optional[str]:
|
95
|
-
"""
|
96
|
-
Get a variable by name. If doesn't exist return the default.
|
97
|
-
```
|
98
|
-
from prefect import variables
|
99
|
-
|
100
|
-
@flow
|
101
|
-
def my_flow():
|
102
|
-
var = variables.get("my_var")
|
103
|
-
```
|
104
|
-
or
|
105
|
-
```
|
106
|
-
from prefect import variables
|
107
|
-
|
108
|
-
@flow
|
109
|
-
async def my_flow():
|
110
|
-
var = await variables.get("my_var")
|
111
|
-
```
|
112
|
-
"""
|
113
|
-
variable = await Variable.get(name)
|
114
|
-
return variable.value if variable else default
|
133
|
+
__getattr__ = getattr_migration(__name__)
|
prefect/workers/__init__.py
CHANGED