prefect 3.7.9.dev2__py3-none-any.whl → 3.7.9.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/cli/deploy/_config.py +3 -1
- prefect/cli/deploy/_core.py +28 -12
- prefect/server/api/collections_data/views/aggregate-worker-metadata.json +1 -0
- prefect/server/orchestration/global_policy.py +75 -16
- {prefect-3.7.9.dev2.dist-info → prefect-3.7.9.dev4.dist-info}/METADATA +1 -1
- {prefect-3.7.9.dev2.dist-info → prefect-3.7.9.dev4.dist-info}/RECORD +10 -10
- {prefect-3.7.9.dev2.dist-info → prefect-3.7.9.dev4.dist-info}/WHEEL +0 -0
- {prefect-3.7.9.dev2.dist-info → prefect-3.7.9.dev4.dist-info}/entry_points.txt +0 -0
- {prefect-3.7.9.dev2.dist-info → prefect-3.7.9.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.9.
|
|
3
|
-
__build_date__ = "2026-07-
|
|
4
|
-
__git_commit__ = "
|
|
2
|
+
__version__ = "3.7.9.dev4"
|
|
3
|
+
__build_date__ = "2026-07-18 08:39:23.510683+00:00"
|
|
4
|
+
__git_commit__ = "60025750fb7ea1d69fef8a1c8b1e013cdc8149ae"
|
|
5
5
|
__dirty__ = False
|
prefect/cli/deploy/_config.py
CHANGED
|
@@ -158,7 +158,9 @@ def _load_deploy_configs_and_actions(
|
|
|
158
158
|
actions: dict[str, Any] = {
|
|
159
159
|
"build": model.build or [],
|
|
160
160
|
"push": model.push or [],
|
|
161
|
-
|
|
161
|
+
# Preserve the distinction between an omitted/`null` pull (auto-generate a
|
|
162
|
+
# default pull action) and an explicit empty `pull: []` (no pull steps).
|
|
163
|
+
"pull": model.pull,
|
|
162
164
|
}
|
|
163
165
|
# Convert Pydantic models to plain dicts for downstream consumption,
|
|
164
166
|
# excluding keys that were not provided by users to preserve legacy semantics
|
prefect/cli/deploy/_core.py
CHANGED
|
@@ -90,6 +90,14 @@ async def _run_single_deploy(
|
|
|
90
90
|
push_steps = deploy_config.get("push", actions.get("push")) or []
|
|
91
91
|
pull_steps = deploy_config.get("pull", actions.get("pull")) or []
|
|
92
92
|
|
|
93
|
+
# An explicit empty `pull: []` (deployment-level takes precedence over the
|
|
94
|
+
# top-level definition) means "no pull steps". This differs from an
|
|
95
|
+
# omitted/`null` pull, which triggers default pull-action generation.
|
|
96
|
+
effective_pull = (
|
|
97
|
+
deploy_config["pull"] if "pull" in deploy_config else actions.get("pull")
|
|
98
|
+
)
|
|
99
|
+
explicit_no_pull = effective_pull == []
|
|
100
|
+
|
|
93
101
|
deploy_config = await resolve_block_document_references(deploy_config)
|
|
94
102
|
deploy_config = await resolve_variables(deploy_config)
|
|
95
103
|
|
|
@@ -237,6 +245,7 @@ async def _run_single_deploy(
|
|
|
237
245
|
## CONFIGURE PUSH and/or PULL STEPS FOR REMOTE FLOW STORAGE
|
|
238
246
|
if (
|
|
239
247
|
is_interactive()
|
|
248
|
+
and not explicit_no_pull
|
|
240
249
|
and not (deploy_config.get("pull") or actions.get("pull"))
|
|
241
250
|
and not docker_push_step_exists
|
|
242
251
|
and confirm(
|
|
@@ -255,18 +264,23 @@ async def _run_single_deploy(
|
|
|
255
264
|
|
|
256
265
|
# Prefer the originally captured pull_steps (taken before resolution) to
|
|
257
266
|
# preserve unresolved block placeholders in the deployment spec. Only fall
|
|
258
|
-
# back to the config/actions/default if no pull steps were provided.
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
267
|
+
# back to the config/actions/default if no pull steps were provided. An
|
|
268
|
+
# explicit empty `pull: []` disables pull steps entirely and skips default
|
|
269
|
+
# pull-action generation.
|
|
270
|
+
if explicit_no_pull:
|
|
271
|
+
pull_steps = []
|
|
272
|
+
else:
|
|
273
|
+
pull_steps = (
|
|
274
|
+
pull_steps
|
|
275
|
+
or deploy_config.get("pull")
|
|
276
|
+
or actions.get("pull")
|
|
277
|
+
or await _generate_default_pull_action(
|
|
278
|
+
console,
|
|
279
|
+
deploy_config=deploy_config,
|
|
280
|
+
actions=actions,
|
|
281
|
+
is_interactive=is_interactive,
|
|
282
|
+
)
|
|
268
283
|
)
|
|
269
|
-
)
|
|
270
284
|
|
|
271
285
|
## RUN BUILD AND PUSH STEPS
|
|
272
286
|
step_outputs: dict[str, Any] = {}
|
|
@@ -438,7 +452,9 @@ async def _run_single_deploy(
|
|
|
438
452
|
deploy_config_before_templating,
|
|
439
453
|
build_steps=build_steps or None,
|
|
440
454
|
push_steps=push_steps or None,
|
|
441
|
-
|
|
455
|
+
# Preserve an explicit empty `pull: []` when saving so the
|
|
456
|
+
# no-pull setting survives; otherwise collapse falsey pull to None.
|
|
457
|
+
pull_steps=pull_steps if explicit_no_pull else (pull_steps or None),
|
|
442
458
|
triggers=trigger_specs or None,
|
|
443
459
|
sla=sla_specs or None,
|
|
444
460
|
prefect_file=prefect_file,
|
|
@@ -10,8 +10,10 @@ state database, they should be the most deeply nested contexts in orchestration
|
|
|
10
10
|
|
|
11
11
|
from __future__ import annotations
|
|
12
12
|
|
|
13
|
+
from datetime import timedelta
|
|
13
14
|
from typing import Any, Union, cast
|
|
14
15
|
|
|
16
|
+
import sqlalchemy as sa
|
|
15
17
|
from packaging.version import Version
|
|
16
18
|
|
|
17
19
|
import prefect.server.models as models
|
|
@@ -66,22 +68,32 @@ class GlobalFlowPolicy(BaseOrchestrationPolicy[orm_models.FlowRun, core.FlowRunP
|
|
|
66
68
|
type[BaseOrchestrationRule[orm_models.FlowRun, core.FlowRunPolicy]],
|
|
67
69
|
]
|
|
68
70
|
]:
|
|
69
|
-
return
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
71
|
+
return (
|
|
72
|
+
[EnsureFlowRunStateTimestampIsUnique]
|
|
73
|
+
+ cast(
|
|
74
|
+
list[
|
|
75
|
+
Union[
|
|
76
|
+
type[
|
|
77
|
+
BaseUniversalTransform[
|
|
78
|
+
orm_models.FlowRun, core.FlowRunPolicy
|
|
79
|
+
]
|
|
80
|
+
],
|
|
81
|
+
type[
|
|
82
|
+
BaseOrchestrationRule[
|
|
83
|
+
orm_models.FlowRun, core.FlowRunPolicy
|
|
84
|
+
]
|
|
85
|
+
],
|
|
86
|
+
]
|
|
87
|
+
],
|
|
88
|
+
COMMON_GLOBAL_TRANSFORMS(),
|
|
89
|
+
)
|
|
90
|
+
+ [
|
|
91
|
+
UpdateSubflowParentTask,
|
|
92
|
+
UpdateSubflowStateDetails,
|
|
93
|
+
IncrementFlowRunCount,
|
|
94
|
+
RemoveResumingIndicator,
|
|
95
|
+
]
|
|
96
|
+
)
|
|
85
97
|
|
|
86
98
|
|
|
87
99
|
class GlobalTaskPolicy(BaseOrchestrationPolicy[orm_models.TaskRun, core.TaskRunPolicy]):
|
|
@@ -112,6 +124,53 @@ class GlobalTaskPolicy(BaseOrchestrationPolicy[orm_models.TaskRun, core.TaskRunP
|
|
|
112
124
|
) + [IncrementTaskRunCount]
|
|
113
125
|
|
|
114
126
|
|
|
127
|
+
class EnsureFlowRunStateTimestampIsUnique(
|
|
128
|
+
FlowRunUniversalTransform[orm_models.FlowRun, core.FlowRunPolicy]
|
|
129
|
+
):
|
|
130
|
+
"""
|
|
131
|
+
Prevents a flow run's states from sharing a timestamp.
|
|
132
|
+
|
|
133
|
+
State timestamps are minted server-side from the wall clock. On platforms with
|
|
134
|
+
coarse clock resolution (notably Windows, ~15.6ms) several states written for the
|
|
135
|
+
same flow run within a single clock tick can receive identical timestamps,
|
|
136
|
+
violating the unique `(flow_run_id, timestamp)` constraint. When the proposed
|
|
137
|
+
timestamp collides with a persisted state, advance it to the first available
|
|
138
|
+
microsecond after the collision. This handles repeated collisions while keeping
|
|
139
|
+
explicitly backdated states near their intended timestamp.
|
|
140
|
+
|
|
141
|
+
This transform must run before the transforms that read `proposed_state.timestamp`
|
|
142
|
+
(e.g. `SetRunStateTimestamp`, `SetStartTime`, `SetEndTime`, `IncrementRunTime`) so
|
|
143
|
+
the adjusted timestamp is reflected consistently in the persisted state, the run's
|
|
144
|
+
denormalized timestamps, and its runtime accounting.
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
async def before_transition(
|
|
148
|
+
self, context: OrchestrationContext[orm_models.FlowRun, core.FlowRunPolicy]
|
|
149
|
+
) -> None:
|
|
150
|
+
if self.nullified_transition():
|
|
151
|
+
return
|
|
152
|
+
|
|
153
|
+
proposed_state = context.proposed_state
|
|
154
|
+
if proposed_state is None:
|
|
155
|
+
return
|
|
156
|
+
|
|
157
|
+
candidate_timestamp = proposed_state.timestamp
|
|
158
|
+
while (
|
|
159
|
+
await context.session.scalar(
|
|
160
|
+
sa.select(orm_models.FlowRunState.timestamp)
|
|
161
|
+
.where(
|
|
162
|
+
orm_models.FlowRunState.flow_run_id == context.run.id,
|
|
163
|
+
orm_models.FlowRunState.timestamp == candidate_timestamp,
|
|
164
|
+
)
|
|
165
|
+
.limit(1)
|
|
166
|
+
)
|
|
167
|
+
is not None
|
|
168
|
+
):
|
|
169
|
+
candidate_timestamp += timedelta(microseconds=1)
|
|
170
|
+
|
|
171
|
+
proposed_state.timestamp = candidate_timestamp
|
|
172
|
+
|
|
173
|
+
|
|
115
174
|
class SetRunStateType(
|
|
116
175
|
BaseUniversalTransform[
|
|
117
176
|
orm_models.Run, Union[core.FlowRunPolicy, core.TaskRunPolicy]
|
|
@@ -2,7 +2,7 @@ prefect/.prefectignore,sha256=awSprvKT0vI8a64mEOLrMxhxqcO-b0ERQeYpA2rNKVQ,390
|
|
|
2
2
|
prefect/AGENTS.md,sha256=H7j73ZMACxsIfHXO6pTAdyQy2yi7XGnADtgwcMqMVO4,11049
|
|
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=AWATDlKtJxBAeNA9P88peiYj33uWejBKcXHVJ0EMS9c,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
|
|
@@ -195,8 +195,8 @@ prefect/cli/cloud/webhook.py,sha256=j0nzupRem5gr1cLutrO5ALhDaiTeNWTBusq1c-UBArI,
|
|
|
195
195
|
prefect/cli/deploy/__init__.py,sha256=plVbJQ0ZDPsTFCRL7SYZXUhXaUi0KNU86dlydBeKGjs,121
|
|
196
196
|
prefect/cli/deploy/_actions.py,sha256=5ORSReuDpdttxsNQTRNyXYl1HxRnCpEut-LVrlaiJ1U,10659
|
|
197
197
|
prefect/cli/deploy/_commands.py,sha256=ofKDJ0KVTdEZy3BraJoaltKjxhZbDgTrq8xg4dk4IGg,16280
|
|
198
|
-
prefect/cli/deploy/_config.py,sha256=
|
|
199
|
-
prefect/cli/deploy/_core.py,sha256=
|
|
198
|
+
prefect/cli/deploy/_config.py,sha256=T9525VOvUT8GP1-If3nGq8NPjToFCm2kW8q4kYEG0bA,19403
|
|
199
|
+
prefect/cli/deploy/_core.py,sha256=Cs9DMBnzlmzfu9cvuNX8qIWy46nnqsTixgyCpBGoHos,21380
|
|
200
200
|
prefect/cli/deploy/_models.py,sha256=nkS85-OTz4wCzrlKkGqUKwXqHtzyfwbv-0MSC7eHnmE,6102
|
|
201
201
|
prefect/cli/deploy/_schedules.py,sha256=10uB_aHM-wdWKmHosAm3ycMSRaOshgeF3kr1A0YaZ74,3236
|
|
202
202
|
prefect/cli/deploy/_sla.py,sha256=1-D0t30kGzs1Jq2hTu2h1kNXS6JKq5t71I_7INI9_bE,1903
|
|
@@ -413,7 +413,7 @@ prefect/server/api/validation.py,sha256=DPofXjLFejs_qusUQgzRkG89X2EFoviAy9J08pnN
|
|
|
413
413
|
prefect/server/api/variables.py,sha256=8Ursuf20R5zXUS015ZexCH72K7R6Yv76ehkr_l3Xt0k,6186
|
|
414
414
|
prefect/server/api/work_queues.py,sha256=wEb_Hx1MlTrg5juOguk5nvGKwLmTGSIHEUyt_-2GJiE,11957
|
|
415
415
|
prefect/server/api/workers.py,sha256=zUxF-ilf-Z9EuXZcqEk-IIbUmZI2v8dpGzhwXayg53Y,46264
|
|
416
|
-
prefect/server/api/collections_data/views/aggregate-worker-metadata.json,sha256=
|
|
416
|
+
prefect/server/api/collections_data/views/aggregate-worker-metadata.json,sha256=u5zqD8sY2BNrNoMohlr5Z9xMG0gcwqc5yi_Py4vPO_s,81555
|
|
417
417
|
prefect/server/api/static/prefect-logo-mark-gradient.png,sha256=ylRjJkI_JHCw8VbQasNnXQHwZW-sH-IQiUGSD3aWP1E,73430
|
|
418
418
|
prefect/server/api/ui/__init__.py,sha256=TCXO4ZUZCqCbm2QoNvWNTErkzWiX2nSACuO-0Tiomvg,93
|
|
419
419
|
prefect/server/api/ui/flow_runs.py,sha256=ALmUFY4WrJggN1ha0z-tqXeddG2GptswbPnB7iYixUM,4172
|
|
@@ -719,7 +719,7 @@ prefect/server/models/workers.py,sha256=vPqs4dRjVxr_fr9Ibt02o3k4rl7pMhSWr7TfElq6
|
|
|
719
719
|
prefect/server/orchestration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
720
720
|
prefect/server/orchestration/core_policy.py,sha256=I-BqVUk9x_-GgynatayRFDh8Jri4TM_B73KdpP8EdaI,79896
|
|
721
721
|
prefect/server/orchestration/dependencies.py,sha256=zV5zUj699gjgGroMVufTOhI5DuRp2r70hNSnQz8i768,4671
|
|
722
|
-
prefect/server/orchestration/global_policy.py,sha256=
|
|
722
|
+
prefect/server/orchestration/global_policy.py,sha256=lxAE3YeouWmlthTKJuJe8deA-6t8kRbX9VW2OuC5NZw,17807
|
|
723
723
|
prefect/server/orchestration/instrumentation_policies.py,sha256=Qx5fIzsUyc2cGY00FXksM7o7WRYvjp2daJcPEExDt9M,2416
|
|
724
724
|
prefect/server/orchestration/policies.py,sha256=Ia18UBA0cFEoI4MJP8t7GmGJBgHr2aSCqrq8YYhuNF4,2794
|
|
725
725
|
prefect/server/orchestration/rules.py,sha256=33iULZKbNPCtDi8mErcOqh8nOe1YyinqLaOFpfx3he0,44889
|
|
@@ -1470,8 +1470,8 @@ prefect/workers/_worker_channel/_protocol.py,sha256=GpCNh1o3qmmqHA_UOOTge1QVC6IR
|
|
|
1470
1470
|
prefect/workers/_worker_channel/_state.py,sha256=eQTFZtAVDZH1vVWps3SdeY6aW3qu2wx1UKYQXK3AyuE,5369
|
|
1471
1471
|
prefect/workers/_worker_channel/_sync.py,sha256=G5G8_UaQYbeLebi5Mb1Z_KgGfXfyjXo5uT9la5_zwqY,14984
|
|
1472
1472
|
prefect/workers/_worker_channel/_transport.py,sha256=6VXxiZKIu0rqImlif14ojoAL3UGOBTmNpnlYxNggaLE,9423
|
|
1473
|
-
prefect-3.7.9.
|
|
1474
|
-
prefect-3.7.9.
|
|
1475
|
-
prefect-3.7.9.
|
|
1476
|
-
prefect-3.7.9.
|
|
1477
|
-
prefect-3.7.9.
|
|
1473
|
+
prefect-3.7.9.dev4.dist-info/METADATA,sha256=dW9OGkHQXgY_8a8RrpxC3H_pPnkXL9jgp0rQ5fUeD2k,14030
|
|
1474
|
+
prefect-3.7.9.dev4.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
|
|
1475
|
+
prefect-3.7.9.dev4.dist-info/entry_points.txt,sha256=HlY8up83iIq2vU2r33a0qSis4eOFSyb1mRH4l7Xt9X8,126
|
|
1476
|
+
prefect-3.7.9.dev4.dist-info/licenses/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
|
|
1477
|
+
prefect-3.7.9.dev4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|