prefect-client 3.1.5__py3-none-any.whl → 3.1.6__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 +3 -0
- prefect/_internal/compatibility/migration.py +1 -1
- prefect/_internal/concurrency/api.py +52 -52
- prefect/_internal/concurrency/calls.py +59 -35
- prefect/_internal/concurrency/cancellation.py +34 -18
- prefect/_internal/concurrency/event_loop.py +7 -6
- prefect/_internal/concurrency/threads.py +41 -33
- prefect/_internal/concurrency/waiters.py +28 -21
- prefect/_internal/pydantic/v1_schema.py +2 -2
- prefect/_internal/pydantic/v2_schema.py +10 -9
- prefect/_internal/schemas/bases.py +9 -7
- prefect/_internal/schemas/validators.py +2 -1
- prefect/_version.py +3 -3
- prefect/automations.py +53 -47
- prefect/blocks/abstract.py +12 -10
- prefect/blocks/core.py +4 -2
- prefect/cache_policies.py +11 -11
- prefect/client/__init__.py +3 -1
- prefect/client/base.py +36 -37
- prefect/client/cloud.py +26 -19
- prefect/client/collections.py +2 -2
- prefect/client/orchestration.py +342 -273
- prefect/client/schemas/__init__.py +24 -0
- prefect/client/schemas/actions.py +123 -116
- prefect/client/schemas/objects.py +110 -81
- prefect/client/schemas/responses.py +18 -18
- prefect/client/schemas/schedules.py +136 -93
- prefect/client/subscriptions.py +28 -14
- prefect/client/utilities.py +32 -36
- prefect/concurrency/asyncio.py +6 -9
- prefect/concurrency/sync.py +35 -5
- prefect/context.py +39 -31
- prefect/deployments/flow_runs.py +3 -5
- prefect/docker/__init__.py +1 -1
- prefect/events/schemas/events.py +25 -20
- prefect/events/utilities.py +1 -2
- prefect/filesystems.py +3 -3
- prefect/flow_engine.py +61 -21
- prefect/flow_runs.py +3 -3
- prefect/flows.py +214 -170
- prefect/logging/configuration.py +1 -1
- prefect/logging/highlighters.py +1 -2
- prefect/logging/loggers.py +30 -20
- prefect/main.py +17 -24
- prefect/runner/runner.py +43 -21
- prefect/runner/server.py +30 -32
- prefect/runner/submit.py +3 -6
- prefect/runner/utils.py +6 -6
- prefect/runtime/flow_run.py +7 -0
- prefect/settings/constants.py +2 -2
- prefect/settings/legacy.py +1 -1
- prefect/settings/models/server/events.py +10 -0
- prefect/task_engine.py +72 -19
- prefect/task_runners.py +2 -2
- prefect/tasks.py +46 -33
- prefect/telemetry/bootstrap.py +15 -2
- prefect/telemetry/run_telemetry.py +107 -0
- prefect/transactions.py +14 -14
- prefect/types/__init__.py +1 -4
- prefect/utilities/_engine.py +96 -0
- prefect/utilities/annotations.py +25 -18
- prefect/utilities/asyncutils.py +126 -140
- prefect/utilities/callables.py +87 -78
- prefect/utilities/collections.py +278 -117
- prefect/utilities/compat.py +13 -21
- prefect/utilities/context.py +6 -5
- prefect/utilities/dispatch.py +23 -12
- prefect/utilities/dockerutils.py +33 -32
- prefect/utilities/engine.py +126 -239
- prefect/utilities/filesystem.py +18 -15
- prefect/utilities/hashing.py +10 -11
- prefect/utilities/importtools.py +40 -27
- prefect/utilities/math.py +9 -5
- prefect/utilities/names.py +3 -3
- prefect/utilities/processutils.py +121 -57
- prefect/utilities/pydantic.py +41 -36
- prefect/utilities/render_swagger.py +22 -12
- prefect/utilities/schema_tools/__init__.py +2 -1
- prefect/utilities/schema_tools/hydration.py +50 -43
- prefect/utilities/schema_tools/validation.py +52 -42
- prefect/utilities/services.py +13 -12
- prefect/utilities/templating.py +45 -45
- prefect/utilities/text.py +2 -1
- prefect/utilities/timeout.py +4 -4
- prefect/utilities/urls.py +9 -4
- prefect/utilities/visualization.py +46 -24
- prefect/variables.py +9 -8
- prefect/workers/base.py +15 -8
- {prefect_client-3.1.5.dist-info → prefect_client-3.1.6.dist-info}/METADATA +4 -2
- {prefect_client-3.1.5.dist-info → prefect_client-3.1.6.dist-info}/RECORD +93 -91
- {prefect_client-3.1.5.dist-info → prefect_client-3.1.6.dist-info}/LICENSE +0 -0
- {prefect_client-3.1.5.dist-info → prefect_client-3.1.6.dist-info}/WHEEL +0 -0
- {prefect_client-3.1.5.dist-info → prefect_client-3.1.6.dist-info}/top_level.txt +0 -0
prefect/client/cloud.py
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
import re
|
2
|
-
from typing import Any,
|
2
|
+
from typing import Any, NoReturn, Optional, cast
|
3
3
|
from uuid import UUID
|
4
4
|
|
5
5
|
import anyio
|
6
6
|
import httpx
|
7
7
|
import pydantic
|
8
8
|
from starlette import status
|
9
|
+
from typing_extensions import Self
|
9
10
|
|
10
11
|
import prefect.context
|
11
12
|
import prefect.settings
|
@@ -30,7 +31,7 @@ PARSE_API_URL_REGEX = re.compile(r"accounts/(.{36})/workspaces/(.{36})")
|
|
30
31
|
def get_cloud_client(
|
31
32
|
host: Optional[str] = None,
|
32
33
|
api_key: Optional[str] = None,
|
33
|
-
httpx_settings: Optional[dict] = None,
|
34
|
+
httpx_settings: Optional[dict[str, Any]] = None,
|
34
35
|
infer_cloud_url: bool = False,
|
35
36
|
) -> "CloudClient":
|
36
37
|
"""
|
@@ -45,6 +46,9 @@ def get_cloud_client(
|
|
45
46
|
configured_url = prefect.settings.PREFECT_API_URL.value()
|
46
47
|
host = re.sub(PARSE_API_URL_REGEX, "", configured_url)
|
47
48
|
|
49
|
+
if host is None:
|
50
|
+
raise ValueError("Host was not provided and could not be inferred")
|
51
|
+
|
48
52
|
return CloudClient(
|
49
53
|
host=host,
|
50
54
|
api_key=api_key or PREFECT_API_KEY.value(),
|
@@ -59,11 +63,14 @@ class CloudUnauthorizedError(PrefectException):
|
|
59
63
|
|
60
64
|
|
61
65
|
class CloudClient:
|
66
|
+
account_id: Optional[str] = None
|
67
|
+
workspace_id: Optional[str] = None
|
68
|
+
|
62
69
|
def __init__(
|
63
70
|
self,
|
64
71
|
host: str,
|
65
72
|
api_key: str,
|
66
|
-
httpx_settings: Optional[
|
73
|
+
httpx_settings: Optional[dict[str, Any]] = None,
|
67
74
|
) -> None:
|
68
75
|
httpx_settings = httpx_settings or dict()
|
69
76
|
httpx_settings.setdefault("headers", dict())
|
@@ -76,7 +83,7 @@ class CloudClient:
|
|
76
83
|
**httpx_settings, enable_csrf_support=False
|
77
84
|
)
|
78
85
|
|
79
|
-
api_url = prefect.settings.PREFECT_API_URL.value() or ""
|
86
|
+
api_url: str = prefect.settings.PREFECT_API_URL.value() or ""
|
80
87
|
if match := (
|
81
88
|
re.search(PARSE_API_URL_REGEX, host)
|
82
89
|
or re.search(PARSE_API_URL_REGEX, api_url)
|
@@ -97,7 +104,7 @@ class CloudClient:
|
|
97
104
|
|
98
105
|
return f"{self.account_base_url}/workspaces/{self.workspace_id}"
|
99
106
|
|
100
|
-
async def api_healthcheck(self):
|
107
|
+
async def api_healthcheck(self) -> None:
|
101
108
|
"""
|
102
109
|
Attempts to connect to the Cloud API and raises the encountered exception if not
|
103
110
|
successful.
|
@@ -107,8 +114,8 @@ class CloudClient:
|
|
107
114
|
with anyio.fail_after(10):
|
108
115
|
await self.read_workspaces()
|
109
116
|
|
110
|
-
async def read_workspaces(self) ->
|
111
|
-
workspaces = pydantic.TypeAdapter(
|
117
|
+
async def read_workspaces(self) -> list[Workspace]:
|
118
|
+
workspaces = pydantic.TypeAdapter(list[Workspace]).validate_python(
|
112
119
|
await self.get("/me/workspaces")
|
113
120
|
)
|
114
121
|
return workspaces
|
@@ -121,17 +128,17 @@ class CloudClient:
|
|
121
128
|
return workspace
|
122
129
|
raise ValueError("Current workspace not found")
|
123
130
|
|
124
|
-
async def read_worker_metadata(self) ->
|
131
|
+
async def read_worker_metadata(self) -> dict[str, Any]:
|
125
132
|
response = await self.get(
|
126
133
|
f"{self.workspace_base_url}/collections/work_pool_types"
|
127
134
|
)
|
128
|
-
return cast(
|
135
|
+
return cast(dict[str, Any], response)
|
129
136
|
|
130
|
-
async def read_account_settings(self) ->
|
137
|
+
async def read_account_settings(self) -> dict[str, Any]:
|
131
138
|
response = await self.get(f"{self.account_base_url}/settings")
|
132
|
-
return cast(
|
139
|
+
return cast(dict[str, Any], response)
|
133
140
|
|
134
|
-
async def update_account_settings(self, settings:
|
141
|
+
async def update_account_settings(self, settings: dict[str, Any]) -> None:
|
135
142
|
await self.request(
|
136
143
|
"PATCH",
|
137
144
|
f"{self.account_base_url}/settings",
|
@@ -142,7 +149,7 @@ class CloudClient:
|
|
142
149
|
response = await self.get(f"{self.account_base_url}/ip_allowlist")
|
143
150
|
return IPAllowlist.model_validate(response)
|
144
151
|
|
145
|
-
async def update_account_ip_allowlist(self, updated_allowlist: IPAllowlist):
|
152
|
+
async def update_account_ip_allowlist(self, updated_allowlist: IPAllowlist) -> None:
|
146
153
|
await self.request(
|
147
154
|
"PUT",
|
148
155
|
f"{self.account_base_url}/ip_allowlist",
|
@@ -172,26 +179,26 @@ class CloudClient:
|
|
172
179
|
json=labels,
|
173
180
|
)
|
174
181
|
|
175
|
-
async def __aenter__(self):
|
182
|
+
async def __aenter__(self) -> Self:
|
176
183
|
await self._client.__aenter__()
|
177
184
|
return self
|
178
185
|
|
179
|
-
async def __aexit__(self, *exc_info):
|
186
|
+
async def __aexit__(self, *exc_info: Any) -> None:
|
180
187
|
return await self._client.__aexit__(*exc_info)
|
181
188
|
|
182
|
-
def __enter__(self):
|
189
|
+
def __enter__(self) -> NoReturn:
|
183
190
|
raise RuntimeError(
|
184
191
|
"The `CloudClient` must be entered with an async context. Use 'async "
|
185
192
|
"with CloudClient(...)' not 'with CloudClient(...)'"
|
186
193
|
)
|
187
194
|
|
188
|
-
def __exit__(self, *_):
|
195
|
+
def __exit__(self, *_: object) -> NoReturn:
|
189
196
|
assert False, "This should never be called but must be defined for __enter__"
|
190
197
|
|
191
|
-
async def get(self, route, **kwargs):
|
198
|
+
async def get(self, route: str, **kwargs: Any) -> Any:
|
192
199
|
return await self.request("GET", route, **kwargs)
|
193
200
|
|
194
|
-
async def request(self, method, route, **kwargs):
|
201
|
+
async def request(self, method: str, route: str, **kwargs: Any) -> Any:
|
195
202
|
try:
|
196
203
|
res = await self._client.request(method, route, **kwargs)
|
197
204
|
res.raise_for_status()
|
prefect/client/collections.py
CHANGED
@@ -13,12 +13,12 @@ class CollectionsMetadataClient(Protocol):
|
|
13
13
|
async def __aenter__(self) -> "CollectionsMetadataClient":
|
14
14
|
...
|
15
15
|
|
16
|
-
async def __aexit__(self, *exc_info) -> Any:
|
16
|
+
async def __aexit__(self, *exc_info: Any) -> Any:
|
17
17
|
...
|
18
18
|
|
19
19
|
|
20
20
|
def get_collections_metadata_client(
|
21
|
-
httpx_settings: Optional[Dict] = None,
|
21
|
+
httpx_settings: Optional[Dict[str, Any]] = None,
|
22
22
|
) -> "CollectionsMetadataClient":
|
23
23
|
"""
|
24
24
|
Creates a client that can be used to fetch metadata for
|