prefect-client 2.19.4__py3-none-any.whl → 3.0.0rc2__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 +8 -56
- prefect/_internal/compatibility/deprecated.py +6 -115
- prefect/_internal/compatibility/experimental.py +4 -79
- prefect/_internal/concurrency/api.py +0 -34
- 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/threads.py +35 -0
- prefect/_internal/concurrency/waiters.py +0 -28
- prefect/_internal/pydantic/__init__.py +0 -45
- 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/schemas/bases.py +44 -177
- prefect/_internal/schemas/fields.py +1 -43
- prefect/_internal/schemas/validators.py +60 -158
- prefect/artifacts.py +161 -14
- prefect/automations.py +39 -4
- prefect/blocks/abstract.py +1 -1
- prefect/blocks/core.py +268 -148
- prefect/blocks/fields.py +2 -57
- prefect/blocks/kubernetes.py +8 -12
- prefect/blocks/notifications.py +40 -20
- prefect/blocks/redis.py +168 -0
- prefect/blocks/system.py +22 -11
- prefect/blocks/webhook.py +2 -9
- prefect/client/base.py +4 -4
- prefect/client/cloud.py +8 -13
- prefect/client/orchestration.py +362 -340
- prefect/client/schemas/actions.py +92 -86
- prefect/client/schemas/filters.py +20 -40
- prefect/client/schemas/objects.py +158 -152
- prefect/client/schemas/responses.py +16 -24
- prefect/client/schemas/schedules.py +47 -35
- prefect/client/subscriptions.py +2 -2
- prefect/client/utilities.py +5 -2
- prefect/concurrency/asyncio.py +4 -2
- prefect/concurrency/events.py +1 -1
- prefect/concurrency/services.py +7 -4
- prefect/context.py +195 -27
- prefect/deployments/__init__.py +5 -6
- prefect/deployments/base.py +7 -5
- prefect/deployments/flow_runs.py +185 -0
- prefect/deployments/runner.py +50 -45
- prefect/deployments/schedules.py +28 -23
- prefect/deployments/steps/__init__.py +0 -1
- prefect/deployments/steps/core.py +1 -0
- prefect/deployments/steps/pull.py +7 -21
- prefect/engine.py +12 -2422
- prefect/events/actions.py +17 -23
- prefect/events/cli/automations.py +19 -6
- prefect/events/clients.py +14 -37
- prefect/events/filters.py +14 -18
- prefect/events/related.py +2 -2
- 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 +36 -65
- prefect/events/schemas/labelling.py +10 -14
- prefect/events/utilities.py +2 -3
- prefect/events/worker.py +2 -3
- prefect/filesystems.py +6 -517
- prefect/{new_flow_engine.py → flow_engine.py} +315 -74
- prefect/flow_runs.py +379 -7
- prefect/flows.py +248 -165
- prefect/futures.py +187 -345
- prefect/infrastructure/__init__.py +0 -27
- prefect/infrastructure/provisioners/__init__.py +5 -3
- prefect/infrastructure/provisioners/cloud_run.py +11 -6
- prefect/infrastructure/provisioners/container_instance.py +11 -7
- prefect/infrastructure/provisioners/ecs.py +6 -4
- prefect/infrastructure/provisioners/modal.py +8 -5
- prefect/input/actions.py +2 -4
- prefect/input/run_input.py +9 -9
- prefect/logging/formatters.py +0 -2
- prefect/logging/handlers.py +3 -11
- prefect/logging/loggers.py +2 -2
- prefect/manifests.py +2 -1
- prefect/records/__init__.py +1 -0
- prefect/records/cache_policies.py +179 -0
- prefect/records/result_store.py +42 -0
- prefect/records/store.py +9 -0
- prefect/results.py +43 -39
- prefect/runner/runner.py +9 -9
- prefect/runner/server.py +6 -10
- prefect/runner/storage.py +3 -8
- prefect/runner/submit.py +2 -2
- prefect/runner/utils.py +2 -2
- prefect/serializers.py +24 -35
- prefect/server/api/collections_data/views/aggregate-worker-metadata.json +5 -14
- prefect/settings.py +76 -136
- prefect/states.py +22 -50
- prefect/task_engine.py +666 -56
- prefect/task_runners.py +272 -300
- prefect/task_runs.py +203 -0
- prefect/{task_server.py → task_worker.py} +89 -60
- prefect/tasks.py +358 -341
- prefect/transactions.py +224 -0
- prefect/types/__init__.py +61 -82
- prefect/utilities/asyncutils.py +195 -136
- prefect/utilities/callables.py +121 -41
- prefect/utilities/collections.py +23 -38
- prefect/utilities/dispatch.py +11 -3
- prefect/utilities/dockerutils.py +4 -0
- prefect/utilities/engine.py +140 -20
- prefect/utilities/importtools.py +26 -27
- prefect/utilities/pydantic.py +128 -38
- prefect/utilities/schema_tools/hydration.py +5 -1
- prefect/utilities/templating.py +12 -2
- prefect/variables.py +84 -62
- prefect/workers/__init__.py +0 -1
- prefect/workers/base.py +26 -18
- prefect/workers/process.py +3 -8
- prefect/workers/server.py +2 -2
- {prefect_client-2.19.4.dist-info → prefect_client-3.0.0rc2.dist-info}/METADATA +23 -21
- prefect_client-3.0.0rc2.dist-info/RECORD +179 -0
- 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/__init__.py +0 -0
- 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/__init__.py +0 -0
- 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/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/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/agent.py +0 -698
- prefect/deployments/deployments.py +0 -1042
- 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/base.py +0 -323
- prefect/infrastructure/container.py +0 -818
- prefect/infrastructure/kubernetes.py +0 -920
- prefect/infrastructure/process.py +0 -289
- 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/workers/block.py +0 -218
- prefect_client-2.19.4.dist-info/RECORD +0 -292
- {prefect_client-2.19.4.dist-info → prefect_client-3.0.0rc2.dist-info}/LICENSE +0 -0
- {prefect_client-2.19.4.dist-info → prefect_client-3.0.0rc2.dist-info}/WHEEL +0 -0
- {prefect_client-2.19.4.dist-info → prefect_client-3.0.0rc2.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,6 @@
|
|
1
1
|
import datetime
|
2
|
+
import warnings
|
3
|
+
from functools import partial
|
2
4
|
from typing import (
|
3
5
|
TYPE_CHECKING,
|
4
6
|
Any,
|
@@ -10,33 +12,30 @@ from typing import (
|
|
10
12
|
Union,
|
11
13
|
overload,
|
12
14
|
)
|
13
|
-
from uuid import UUID
|
15
|
+
from uuid import UUID, uuid4
|
14
16
|
|
15
17
|
import orjson
|
16
18
|
import pendulum
|
17
|
-
|
18
|
-
|
19
|
-
|
19
|
+
from pydantic import (
|
20
|
+
ConfigDict,
|
21
|
+
Field,
|
22
|
+
HttpUrl,
|
23
|
+
SerializationInfo,
|
24
|
+
field_validator,
|
25
|
+
model_serializer,
|
26
|
+
model_validator,
|
20
27
|
)
|
21
|
-
from
|
22
|
-
from
|
23
|
-
|
24
|
-
if HAS_PYDANTIC_V2:
|
25
|
-
from pydantic.v1 import Field, HttpUrl, root_validator, validator
|
26
|
-
else:
|
27
|
-
from pydantic import Field, HttpUrl, root_validator, validator
|
28
|
-
|
29
|
-
from typing_extensions import Literal
|
28
|
+
from pydantic_extra_types.pendulum_dt import DateTime
|
29
|
+
from typing_extensions import Literal, Self
|
30
30
|
|
31
31
|
from prefect._internal.schemas.bases import ObjectBaseModel, PrefectBaseModel
|
32
|
-
from prefect._internal.schemas.fields import CreatedBy,
|
32
|
+
from prefect._internal.schemas.fields import CreatedBy, UpdatedBy
|
33
33
|
from prefect._internal.schemas.validators import (
|
34
34
|
get_or_create_run_name,
|
35
|
-
get_or_create_state_name,
|
36
35
|
list_length_50_or_less,
|
37
36
|
raise_on_name_alphanumeric_dashes_only,
|
38
|
-
raise_on_name_with_banned_characters,
|
39
37
|
set_run_policy_deprecated_fields,
|
38
|
+
validate_block_document_name,
|
40
39
|
validate_default_queue_id_not_none,
|
41
40
|
validate_max_metadata_length,
|
42
41
|
validate_message_template_variables,
|
@@ -46,11 +45,18 @@ from prefect._internal.schemas.validators import (
|
|
46
45
|
)
|
47
46
|
from prefect.client.schemas.schedules import SCHEDULE_TYPES
|
48
47
|
from prefect.settings import PREFECT_CLOUD_API_URL, PREFECT_CLOUD_UI_URL
|
49
|
-
from prefect.
|
48
|
+
from prefect.types import (
|
49
|
+
MAX_VARIABLE_NAME_LENGTH,
|
50
|
+
Name,
|
51
|
+
NonNegativeInteger,
|
52
|
+
PositiveInteger,
|
53
|
+
StrictVariableValue,
|
54
|
+
)
|
55
|
+
from prefect.utilities.collections import AutoEnum, listrepr, visit_collection
|
50
56
|
from prefect.utilities.names import generate_slug
|
57
|
+
from prefect.utilities.pydantic import handle_secret_render
|
51
58
|
|
52
59
|
if TYPE_CHECKING:
|
53
|
-
from prefect.deprecated.data_documents import DataDocument
|
54
60
|
from prefect.results import BaseResult
|
55
61
|
|
56
62
|
|
@@ -72,8 +78,6 @@ FLOW_RUN_NOTIFICATION_TEMPLATE_KWARGS = [
|
|
72
78
|
"flow_run_state_timestamp",
|
73
79
|
"flow_run_state_message",
|
74
80
|
]
|
75
|
-
MAX_VARIABLE_NAME_LENGTH = 255
|
76
|
-
MAX_VARIABLE_VALUE_LENGTH = 5000
|
77
81
|
|
78
82
|
|
79
83
|
class StateType(AutoEnum):
|
@@ -90,6 +94,14 @@ class StateType(AutoEnum):
|
|
90
94
|
CANCELLING = AutoEnum.auto()
|
91
95
|
|
92
96
|
|
97
|
+
TERMINAL_STATES = {
|
98
|
+
StateType.COMPLETED,
|
99
|
+
StateType.CANCELLED,
|
100
|
+
StateType.FAILED,
|
101
|
+
StateType.CRASHED,
|
102
|
+
}
|
103
|
+
|
104
|
+
|
93
105
|
class WorkPoolStatus(AutoEnum):
|
94
106
|
"""Enumeration of work pool statuses."""
|
95
107
|
|
@@ -129,11 +141,12 @@ class StateDetails(PrefectBaseModel):
|
|
129
141
|
task_run_id: Optional[UUID] = None
|
130
142
|
# for task runs that represent subflows, the subflow's run ID
|
131
143
|
child_flow_run_id: Optional[UUID] = None
|
132
|
-
scheduled_time:
|
144
|
+
scheduled_time: Optional[DateTime] = None
|
133
145
|
cache_key: Optional[str] = None
|
134
|
-
cache_expiration:
|
146
|
+
cache_expiration: Optional[DateTime] = None
|
147
|
+
deferred: Optional[bool] = None
|
135
148
|
untrackable_result: bool = False
|
136
|
-
pause_timeout:
|
149
|
+
pause_timeout: Optional[DateTime] = None
|
137
150
|
pause_reschedule: bool = False
|
138
151
|
pause_key: Optional[str] = None
|
139
152
|
run_input_keyset: Optional[Dict[str, str]] = None
|
@@ -150,10 +163,10 @@ class State(ObjectBaseModel, Generic[R]):
|
|
150
163
|
|
151
164
|
type: StateType
|
152
165
|
name: Optional[str] = Field(default=None)
|
153
|
-
timestamp:
|
166
|
+
timestamp: DateTime = Field(default_factory=lambda: pendulum.now("UTC"))
|
154
167
|
message: Optional[str] = Field(default=None, examples=["Run started"])
|
155
168
|
state_details: StateDetails = Field(default_factory=StateDetails)
|
156
|
-
data: Union["BaseResult[R]",
|
169
|
+
data: Union["BaseResult[R]", Any] = Field(
|
157
170
|
default=None,
|
158
171
|
)
|
159
172
|
|
@@ -261,24 +274,22 @@ class State(ObjectBaseModel, Generic[R]):
|
|
261
274
|
state_details=self.state_details,
|
262
275
|
)
|
263
276
|
|
264
|
-
@
|
265
|
-
def default_name_from_type(
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
state_details.scheduled_time = pendulum.now("utc")
|
281
|
-
return values
|
277
|
+
@model_validator(mode="after")
|
278
|
+
def default_name_from_type(self) -> Self:
|
279
|
+
"""If a name is not provided, use the type"""
|
280
|
+
# if `type` is not in `values` it means the `type` didn't pass its own
|
281
|
+
# validation check and an error will be raised after this function is called
|
282
|
+
name = self.name
|
283
|
+
if name is None and self.type:
|
284
|
+
self.name = " ".join([v.capitalize() for v in self.type.value.split("_")])
|
285
|
+
return self
|
286
|
+
|
287
|
+
@model_validator(mode="after")
|
288
|
+
def default_scheduled_start_time(self) -> Self:
|
289
|
+
if self.type == StateType.SCHEDULED:
|
290
|
+
if not self.state_details.scheduled_time:
|
291
|
+
self.state_details.scheduled_time = DateTime.now("utc")
|
292
|
+
return self
|
282
293
|
|
283
294
|
def is_scheduled(self) -> bool:
|
284
295
|
return self.type == StateType.SCHEDULED
|
@@ -305,30 +316,35 @@ class State(ObjectBaseModel, Generic[R]):
|
|
305
316
|
return self.type == StateType.CANCELLING
|
306
317
|
|
307
318
|
def is_final(self) -> bool:
|
308
|
-
return self.type in
|
309
|
-
StateType.CANCELLED,
|
310
|
-
StateType.FAILED,
|
311
|
-
StateType.COMPLETED,
|
312
|
-
StateType.CRASHED,
|
313
|
-
}
|
319
|
+
return self.type in TERMINAL_STATES
|
314
320
|
|
315
321
|
def is_paused(self) -> bool:
|
316
322
|
return self.type == StateType.PAUSED
|
317
323
|
|
318
|
-
def
|
319
|
-
self,
|
320
|
-
*,
|
321
|
-
update: Optional[Dict[str, Any]] = None,
|
322
|
-
reset_fields: bool = False,
|
323
|
-
**kwargs,
|
324
|
+
def model_copy(
|
325
|
+
self, *, update: Optional[Dict[str, Any]] = None, deep: bool = False
|
324
326
|
):
|
325
327
|
"""
|
326
328
|
Copying API models should return an object that could be inserted into the
|
327
329
|
database again. The 'timestamp' is reset using the default factory.
|
328
330
|
"""
|
329
331
|
update = update or {}
|
330
|
-
update.setdefault("timestamp", self.
|
331
|
-
return super().
|
332
|
+
update.setdefault("timestamp", self.model_fields["timestamp"].get_default())
|
333
|
+
return super().model_copy(update=update, deep=deep)
|
334
|
+
|
335
|
+
def fresh_copy(self, **kwargs) -> Self:
|
336
|
+
"""
|
337
|
+
Return a fresh copy of the state with a new ID.
|
338
|
+
"""
|
339
|
+
return self.model_copy(
|
340
|
+
update={
|
341
|
+
"id": uuid4(),
|
342
|
+
"created": pendulum.now("utc"),
|
343
|
+
"updated": pendulum.now("utc"),
|
344
|
+
"timestamp": pendulum.now("utc"),
|
345
|
+
},
|
346
|
+
**kwargs,
|
347
|
+
)
|
332
348
|
|
333
349
|
def __repr__(self) -> str:
|
334
350
|
"""
|
@@ -337,12 +353,7 @@ class State(ObjectBaseModel, Generic[R]):
|
|
337
353
|
|
338
354
|
`MyCompletedState(message="my message", type=COMPLETED, result=...)`
|
339
355
|
"""
|
340
|
-
|
341
|
-
|
342
|
-
if isinstance(self.data, DataDocument):
|
343
|
-
result = self.data.decode()
|
344
|
-
else:
|
345
|
-
result = self.data
|
356
|
+
result = self.data
|
346
357
|
|
347
358
|
display = dict(
|
348
359
|
message=repr(self.message),
|
@@ -410,7 +421,7 @@ class FlowRunPolicy(PrefectBaseModel):
|
|
410
421
|
default=False, description="Indicates if this run is resuming from a pause."
|
411
422
|
)
|
412
423
|
|
413
|
-
@
|
424
|
+
@model_validator(mode="before")
|
414
425
|
def populate_deprecated_fields(cls, values):
|
415
426
|
return set_run_policy_deprecated_fields(values)
|
416
427
|
|
@@ -479,18 +490,18 @@ class FlowRun(ObjectBaseModel):
|
|
479
490
|
run_count: int = Field(
|
480
491
|
default=0, description="The number of times the flow run was executed."
|
481
492
|
)
|
482
|
-
expected_start_time: Optional[
|
493
|
+
expected_start_time: Optional[DateTime] = Field(
|
483
494
|
default=None,
|
484
495
|
description="The flow run's expected start time.",
|
485
496
|
)
|
486
|
-
next_scheduled_start_time: Optional[
|
497
|
+
next_scheduled_start_time: Optional[DateTime] = Field(
|
487
498
|
default=None,
|
488
499
|
description="The next time the flow run is scheduled to start.",
|
489
500
|
)
|
490
|
-
start_time: Optional[
|
501
|
+
start_time: Optional[DateTime] = Field(
|
491
502
|
default=None, description="The actual start time."
|
492
503
|
)
|
493
|
-
end_time: Optional[
|
504
|
+
end_time: Optional[DateTime] = Field(
|
494
505
|
default=None, description="The actual end time."
|
495
506
|
)
|
496
507
|
total_run_time: datetime.timedelta = Field(
|
@@ -529,7 +540,7 @@ class FlowRun(ObjectBaseModel):
|
|
529
540
|
)
|
530
541
|
|
531
542
|
work_pool_id: Optional[UUID] = Field(
|
532
|
-
description="The work pool with which the queue is associated."
|
543
|
+
default=None, description="The work pool with which the queue is associated."
|
533
544
|
)
|
534
545
|
work_pool_name: Optional[str] = Field(
|
535
546
|
default=None,
|
@@ -539,10 +550,11 @@ class FlowRun(ObjectBaseModel):
|
|
539
550
|
state: Optional[State] = Field(
|
540
551
|
default=None,
|
541
552
|
description="The state of the flow run.",
|
542
|
-
examples=[State(type=StateType.COMPLETED)],
|
553
|
+
examples=["State(type=StateType.COMPLETED)"],
|
543
554
|
)
|
544
555
|
job_variables: Optional[dict] = Field(
|
545
|
-
default=None,
|
556
|
+
default=None,
|
557
|
+
description="Job variables for the flow run.",
|
546
558
|
)
|
547
559
|
|
548
560
|
# These are server-side optimizations and should not be present on client models
|
@@ -564,12 +576,13 @@ class FlowRun(ObjectBaseModel):
|
|
564
576
|
"""
|
565
577
|
if isinstance(other, FlowRun):
|
566
578
|
exclude_fields = {"estimated_run_time", "estimated_start_time_delta"}
|
567
|
-
return self.
|
579
|
+
return self.model_dump(exclude=exclude_fields) == other.model_dump(
|
568
580
|
exclude=exclude_fields
|
569
581
|
)
|
570
582
|
return super().__eq__(other)
|
571
583
|
|
572
|
-
@
|
584
|
+
@field_validator("name", mode="before")
|
585
|
+
@classmethod
|
573
586
|
def set_default_name(cls, name):
|
574
587
|
return get_or_create_run_name(name)
|
575
588
|
|
@@ -602,15 +615,32 @@ class TaskRunPolicy(PrefectBaseModel):
|
|
602
615
|
default=None, description="Determines the amount a retry should jitter"
|
603
616
|
)
|
604
617
|
|
605
|
-
@
|
606
|
-
def populate_deprecated_fields(
|
607
|
-
|
618
|
+
@model_validator(mode="after")
|
619
|
+
def populate_deprecated_fields(self):
|
620
|
+
"""
|
621
|
+
If deprecated fields are provided, populate the corresponding new fields
|
622
|
+
to preserve orchestration behavior.
|
623
|
+
"""
|
624
|
+
# We have marked these fields as deprecated, so we need to filter out the
|
625
|
+
# deprecation warnings _we're_ generating here
|
626
|
+
with warnings.catch_warnings():
|
627
|
+
warnings.simplefilter("ignore", DeprecationWarning)
|
628
|
+
|
629
|
+
if not self.retries and self.max_retries != 0:
|
630
|
+
self.retries = self.max_retries
|
631
|
+
|
632
|
+
if not self.retry_delay and self.retry_delay_seconds != 0:
|
633
|
+
self.retry_delay = self.retry_delay_seconds
|
608
634
|
|
609
|
-
|
635
|
+
return self
|
636
|
+
|
637
|
+
@field_validator("retry_delay")
|
638
|
+
@classmethod
|
610
639
|
def validate_configured_retry_delays(cls, v):
|
611
640
|
return list_length_50_or_less(v)
|
612
641
|
|
613
|
-
@
|
642
|
+
@field_validator("retry_jitter_factor")
|
643
|
+
@classmethod
|
614
644
|
def validate_jitter_factor(cls, v):
|
615
645
|
return validate_not_negative(v)
|
616
646
|
|
@@ -621,9 +651,7 @@ class TaskRunInput(PrefectBaseModel):
|
|
621
651
|
could include, constants, parameters, or other task runs.
|
622
652
|
"""
|
623
653
|
|
624
|
-
|
625
|
-
class Config:
|
626
|
-
frozen = True
|
654
|
+
model_config = ConfigDict(frozen=True)
|
627
655
|
|
628
656
|
input_type: str
|
629
657
|
|
@@ -674,7 +702,7 @@ class TaskRun(ObjectBaseModel):
|
|
674
702
|
" the task run."
|
675
703
|
),
|
676
704
|
)
|
677
|
-
cache_expiration: Optional[
|
705
|
+
cache_expiration: Optional[DateTime] = Field(
|
678
706
|
default=None, description="Specifies when the cached state should expire."
|
679
707
|
)
|
680
708
|
task_version: Optional[str] = Field(
|
@@ -715,21 +743,21 @@ class TaskRun(ObjectBaseModel):
|
|
715
743
|
" associated with."
|
716
744
|
),
|
717
745
|
)
|
718
|
-
expected_start_time: Optional[
|
746
|
+
expected_start_time: Optional[DateTime] = Field(
|
719
747
|
default=None,
|
720
748
|
description="The task run's expected start time.",
|
721
749
|
)
|
722
750
|
|
723
751
|
# the next scheduled start time will be populated
|
724
752
|
# whenever the run is in a scheduled state
|
725
|
-
next_scheduled_start_time: Optional[
|
753
|
+
next_scheduled_start_time: Optional[DateTime] = Field(
|
726
754
|
default=None,
|
727
755
|
description="The next time the task run is scheduled to start.",
|
728
756
|
)
|
729
|
-
start_time: Optional[
|
757
|
+
start_time: Optional[DateTime] = Field(
|
730
758
|
default=None, description="The actual start time."
|
731
759
|
)
|
732
|
-
end_time: Optional[
|
760
|
+
end_time: Optional[DateTime] = Field(
|
733
761
|
default=None, description="The actual end time."
|
734
762
|
)
|
735
763
|
total_run_time: datetime.timedelta = Field(
|
@@ -751,10 +779,11 @@ class TaskRun(ObjectBaseModel):
|
|
751
779
|
state: Optional[State] = Field(
|
752
780
|
default=None,
|
753
781
|
description="The state of the flow run.",
|
754
|
-
examples=[State(type=StateType.COMPLETED)],
|
782
|
+
examples=["State(type=StateType.COMPLETED)"],
|
755
783
|
)
|
756
784
|
|
757
|
-
@
|
785
|
+
@field_validator("name", mode="before")
|
786
|
+
@classmethod
|
758
787
|
def set_default_name(cls, name):
|
759
788
|
return get_or_create_run_name(name)
|
760
789
|
|
@@ -773,9 +802,7 @@ class Workspace(PrefectBaseModel):
|
|
773
802
|
workspace_name: str = Field(..., description="The workspace name.")
|
774
803
|
workspace_description: str = Field(..., description="Description of the workspace.")
|
775
804
|
workspace_handle: str = Field(..., description="The workspace's unique handle.")
|
776
|
-
|
777
|
-
class Config:
|
778
|
-
extra = "ignore"
|
805
|
+
model_config = ConfigDict(extra="ignore")
|
779
806
|
|
780
807
|
@property
|
781
808
|
def handle(self) -> str:
|
@@ -811,7 +838,7 @@ class Workspace(PrefectBaseModel):
|
|
811
838
|
class BlockType(ObjectBaseModel):
|
812
839
|
"""An ORM representation of a block type"""
|
813
840
|
|
814
|
-
name:
|
841
|
+
name: Name = Field(default=..., description="A block type's name")
|
815
842
|
slug: str = Field(default=..., description="A block type's slug")
|
816
843
|
logo_url: Optional[HttpUrl] = Field(
|
817
844
|
default=None, description="Web URL for the block type's logo"
|
@@ -831,10 +858,6 @@ class BlockType(ObjectBaseModel):
|
|
831
858
|
default=False, description="Protected block types cannot be modified via API."
|
832
859
|
)
|
833
860
|
|
834
|
-
@validator("name", check_fields=False)
|
835
|
-
def validate_name_characters(cls, v):
|
836
|
-
return raise_on_name_with_banned_characters(v)
|
837
|
-
|
838
861
|
|
839
862
|
class BlockSchema(ObjectBaseModel):
|
840
863
|
"""A representation of a block schema."""
|
@@ -860,7 +883,7 @@ class BlockSchema(ObjectBaseModel):
|
|
860
883
|
class BlockDocument(ObjectBaseModel):
|
861
884
|
"""An ORM representation of a block document."""
|
862
885
|
|
863
|
-
name: Optional[
|
886
|
+
name: Optional[Name] = Field(
|
864
887
|
default=None,
|
865
888
|
description=(
|
866
889
|
"The block document's name. Not required for anonymous block documents."
|
@@ -889,21 +912,26 @@ class BlockDocument(ObjectBaseModel):
|
|
889
912
|
),
|
890
913
|
)
|
891
914
|
|
892
|
-
|
893
|
-
def validate_name_characters(cls, v):
|
894
|
-
# the BlockDocumentCreate subclass allows name=None
|
895
|
-
# and will inherit this validator
|
896
|
-
return raise_on_name_with_banned_characters(v)
|
915
|
+
_validate_name_format = field_validator("name")(validate_block_document_name)
|
897
916
|
|
898
|
-
@
|
917
|
+
@model_validator(mode="before")
|
899
918
|
def validate_name_is_present_if_not_anonymous(cls, values):
|
900
919
|
return validate_name_present_on_nonanonymous_blocks(values)
|
901
920
|
|
921
|
+
@model_serializer(mode="wrap")
|
922
|
+
def serialize_data(self, handler, info: SerializationInfo):
|
923
|
+
self.data = visit_collection(
|
924
|
+
self.data,
|
925
|
+
visit_fn=partial(handle_secret_render, context=info.context or {}),
|
926
|
+
return_data=True,
|
927
|
+
)
|
928
|
+
return handler(self)
|
929
|
+
|
902
930
|
|
903
931
|
class Flow(ObjectBaseModel):
|
904
932
|
"""An ORM representation of flow data."""
|
905
933
|
|
906
|
-
name:
|
934
|
+
name: Name = Field(
|
907
935
|
default=..., description="The name of the flow", examples=["my-flow"]
|
908
936
|
)
|
909
937
|
tags: List[str] = Field(
|
@@ -912,19 +940,6 @@ class Flow(ObjectBaseModel):
|
|
912
940
|
examples=[["tag-1", "tag-2"]],
|
913
941
|
)
|
914
942
|
|
915
|
-
@validator("name", check_fields=False)
|
916
|
-
def validate_name_characters(cls, v):
|
917
|
-
return raise_on_name_with_banned_characters(v)
|
918
|
-
|
919
|
-
|
920
|
-
class MinimalDeploymentSchedule(PrefectBaseModel):
|
921
|
-
schedule: SCHEDULE_TYPES = Field(
|
922
|
-
default=..., description="The schedule for the deployment."
|
923
|
-
)
|
924
|
-
active: bool = Field(
|
925
|
-
default=True, description="Whether or not the schedule is active."
|
926
|
-
)
|
927
|
-
|
928
943
|
|
929
944
|
class DeploymentSchedule(ObjectBaseModel):
|
930
945
|
deployment_id: Optional[UUID] = Field(
|
@@ -951,10 +966,10 @@ class DeploymentSchedule(ObjectBaseModel):
|
|
951
966
|
)
|
952
967
|
|
953
968
|
|
954
|
-
class Deployment(
|
969
|
+
class Deployment(ObjectBaseModel):
|
955
970
|
"""An ORM representation of deployment data."""
|
956
971
|
|
957
|
-
name:
|
972
|
+
name: Name = Field(default=..., description="The name of the deployment.")
|
958
973
|
version: Optional[str] = Field(
|
959
974
|
default=None, description="An optional version for the deployment."
|
960
975
|
)
|
@@ -1000,7 +1015,7 @@ class Deployment(DeprecatedInfraOverridesField, ObjectBaseModel):
|
|
1000
1015
|
" be scheduled."
|
1001
1016
|
),
|
1002
1017
|
)
|
1003
|
-
last_polled: Optional[
|
1018
|
+
last_polled: Optional[DateTime] = Field(
|
1004
1019
|
default=None,
|
1005
1020
|
description="The last time the deployment was polled for status updates.",
|
1006
1021
|
)
|
@@ -1043,23 +1058,19 @@ class Deployment(DeprecatedInfraOverridesField, ObjectBaseModel):
|
|
1043
1058
|
default=None,
|
1044
1059
|
description="Optional information about the updater of this deployment.",
|
1045
1060
|
)
|
1046
|
-
work_queue_id: UUID = Field(
|
1061
|
+
work_queue_id: Optional[UUID] = Field(
|
1047
1062
|
default=None,
|
1048
1063
|
description=(
|
1049
1064
|
"The id of the work pool queue to which this deployment is assigned."
|
1050
1065
|
),
|
1051
1066
|
)
|
1052
1067
|
enforce_parameter_schema: bool = Field(
|
1053
|
-
default=
|
1068
|
+
default=True,
|
1054
1069
|
description=(
|
1055
1070
|
"Whether or not the deployment should enforce the parameter schema."
|
1056
1071
|
),
|
1057
1072
|
)
|
1058
1073
|
|
1059
|
-
@validator("name", check_fields=False)
|
1060
|
-
def validate_name_characters(cls, v):
|
1061
|
-
return raise_on_name_with_banned_characters(v)
|
1062
|
-
|
1063
1074
|
|
1064
1075
|
class ConcurrencyLimit(ObjectBaseModel):
|
1065
1076
|
"""An ORM representation of a concurrency limit."""
|
@@ -1134,7 +1145,7 @@ class BlockDocumentReference(ObjectBaseModel):
|
|
1134
1145
|
default=..., description="The name that the reference is nested under"
|
1135
1146
|
)
|
1136
1147
|
|
1137
|
-
@
|
1148
|
+
@model_validator(mode="before")
|
1138
1149
|
def validate_parent_and_ref_are_different(cls, values):
|
1139
1150
|
return validate_parent_and_ref_diff(values)
|
1140
1151
|
|
@@ -1178,7 +1189,7 @@ class Log(ObjectBaseModel):
|
|
1178
1189
|
name: str = Field(default=..., description="The logger name.")
|
1179
1190
|
level: int = Field(default=..., description="The log level.")
|
1180
1191
|
message: str = Field(default=..., description="The log message.")
|
1181
|
-
timestamp:
|
1192
|
+
timestamp: DateTime = Field(default=..., description="The log timestamp.")
|
1182
1193
|
flow_run_id: Optional[UUID] = Field(
|
1183
1194
|
default=None, description="The flow run ID associated with the log."
|
1184
1195
|
)
|
@@ -1203,7 +1214,7 @@ class QueueFilter(PrefectBaseModel):
|
|
1203
1214
|
class WorkQueue(ObjectBaseModel):
|
1204
1215
|
"""An ORM representation of a work queue"""
|
1205
1216
|
|
1206
|
-
name:
|
1217
|
+
name: Name = Field(default=..., description="The name of the work queue.")
|
1207
1218
|
description: Optional[str] = Field(
|
1208
1219
|
default="", description="An optional description for the work queue."
|
1209
1220
|
)
|
@@ -1229,17 +1240,13 @@ class WorkQueue(ObjectBaseModel):
|
|
1229
1240
|
description="DEPRECATED: Filter criteria for the work queue.",
|
1230
1241
|
deprecated=True,
|
1231
1242
|
)
|
1232
|
-
last_polled: Optional[
|
1243
|
+
last_polled: Optional[DateTime] = Field(
|
1233
1244
|
default=None, description="The last time an agent polled this queue for work."
|
1234
1245
|
)
|
1235
1246
|
status: Optional[WorkQueueStatus] = Field(
|
1236
1247
|
default=None, description="The queue status."
|
1237
1248
|
)
|
1238
1249
|
|
1239
|
-
@validator("name", check_fields=False)
|
1240
|
-
def validate_name_characters(cls, v):
|
1241
|
-
return raise_on_name_with_banned_characters(v)
|
1242
|
-
|
1243
1250
|
|
1244
1251
|
class WorkQueueHealthPolicy(PrefectBaseModel):
|
1245
1252
|
maximum_late_runs: Optional[int] = Field(
|
@@ -1258,7 +1265,7 @@ class WorkQueueHealthPolicy(PrefectBaseModel):
|
|
1258
1265
|
)
|
1259
1266
|
|
1260
1267
|
def evaluate_health_status(
|
1261
|
-
self, late_runs_count: int, last_polled: Optional[
|
1268
|
+
self, late_runs_count: int, last_polled: Optional[DateTime] = None
|
1262
1269
|
) -> bool:
|
1263
1270
|
"""
|
1264
1271
|
Given empirical information about the state of the work queue, evaluate its health status.
|
@@ -1293,7 +1300,7 @@ class WorkQueueStatusDetail(PrefectBaseModel):
|
|
1293
1300
|
late_runs_count: int = Field(
|
1294
1301
|
default=0, description="The number of late flow runs in the work queue."
|
1295
1302
|
)
|
1296
|
-
last_polled: Optional[
|
1303
|
+
last_polled: Optional[DateTime] = Field(
|
1297
1304
|
default=None, description="The last time an agent polled this queue for work."
|
1298
1305
|
)
|
1299
1306
|
health_check_policy: WorkQueueHealthPolicy = Field(
|
@@ -1333,7 +1340,8 @@ class FlowRunNotificationPolicy(ObjectBaseModel):
|
|
1333
1340
|
],
|
1334
1341
|
)
|
1335
1342
|
|
1336
|
-
@
|
1343
|
+
@field_validator("message_template")
|
1344
|
+
@classmethod
|
1337
1345
|
def validate_message_template_variables(cls, v):
|
1338
1346
|
return validate_message_template_variables(v)
|
1339
1347
|
|
@@ -1351,7 +1359,7 @@ class Agent(ObjectBaseModel):
|
|
1351
1359
|
work_queue_id: UUID = Field(
|
1352
1360
|
default=..., description="The work queue with which the agent is associated."
|
1353
1361
|
)
|
1354
|
-
last_activity_time: Optional[
|
1362
|
+
last_activity_time: Optional[DateTime] = Field(
|
1355
1363
|
default=None, description="The last time this agent polled for work."
|
1356
1364
|
)
|
1357
1365
|
|
@@ -1359,7 +1367,7 @@ class Agent(ObjectBaseModel):
|
|
1359
1367
|
class WorkPool(ObjectBaseModel):
|
1360
1368
|
"""An ORM representation of a work pool"""
|
1361
1369
|
|
1362
|
-
name:
|
1370
|
+
name: Name = Field(
|
1363
1371
|
description="The name of the work pool.",
|
1364
1372
|
)
|
1365
1373
|
description: Optional[str] = Field(
|
@@ -1394,11 +1402,8 @@ class WorkPool(ObjectBaseModel):
|
|
1394
1402
|
def is_managed_pool(self) -> bool:
|
1395
1403
|
return self.type.endswith(":managed")
|
1396
1404
|
|
1397
|
-
@
|
1398
|
-
|
1399
|
-
return raise_on_name_with_banned_characters(v)
|
1400
|
-
|
1401
|
-
@validator("default_queue_id", always=True)
|
1405
|
+
@field_validator("default_queue_id")
|
1406
|
+
@classmethod
|
1402
1407
|
def helpful_error_for_missing_default_queue_id(cls, v):
|
1403
1408
|
return validate_default_queue_id_not_none(v)
|
1404
1409
|
|
@@ -1425,8 +1430,8 @@ class Worker(ObjectBaseModel):
|
|
1425
1430
|
)
|
1426
1431
|
|
1427
1432
|
|
1428
|
-
Flow.
|
1429
|
-
FlowRun.
|
1433
|
+
Flow.model_rebuild()
|
1434
|
+
# FlowRun.model_rebuild()
|
1430
1435
|
|
1431
1436
|
|
1432
1437
|
class Artifact(ObjectBaseModel):
|
@@ -1465,7 +1470,8 @@ class Artifact(ObjectBaseModel):
|
|
1465
1470
|
default=None, description="The task run associated with the artifact."
|
1466
1471
|
)
|
1467
1472
|
|
1468
|
-
@
|
1473
|
+
@field_validator("metadata_")
|
1474
|
+
@classmethod
|
1469
1475
|
def validate_metadata_length(cls, v):
|
1470
1476
|
return validate_max_metadata_length(v)
|
1471
1477
|
|
@@ -1514,11 +1520,10 @@ class Variable(ObjectBaseModel):
|
|
1514
1520
|
examples=["my_variable"],
|
1515
1521
|
max_length=MAX_VARIABLE_NAME_LENGTH,
|
1516
1522
|
)
|
1517
|
-
value:
|
1523
|
+
value: StrictVariableValue = Field(
|
1518
1524
|
default=...,
|
1519
1525
|
description="The value of the variable",
|
1520
1526
|
examples=["my_value"],
|
1521
|
-
max_length=MAX_VARIABLE_VALUE_LENGTH,
|
1522
1527
|
)
|
1523
1528
|
tags: List[str] = Field(
|
1524
1529
|
default_factory=list,
|
@@ -1531,7 +1536,7 @@ class FlowRunInput(ObjectBaseModel):
|
|
1531
1536
|
flow_run_id: UUID = Field(description="The flow run ID associated with the input.")
|
1532
1537
|
key: str = Field(description="The key of the input.")
|
1533
1538
|
value: str = Field(description="The value of the input.")
|
1534
|
-
sender: Optional[str] = Field(description="The sender of the input.")
|
1539
|
+
sender: Optional[str] = Field(default=None, description="The sender of the input.")
|
1535
1540
|
|
1536
1541
|
@property
|
1537
1542
|
def decoded_value(self) -> Any:
|
@@ -1543,7 +1548,8 @@ class FlowRunInput(ObjectBaseModel):
|
|
1543
1548
|
"""
|
1544
1549
|
return orjson.loads(self.value)
|
1545
1550
|
|
1546
|
-
@
|
1551
|
+
@field_validator("key", check_fields=False)
|
1552
|
+
@classmethod
|
1547
1553
|
def validate_name_characters(cls, v):
|
1548
1554
|
raise_on_name_alphanumeric_dashes_only(v)
|
1549
1555
|
return v
|
@@ -1584,6 +1590,6 @@ class CsrfToken(ObjectBaseModel):
|
|
1584
1590
|
client: str = Field(
|
1585
1591
|
default=..., description="The client id associated with the CSRF token"
|
1586
1592
|
)
|
1587
|
-
expiration:
|
1593
|
+
expiration: datetime.datetime = Field(
|
1588
1594
|
default=..., description="The expiration time of the CSRF token"
|
1589
1595
|
)
|