prefect-client 3.7.3.dev2__py3-none-any.whl → 3.7.3.dev4__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/_build_info.py +3 -3
- prefect/client/orchestration/__init__.py +10 -3
- prefect/runner/_workspace_resolver.py +83 -5
- prefect/workers/_worker_channel/_transport.py +6 -1
- {prefect_client-3.7.3.dev2.dist-info → prefect_client-3.7.3.dev4.dist-info}/METADATA +1 -1
- {prefect_client-3.7.3.dev2.dist-info → prefect_client-3.7.3.dev4.dist-info}/RECORD +8 -8
- {prefect_client-3.7.3.dev2.dist-info → prefect_client-3.7.3.dev4.dist-info}/WHEEL +0 -0
- {prefect_client-3.7.3.dev2.dist-info → prefect_client-3.7.3.dev4.dist-info}/licenses/LICENSE +0 -0
prefect/_build_info.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Generated by versioningit
|
|
2
|
-
__version__ = "3.7.3.
|
|
3
|
-
__build_date__ = "2026-05-
|
|
4
|
-
__git_commit__ = "
|
|
2
|
+
__version__ = "3.7.3.dev4"
|
|
3
|
+
__build_date__ = "2026-05-27 09:16:21.912708+00:00"
|
|
4
|
+
__git_commit__ = "bbfa2910a7234f773a7a12cd4c7fcf8a4ce9708a"
|
|
5
5
|
__dirty__ = False
|
|
@@ -137,6 +137,7 @@ from prefect.settings import (
|
|
|
137
137
|
)
|
|
138
138
|
from prefect.types._datetime import now
|
|
139
139
|
|
|
140
|
+
from prefect._internal.urls import strip_auth_from_url
|
|
140
141
|
from prefect._internal.version_checking import (
|
|
141
142
|
_api_version_check_key,
|
|
142
143
|
_cache_api_version_check,
|
|
@@ -1132,7 +1133,9 @@ class PrefectClient(
|
|
|
1132
1133
|
except Exception as e:
|
|
1133
1134
|
if "Unauthorized" in str(e):
|
|
1134
1135
|
raise e
|
|
1135
|
-
raise RuntimeError(
|
|
1136
|
+
raise RuntimeError(
|
|
1137
|
+
f"Failed to reach API at {strip_auth_from_url(str(self.api_url))}"
|
|
1138
|
+
) from e
|
|
1136
1139
|
|
|
1137
1140
|
api_version = version.parse(api_version)
|
|
1138
1141
|
client_version = version.parse(self.client_version())
|
|
@@ -1190,7 +1193,9 @@ class PrefectClient(
|
|
|
1190
1193
|
f"{PREFECT_API_DATABASE_CONNECTION_URL.value()}"
|
|
1191
1194
|
)
|
|
1192
1195
|
else:
|
|
1193
|
-
self.logger.debug(
|
|
1196
|
+
self.logger.debug(
|
|
1197
|
+
f"Connecting to API at {strip_auth_from_url(str(self.api_url))}"
|
|
1198
|
+
)
|
|
1194
1199
|
|
|
1195
1200
|
# Enter the httpx client's context
|
|
1196
1201
|
await self._exit_stack.enter_async_context(self._client)
|
|
@@ -1519,7 +1524,9 @@ class SyncPrefectClient(
|
|
|
1519
1524
|
except Exception as e:
|
|
1520
1525
|
if "Unauthorized" in str(e):
|
|
1521
1526
|
raise e
|
|
1522
|
-
raise RuntimeError(
|
|
1527
|
+
raise RuntimeError(
|
|
1528
|
+
f"Failed to reach API at {strip_auth_from_url(str(self.api_url))}"
|
|
1529
|
+
) from e
|
|
1523
1530
|
|
|
1524
1531
|
api_version = version.parse(api_version)
|
|
1525
1532
|
client_version = version.parse(self.client_version())
|
|
@@ -174,6 +174,61 @@ def _workspace_destination_for_deployment_path(
|
|
|
174
174
|
return (workspace_root / relative_destination).resolve()
|
|
175
175
|
|
|
176
176
|
|
|
177
|
+
def _resolve_local_runtime_directory(
|
|
178
|
+
path: str | None, source_cwd: Path, storage_base_path: Path | None
|
|
179
|
+
) -> Path:
|
|
180
|
+
resolved_path = _resolve_local_deployment_path(path, source_cwd, storage_base_path)
|
|
181
|
+
return Path(resolved_path).resolve() if resolved_path is not None else source_cwd
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def _entrypoint_file_path(entrypoint: str, working_directory: Path) -> Path | None:
|
|
185
|
+
entrypoint = _resolve_runtime_entrypoint(entrypoint)
|
|
186
|
+
if ":" not in entrypoint:
|
|
187
|
+
return None
|
|
188
|
+
|
|
189
|
+
path, _object_name = entrypoint.rsplit(":", 1)
|
|
190
|
+
if not path.endswith(".py"):
|
|
191
|
+
return None
|
|
192
|
+
|
|
193
|
+
entrypoint_path = Path(path).expanduser()
|
|
194
|
+
if not entrypoint_path.is_absolute():
|
|
195
|
+
entrypoint_path = working_directory / entrypoint_path
|
|
196
|
+
return entrypoint_path.resolve()
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _has_entrypoint_file(entrypoint: str, working_directory: Path) -> bool:
|
|
200
|
+
entrypoint_path = _entrypoint_file_path(entrypoint, working_directory)
|
|
201
|
+
return entrypoint_path is not None and entrypoint_path.is_file()
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
async def _ensure_entrypoint_in_workspace(
|
|
205
|
+
client: "PrefectClient",
|
|
206
|
+
deployment: "DeploymentResponse",
|
|
207
|
+
workspace_root: Path,
|
|
208
|
+
source_cwd: Path,
|
|
209
|
+
storage_base_path: Path | None,
|
|
210
|
+
) -> Path:
|
|
211
|
+
if _has_entrypoint_file(deployment.entrypoint, workspace_root):
|
|
212
|
+
return workspace_root
|
|
213
|
+
|
|
214
|
+
local_runtime_directory = _resolve_local_runtime_directory(
|
|
215
|
+
deployment.path, source_cwd, storage_base_path
|
|
216
|
+
)
|
|
217
|
+
if not deployment.storage_document_id and not _has_entrypoint_file(
|
|
218
|
+
deployment.entrypoint, local_runtime_directory
|
|
219
|
+
):
|
|
220
|
+
return workspace_root
|
|
221
|
+
|
|
222
|
+
await _pull_storage_into_workspace(
|
|
223
|
+
client,
|
|
224
|
+
deployment,
|
|
225
|
+
workspace_root,
|
|
226
|
+
source_cwd,
|
|
227
|
+
storage_base_path,
|
|
228
|
+
)
|
|
229
|
+
return workspace_root
|
|
230
|
+
|
|
231
|
+
|
|
177
232
|
@contextlib.contextmanager
|
|
178
233
|
def _redirect_stdout_to_stderr() -> Any:
|
|
179
234
|
stdout = sys.stdout
|
|
@@ -218,9 +273,12 @@ async def _pull_storage_into_workspace(
|
|
|
218
273
|
else None
|
|
219
274
|
)
|
|
220
275
|
else:
|
|
221
|
-
|
|
276
|
+
resolved_local_path = _resolve_local_deployment_path(
|
|
222
277
|
deployment.path, source_cwd, storage_base_path
|
|
223
278
|
)
|
|
279
|
+
from_path = (
|
|
280
|
+
resolved_local_path if resolved_local_path is not None else str(source_cwd)
|
|
281
|
+
)
|
|
224
282
|
storage_block = LocalFileSystem(basepath=from_path)
|
|
225
283
|
|
|
226
284
|
LOGGER.info("Downloading flow code from storage at %r", from_path)
|
|
@@ -253,11 +311,17 @@ async def prepare_workspace(
|
|
|
253
311
|
source_cwd,
|
|
254
312
|
storage_base_path,
|
|
255
313
|
)
|
|
256
|
-
|
|
257
|
-
|
|
314
|
+
local_runtime_directory = _resolve_local_runtime_directory(
|
|
315
|
+
deployment.path, source_cwd, storage_base_path
|
|
316
|
+
)
|
|
317
|
+
if not _has_entrypoint_file(
|
|
318
|
+
deployment.entrypoint, working_directory
|
|
319
|
+
) and _has_entrypoint_file(deployment.entrypoint, local_runtime_directory):
|
|
320
|
+
working_directory = local_runtime_directory
|
|
258
321
|
else:
|
|
322
|
+
working_directory = resolved_workspace_root
|
|
323
|
+
step_selected_working_directory = False
|
|
259
324
|
os.chdir(resolved_workspace_root)
|
|
260
|
-
working_directory = Path.cwd().resolve()
|
|
261
325
|
LOGGER.info("Running %s deployment pull step(s)", len(deployment.pull_steps))
|
|
262
326
|
|
|
263
327
|
def _track_step_workspace(
|
|
@@ -266,17 +330,19 @@ async def prepare_workspace(
|
|
|
266
330
|
step_start_cwd: Path | None,
|
|
267
331
|
step_end_cwd: Path | None,
|
|
268
332
|
) -> None:
|
|
269
|
-
nonlocal working_directory
|
|
333
|
+
nonlocal step_selected_working_directory, working_directory
|
|
270
334
|
|
|
271
335
|
if isinstance(step_output, dict) and step_output.get("directory"):
|
|
272
336
|
resolved_directory = _resolve_directory_output(
|
|
273
337
|
step_output, step_end_cwd
|
|
274
338
|
)
|
|
275
339
|
if resolved_directory is not None:
|
|
340
|
+
step_selected_working_directory = True
|
|
276
341
|
working_directory = resolved_directory
|
|
277
342
|
return
|
|
278
343
|
|
|
279
344
|
if step_end_cwd is not None and step_end_cwd != step_start_cwd:
|
|
345
|
+
step_selected_working_directory = True
|
|
280
346
|
working_directory = step_end_cwd
|
|
281
347
|
|
|
282
348
|
with _observe_step_completion(_track_step_workspace):
|
|
@@ -288,6 +354,18 @@ async def prepare_workspace(
|
|
|
288
354
|
logger=LOGGER,
|
|
289
355
|
)
|
|
290
356
|
|
|
357
|
+
if not step_selected_working_directory:
|
|
358
|
+
working_directory = await _ensure_entrypoint_in_workspace(
|
|
359
|
+
client,
|
|
360
|
+
deployment,
|
|
361
|
+
resolved_workspace_root,
|
|
362
|
+
source_cwd,
|
|
363
|
+
storage_base_path,
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
os.chdir(working_directory)
|
|
367
|
+
working_directory = Path.cwd().resolve()
|
|
368
|
+
|
|
291
369
|
project_root = _find_project_root(working_directory, resolved_workspace_root)
|
|
292
370
|
return PreparedWorkspace(
|
|
293
371
|
workspace_root=resolved_workspace_root,
|
|
@@ -235,11 +235,16 @@ class WorkerChannelTransport:
|
|
|
235
235
|
|
|
236
236
|
return None
|
|
237
237
|
|
|
238
|
+
_MAX_RECONNECT_EXPONENT = 32
|
|
239
|
+
|
|
238
240
|
def reconnect_delay(self, attempt: int) -> float:
|
|
239
241
|
if self._reconnect_base_seconds <= 0:
|
|
240
242
|
return 0
|
|
243
|
+
exponent = max(attempt - 1, 0)
|
|
244
|
+
if exponent >= self._MAX_RECONNECT_EXPONENT:
|
|
245
|
+
return self._reconnect_max_seconds
|
|
241
246
|
return min(
|
|
242
|
-
self._reconnect_base_seconds * 2
|
|
247
|
+
self._reconnect_base_seconds * 2**exponent,
|
|
243
248
|
self._reconnect_max_seconds,
|
|
244
249
|
)
|
|
245
250
|
|
|
@@ -2,7 +2,7 @@ prefect/.prefectignore,sha256=awSprvKT0vI8a64mEOLrMxhxqcO-b0ERQeYpA2rNKVQ,390
|
|
|
2
2
|
prefect/AGENTS.md,sha256=rOU4L6B0ZdvnVmLr_eL394QlwfJkPh1OZswHppAjUN4,10063
|
|
3
3
|
prefect/__init__.py,sha256=Z8rwfLbEOLh-5WcznTZP3FG2-9UgGZxY-prj8sL0-Qk,6828
|
|
4
4
|
prefect/__main__.py,sha256=WFjw3kaYJY6pOTA7WDOgqjsz8zUEUZHCcj3P5wyVa-g,66
|
|
5
|
-
prefect/_build_info.py,sha256=
|
|
5
|
+
prefect/_build_info.py,sha256=h8w9MfRbAgYQChR0tvUubuiUXzHzSdQXN31G9PFC30Q,185
|
|
6
6
|
prefect/_flow_run_suspension.py,sha256=5zTTB7ZIBHzoS0pVrhNn23-9hK51qZ3CQA6C-azluC0,4144
|
|
7
7
|
prefect/agent.py,sha256=dPvG1jDGD5HSH7aM2utwtk6RaJ9qg13XjkA0lAIgQmY,287
|
|
8
8
|
prefect/artifacts.py,sha256=ZdMLJeJGK82hibtRzbsVa-g95dMa0D2UP1LiESoXmf4,23951
|
|
@@ -158,7 +158,7 @@ prefect/client/collections.py,sha256=t9XkVU_onQMZ871L21F1oZnAiPSQeeVfd_MuDEBS3iM
|
|
|
158
158
|
prefect/client/constants.py,sha256=Z_GG8KF70vbbXxpJuqW5pLnwzujTVeHbcYYRikNmGH0,29
|
|
159
159
|
prefect/client/subscriptions.py,sha256=F7fNSJNpQ2ORaYQ6n5Py72r-4JQ7Pccd71eER68jehg,4385
|
|
160
160
|
prefect/client/utilities.py,sha256=UEJD6nwYg2mD8-GSmru-E2ofXaBlmSFZ2-8T_5rIK6c,3472
|
|
161
|
-
prefect/client/orchestration/__init__.py,sha256=
|
|
161
|
+
prefect/client/orchestration/__init__.py,sha256=r6TxprXXvcFCPHHb3-r0roznmW7g1w7J7LOxnoNupxw,74214
|
|
162
162
|
prefect/client/orchestration/base.py,sha256=HM6ryHBZSzuHoCFQM9u5qR5k1dN9Bbr_ah6z1UPNbZQ,1542
|
|
163
163
|
prefect/client/orchestration/routes.py,sha256=YTA183Auz6LN4fqq6uLWxGLupOv6PWf0CtTp1xonXJ4,4446
|
|
164
164
|
prefect/client/orchestration/_artifacts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -286,7 +286,7 @@ prefect/runner/_starter_bundle.py,sha256=ghYK0zufuW0B5u-EPNl8uP2OiUGCZQsuTgdFxQv
|
|
|
286
286
|
prefect/runner/_starter_direct.py,sha256=8cneJRIBud3HXUaf93ut92rQJfWEqg7_y0r_EVGf0ps,2730
|
|
287
287
|
prefect/runner/_starter_engine.py,sha256=FjcHQe_iryk8BFpeiGw8MCWcLSRKhYwmb2iA4eou0zg,6507
|
|
288
288
|
prefect/runner/_state_proposer.py,sha256=iW-SlB5EOWHErWbyRJwRTirfqwo0BJ1fAlbScVi6vcg,7225
|
|
289
|
-
prefect/runner/_workspace_resolver.py,sha256=
|
|
289
|
+
prefect/runner/_workspace_resolver.py,sha256=2wQ7PXTanHY5yVGqhZuGh122DvNpTNZXEY_rMfexEtE,14020
|
|
290
290
|
prefect/runner/_workspace_starter.py,sha256=M8R9JGjLJgS3qm3ZpzpyZ2_3aGGVaHXu55M25k7nxd8,9673
|
|
291
291
|
prefect/runner/runner.py,sha256=O4krExcrpdS3T7pe6RLSfQbpkup8-SltDYS0E7p3obA,75799
|
|
292
292
|
prefect/runner/server.py,sha256=YqvQjlxZZHyhSsqyaLvOy2NwTDg1hLSZB2PK3t8FJUg,3636
|
|
@@ -438,8 +438,8 @@ prefect/workers/_worker_channel/__init__.py,sha256=vEc7NvC1sjxnCn5thQv5lSU1bDKRa
|
|
|
438
438
|
prefect/workers/_worker_channel/_protocol.py,sha256=GpCNh1o3qmmqHA_UOOTge1QVC6IRvWP2RdpAEBqXPs0,15834
|
|
439
439
|
prefect/workers/_worker_channel/_state.py,sha256=eQTFZtAVDZH1vVWps3SdeY6aW3qu2wx1UKYQXK3AyuE,5369
|
|
440
440
|
prefect/workers/_worker_channel/_sync.py,sha256=G5G8_UaQYbeLebi5Mb1Z_KgGfXfyjXo5uT9la5_zwqY,14984
|
|
441
|
-
prefect/workers/_worker_channel/_transport.py,sha256=
|
|
442
|
-
prefect_client-3.7.3.
|
|
443
|
-
prefect_client-3.7.3.
|
|
444
|
-
prefect_client-3.7.3.
|
|
445
|
-
prefect_client-3.7.3.
|
|
441
|
+
prefect/workers/_worker_channel/_transport.py,sha256=_8aWX16tdbZcpqBg4HCX_vCzl2FX47jsYPKMPLAANRA,9181
|
|
442
|
+
prefect_client-3.7.3.dev4.dist-info/METADATA,sha256=_g_b2vTdyJ6Thx_yD9iISgKZRG0H0BwlrUvAqFgTbo0,7495
|
|
443
|
+
prefect_client-3.7.3.dev4.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
444
|
+
prefect_client-3.7.3.dev4.dist-info/licenses/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
|
|
445
|
+
prefect_client-3.7.3.dev4.dist-info/RECORD,,
|
|
File without changes
|
{prefect_client-3.7.3.dev2.dist-info → prefect_client-3.7.3.dev4.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|