prefect-client 2.19.2__py3-none-any.whl → 3.0.0rc1__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.
Files changed (239) hide show
  1. prefect/__init__.py +8 -56
  2. prefect/_internal/compatibility/deprecated.py +6 -115
  3. prefect/_internal/compatibility/experimental.py +4 -79
  4. prefect/_internal/concurrency/api.py +0 -34
  5. prefect/_internal/concurrency/calls.py +0 -6
  6. prefect/_internal/concurrency/cancellation.py +0 -3
  7. prefect/_internal/concurrency/event_loop.py +0 -20
  8. prefect/_internal/concurrency/inspection.py +3 -3
  9. prefect/_internal/concurrency/threads.py +35 -0
  10. prefect/_internal/concurrency/waiters.py +0 -28
  11. prefect/_internal/pydantic/__init__.py +0 -45
  12. prefect/_internal/pydantic/v1_schema.py +21 -22
  13. prefect/_internal/pydantic/v2_schema.py +0 -2
  14. prefect/_internal/pydantic/v2_validated_func.py +18 -23
  15. prefect/_internal/schemas/bases.py +44 -177
  16. prefect/_internal/schemas/fields.py +1 -43
  17. prefect/_internal/schemas/validators.py +60 -158
  18. prefect/artifacts.py +161 -14
  19. prefect/automations.py +39 -4
  20. prefect/blocks/abstract.py +1 -1
  21. prefect/blocks/core.py +268 -148
  22. prefect/blocks/fields.py +2 -57
  23. prefect/blocks/kubernetes.py +8 -12
  24. prefect/blocks/notifications.py +40 -20
  25. prefect/blocks/system.py +22 -11
  26. prefect/blocks/webhook.py +2 -9
  27. prefect/client/base.py +4 -4
  28. prefect/client/cloud.py +8 -13
  29. prefect/client/orchestration.py +347 -341
  30. prefect/client/schemas/actions.py +92 -86
  31. prefect/client/schemas/filters.py +20 -40
  32. prefect/client/schemas/objects.py +151 -145
  33. prefect/client/schemas/responses.py +16 -24
  34. prefect/client/schemas/schedules.py +47 -35
  35. prefect/client/subscriptions.py +2 -2
  36. prefect/client/utilities.py +5 -2
  37. prefect/concurrency/asyncio.py +3 -1
  38. prefect/concurrency/events.py +1 -1
  39. prefect/concurrency/services.py +6 -3
  40. prefect/context.py +195 -27
  41. prefect/deployments/__init__.py +5 -6
  42. prefect/deployments/base.py +7 -5
  43. prefect/deployments/flow_runs.py +185 -0
  44. prefect/deployments/runner.py +50 -45
  45. prefect/deployments/schedules.py +28 -23
  46. prefect/deployments/steps/__init__.py +0 -1
  47. prefect/deployments/steps/core.py +1 -0
  48. prefect/deployments/steps/pull.py +7 -21
  49. prefect/engine.py +12 -2422
  50. prefect/events/actions.py +17 -23
  51. prefect/events/cli/automations.py +19 -6
  52. prefect/events/clients.py +14 -37
  53. prefect/events/filters.py +14 -18
  54. prefect/events/related.py +2 -2
  55. prefect/events/schemas/__init__.py +0 -5
  56. prefect/events/schemas/automations.py +55 -46
  57. prefect/events/schemas/deployment_triggers.py +7 -197
  58. prefect/events/schemas/events.py +34 -65
  59. prefect/events/schemas/labelling.py +10 -14
  60. prefect/events/utilities.py +2 -3
  61. prefect/events/worker.py +2 -3
  62. prefect/filesystems.py +6 -517
  63. prefect/{new_flow_engine.py → flow_engine.py} +313 -72
  64. prefect/flow_runs.py +377 -5
  65. prefect/flows.py +307 -166
  66. prefect/futures.py +186 -345
  67. prefect/infrastructure/__init__.py +0 -27
  68. prefect/infrastructure/provisioners/__init__.py +5 -3
  69. prefect/infrastructure/provisioners/cloud_run.py +11 -6
  70. prefect/infrastructure/provisioners/container_instance.py +11 -7
  71. prefect/infrastructure/provisioners/ecs.py +6 -4
  72. prefect/infrastructure/provisioners/modal.py +8 -5
  73. prefect/input/actions.py +2 -4
  74. prefect/input/run_input.py +5 -7
  75. prefect/logging/formatters.py +0 -2
  76. prefect/logging/handlers.py +3 -11
  77. prefect/logging/loggers.py +2 -2
  78. prefect/manifests.py +2 -1
  79. prefect/records/__init__.py +1 -0
  80. prefect/records/result_store.py +42 -0
  81. prefect/records/store.py +9 -0
  82. prefect/results.py +43 -39
  83. prefect/runner/runner.py +19 -15
  84. prefect/runner/server.py +6 -10
  85. prefect/runner/storage.py +3 -8
  86. prefect/runner/submit.py +2 -2
  87. prefect/runner/utils.py +2 -2
  88. prefect/serializers.py +24 -35
  89. prefect/server/api/collections_data/views/aggregate-worker-metadata.json +5 -14
  90. prefect/settings.py +70 -133
  91. prefect/states.py +17 -47
  92. prefect/task_engine.py +697 -58
  93. prefect/task_runners.py +269 -301
  94. prefect/task_server.py +53 -34
  95. prefect/tasks.py +327 -337
  96. prefect/transactions.py +220 -0
  97. prefect/types/__init__.py +61 -82
  98. prefect/utilities/asyncutils.py +195 -136
  99. prefect/utilities/callables.py +311 -43
  100. prefect/utilities/collections.py +23 -38
  101. prefect/utilities/dispatch.py +11 -3
  102. prefect/utilities/dockerutils.py +4 -0
  103. prefect/utilities/engine.py +140 -20
  104. prefect/utilities/importtools.py +97 -27
  105. prefect/utilities/pydantic.py +128 -38
  106. prefect/utilities/schema_tools/hydration.py +5 -1
  107. prefect/utilities/templating.py +12 -2
  108. prefect/variables.py +78 -61
  109. prefect/workers/__init__.py +0 -1
  110. prefect/workers/base.py +15 -17
  111. prefect/workers/process.py +3 -8
  112. prefect/workers/server.py +2 -2
  113. {prefect_client-2.19.2.dist-info → prefect_client-3.0.0rc1.dist-info}/METADATA +22 -21
  114. prefect_client-3.0.0rc1.dist-info/RECORD +176 -0
  115. prefect/_internal/pydantic/_base_model.py +0 -51
  116. prefect/_internal/pydantic/_compat.py +0 -82
  117. prefect/_internal/pydantic/_flags.py +0 -20
  118. prefect/_internal/pydantic/_types.py +0 -8
  119. prefect/_internal/pydantic/utilities/__init__.py +0 -0
  120. prefect/_internal/pydantic/utilities/config_dict.py +0 -72
  121. prefect/_internal/pydantic/utilities/field_validator.py +0 -150
  122. prefect/_internal/pydantic/utilities/model_construct.py +0 -56
  123. prefect/_internal/pydantic/utilities/model_copy.py +0 -55
  124. prefect/_internal/pydantic/utilities/model_dump.py +0 -136
  125. prefect/_internal/pydantic/utilities/model_dump_json.py +0 -112
  126. prefect/_internal/pydantic/utilities/model_fields.py +0 -50
  127. prefect/_internal/pydantic/utilities/model_fields_set.py +0 -29
  128. prefect/_internal/pydantic/utilities/model_json_schema.py +0 -82
  129. prefect/_internal/pydantic/utilities/model_rebuild.py +0 -80
  130. prefect/_internal/pydantic/utilities/model_validate.py +0 -75
  131. prefect/_internal/pydantic/utilities/model_validate_json.py +0 -68
  132. prefect/_internal/pydantic/utilities/model_validator.py +0 -87
  133. prefect/_internal/pydantic/utilities/type_adapter.py +0 -71
  134. prefect/_vendor/__init__.py +0 -0
  135. prefect/_vendor/fastapi/__init__.py +0 -25
  136. prefect/_vendor/fastapi/applications.py +0 -946
  137. prefect/_vendor/fastapi/background.py +0 -3
  138. prefect/_vendor/fastapi/concurrency.py +0 -44
  139. prefect/_vendor/fastapi/datastructures.py +0 -58
  140. prefect/_vendor/fastapi/dependencies/__init__.py +0 -0
  141. prefect/_vendor/fastapi/dependencies/models.py +0 -64
  142. prefect/_vendor/fastapi/dependencies/utils.py +0 -877
  143. prefect/_vendor/fastapi/encoders.py +0 -177
  144. prefect/_vendor/fastapi/exception_handlers.py +0 -40
  145. prefect/_vendor/fastapi/exceptions.py +0 -46
  146. prefect/_vendor/fastapi/logger.py +0 -3
  147. prefect/_vendor/fastapi/middleware/__init__.py +0 -1
  148. prefect/_vendor/fastapi/middleware/asyncexitstack.py +0 -25
  149. prefect/_vendor/fastapi/middleware/cors.py +0 -3
  150. prefect/_vendor/fastapi/middleware/gzip.py +0 -3
  151. prefect/_vendor/fastapi/middleware/httpsredirect.py +0 -3
  152. prefect/_vendor/fastapi/middleware/trustedhost.py +0 -3
  153. prefect/_vendor/fastapi/middleware/wsgi.py +0 -3
  154. prefect/_vendor/fastapi/openapi/__init__.py +0 -0
  155. prefect/_vendor/fastapi/openapi/constants.py +0 -2
  156. prefect/_vendor/fastapi/openapi/docs.py +0 -203
  157. prefect/_vendor/fastapi/openapi/models.py +0 -480
  158. prefect/_vendor/fastapi/openapi/utils.py +0 -485
  159. prefect/_vendor/fastapi/param_functions.py +0 -340
  160. prefect/_vendor/fastapi/params.py +0 -453
  161. prefect/_vendor/fastapi/requests.py +0 -4
  162. prefect/_vendor/fastapi/responses.py +0 -40
  163. prefect/_vendor/fastapi/routing.py +0 -1331
  164. prefect/_vendor/fastapi/security/__init__.py +0 -15
  165. prefect/_vendor/fastapi/security/api_key.py +0 -98
  166. prefect/_vendor/fastapi/security/base.py +0 -6
  167. prefect/_vendor/fastapi/security/http.py +0 -172
  168. prefect/_vendor/fastapi/security/oauth2.py +0 -227
  169. prefect/_vendor/fastapi/security/open_id_connect_url.py +0 -34
  170. prefect/_vendor/fastapi/security/utils.py +0 -10
  171. prefect/_vendor/fastapi/staticfiles.py +0 -1
  172. prefect/_vendor/fastapi/templating.py +0 -3
  173. prefect/_vendor/fastapi/testclient.py +0 -1
  174. prefect/_vendor/fastapi/types.py +0 -3
  175. prefect/_vendor/fastapi/utils.py +0 -235
  176. prefect/_vendor/fastapi/websockets.py +0 -7
  177. prefect/_vendor/starlette/__init__.py +0 -1
  178. prefect/_vendor/starlette/_compat.py +0 -28
  179. prefect/_vendor/starlette/_exception_handler.py +0 -80
  180. prefect/_vendor/starlette/_utils.py +0 -88
  181. prefect/_vendor/starlette/applications.py +0 -261
  182. prefect/_vendor/starlette/authentication.py +0 -159
  183. prefect/_vendor/starlette/background.py +0 -43
  184. prefect/_vendor/starlette/concurrency.py +0 -59
  185. prefect/_vendor/starlette/config.py +0 -151
  186. prefect/_vendor/starlette/convertors.py +0 -87
  187. prefect/_vendor/starlette/datastructures.py +0 -707
  188. prefect/_vendor/starlette/endpoints.py +0 -130
  189. prefect/_vendor/starlette/exceptions.py +0 -60
  190. prefect/_vendor/starlette/formparsers.py +0 -276
  191. prefect/_vendor/starlette/middleware/__init__.py +0 -17
  192. prefect/_vendor/starlette/middleware/authentication.py +0 -52
  193. prefect/_vendor/starlette/middleware/base.py +0 -220
  194. prefect/_vendor/starlette/middleware/cors.py +0 -176
  195. prefect/_vendor/starlette/middleware/errors.py +0 -265
  196. prefect/_vendor/starlette/middleware/exceptions.py +0 -74
  197. prefect/_vendor/starlette/middleware/gzip.py +0 -113
  198. prefect/_vendor/starlette/middleware/httpsredirect.py +0 -19
  199. prefect/_vendor/starlette/middleware/sessions.py +0 -82
  200. prefect/_vendor/starlette/middleware/trustedhost.py +0 -64
  201. prefect/_vendor/starlette/middleware/wsgi.py +0 -147
  202. prefect/_vendor/starlette/requests.py +0 -328
  203. prefect/_vendor/starlette/responses.py +0 -347
  204. prefect/_vendor/starlette/routing.py +0 -933
  205. prefect/_vendor/starlette/schemas.py +0 -154
  206. prefect/_vendor/starlette/staticfiles.py +0 -248
  207. prefect/_vendor/starlette/status.py +0 -199
  208. prefect/_vendor/starlette/templating.py +0 -231
  209. prefect/_vendor/starlette/testclient.py +0 -804
  210. prefect/_vendor/starlette/types.py +0 -30
  211. prefect/_vendor/starlette/websockets.py +0 -193
  212. prefect/agent.py +0 -698
  213. prefect/deployments/deployments.py +0 -1042
  214. prefect/deprecated/__init__.py +0 -0
  215. prefect/deprecated/data_documents.py +0 -350
  216. prefect/deprecated/packaging/__init__.py +0 -12
  217. prefect/deprecated/packaging/base.py +0 -96
  218. prefect/deprecated/packaging/docker.py +0 -146
  219. prefect/deprecated/packaging/file.py +0 -92
  220. prefect/deprecated/packaging/orion.py +0 -80
  221. prefect/deprecated/packaging/serializers.py +0 -171
  222. prefect/events/instrument.py +0 -135
  223. prefect/infrastructure/base.py +0 -323
  224. prefect/infrastructure/container.py +0 -818
  225. prefect/infrastructure/kubernetes.py +0 -920
  226. prefect/infrastructure/process.py +0 -289
  227. prefect/new_task_engine.py +0 -423
  228. prefect/pydantic/__init__.py +0 -76
  229. prefect/pydantic/main.py +0 -39
  230. prefect/software/__init__.py +0 -2
  231. prefect/software/base.py +0 -50
  232. prefect/software/conda.py +0 -199
  233. prefect/software/pip.py +0 -122
  234. prefect/software/python.py +0 -52
  235. prefect/workers/block.py +0 -218
  236. prefect_client-2.19.2.dist-info/RECORD +0 -292
  237. {prefect_client-2.19.2.dist-info → prefect_client-3.0.0rc1.dist-info}/LICENSE +0 -0
  238. {prefect_client-2.19.2.dist-info → prefect_client-3.0.0rc1.dist-info}/WHEEL +0 -0
  239. {prefect_client-2.19.2.dist-info → prefect_client-3.0.0rc1.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
- from prefect._internal.compatibility.deprecated import (
19
- DeprecatedInfraOverridesField,
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 prefect._internal.pydantic import HAS_PYDANTIC_V2
22
- from prefect.types import NonNegativeInteger, PositiveInteger
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, DateTimeTZ, UpdatedBy
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.utilities.collections import AutoEnum, listrepr
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):
@@ -97,6 +101,10 @@ class WorkPoolStatus(AutoEnum):
97
101
  NOT_READY = AutoEnum.auto()
98
102
  PAUSED = AutoEnum.auto()
99
103
 
104
+ @property
105
+ def display_name(self):
106
+ return self.name.replace("_", " ").capitalize()
107
+
100
108
 
101
109
  class WorkerStatus(AutoEnum):
102
110
  """Enumeration of worker statuses."""
@@ -125,11 +133,12 @@ class StateDetails(PrefectBaseModel):
125
133
  task_run_id: Optional[UUID] = None
126
134
  # for task runs that represent subflows, the subflow's run ID
127
135
  child_flow_run_id: Optional[UUID] = None
128
- scheduled_time: DateTimeTZ = None
136
+ scheduled_time: Optional[DateTime] = None
129
137
  cache_key: Optional[str] = None
130
- cache_expiration: DateTimeTZ = None
138
+ cache_expiration: Optional[DateTime] = None
139
+ deferred: Optional[bool] = None
131
140
  untrackable_result: bool = False
132
- pause_timeout: DateTimeTZ = None
141
+ pause_timeout: Optional[DateTime] = None
133
142
  pause_reschedule: bool = False
134
143
  pause_key: Optional[str] = None
135
144
  run_input_keyset: Optional[Dict[str, str]] = None
@@ -146,10 +155,10 @@ class State(ObjectBaseModel, Generic[R]):
146
155
 
147
156
  type: StateType
148
157
  name: Optional[str] = Field(default=None)
149
- timestamp: DateTimeTZ = Field(default_factory=lambda: pendulum.now("UTC"))
158
+ timestamp: DateTime = Field(default_factory=lambda: pendulum.now("UTC"))
150
159
  message: Optional[str] = Field(default=None, examples=["Run started"])
151
160
  state_details: StateDetails = Field(default_factory=StateDetails)
152
- data: Union["BaseResult[R]", "DataDocument[R]", Any] = Field(
161
+ data: Union["BaseResult[R]", Any] = Field(
153
162
  default=None,
154
163
  )
155
164
 
@@ -257,24 +266,22 @@ class State(ObjectBaseModel, Generic[R]):
257
266
  state_details=self.state_details,
258
267
  )
259
268
 
260
- @validator("name", always=True)
261
- def default_name_from_type(cls, v, *, values, **kwargs):
262
- return get_or_create_state_name(v, values)
263
-
264
- @root_validator
265
- def default_scheduled_start_time(cls, values):
266
- """
267
- TODO: This should throw an error instead of setting a default but is out of
268
- scope for https://github.com/PrefectHQ/orion/pull/174/ and can be rolled
269
- into work refactoring state initialization
270
- """
271
- if values.get("type") == StateType.SCHEDULED:
272
- state_details = values.setdefault(
273
- "state_details", cls.__fields__["state_details"].get_default()
274
- )
275
- if not state_details.scheduled_time:
276
- state_details.scheduled_time = pendulum.now("utc")
277
- return values
269
+ @model_validator(mode="after")
270
+ def default_name_from_type(self) -> Self:
271
+ """If a name is not provided, use the type"""
272
+ # if `type` is not in `values` it means the `type` didn't pass its own
273
+ # validation check and an error will be raised after this function is called
274
+ name = self.name
275
+ if name is None and self.type:
276
+ self.name = " ".join([v.capitalize() for v in self.type.value.split("_")])
277
+ return self
278
+
279
+ @model_validator(mode="after")
280
+ def default_scheduled_start_time(self) -> Self:
281
+ if self.type == StateType.SCHEDULED:
282
+ if not self.state_details.scheduled_time:
283
+ self.state_details.scheduled_time = pendulum.now("utc")
284
+ return self
278
285
 
279
286
  def is_scheduled(self) -> bool:
280
287
  return self.type == StateType.SCHEDULED
@@ -311,20 +318,30 @@ class State(ObjectBaseModel, Generic[R]):
311
318
  def is_paused(self) -> bool:
312
319
  return self.type == StateType.PAUSED
313
320
 
314
- def copy(
315
- self,
316
- *,
317
- update: Optional[Dict[str, Any]] = None,
318
- reset_fields: bool = False,
319
- **kwargs,
321
+ def model_copy(
322
+ self, *, update: Optional[Dict[str, Any]] = None, deep: bool = False
320
323
  ):
321
324
  """
322
325
  Copying API models should return an object that could be inserted into the
323
326
  database again. The 'timestamp' is reset using the default factory.
324
327
  """
325
328
  update = update or {}
326
- update.setdefault("timestamp", self.__fields__["timestamp"].get_default())
327
- return super().copy(reset_fields=reset_fields, update=update, **kwargs)
329
+ update.setdefault("timestamp", self.model_fields["timestamp"].get_default())
330
+ return super().model_copy(update=update, deep=deep)
331
+
332
+ def fresh_copy(self, **kwargs) -> Self:
333
+ """
334
+ Return a fresh copy of the state with a new ID.
335
+ """
336
+ return self.model_copy(
337
+ update={
338
+ "id": uuid4(),
339
+ "created": pendulum.now("utc"),
340
+ "updated": pendulum.now("utc"),
341
+ "timestamp": pendulum.now("utc"),
342
+ },
343
+ **kwargs,
344
+ )
328
345
 
329
346
  def __repr__(self) -> str:
330
347
  """
@@ -333,12 +350,7 @@ class State(ObjectBaseModel, Generic[R]):
333
350
 
334
351
  `MyCompletedState(message="my message", type=COMPLETED, result=...)`
335
352
  """
336
- from prefect.deprecated.data_documents import DataDocument
337
-
338
- if isinstance(self.data, DataDocument):
339
- result = self.data.decode()
340
- else:
341
- result = self.data
353
+ result = self.data
342
354
 
343
355
  display = dict(
344
356
  message=repr(self.message),
@@ -406,7 +418,7 @@ class FlowRunPolicy(PrefectBaseModel):
406
418
  default=False, description="Indicates if this run is resuming from a pause."
407
419
  )
408
420
 
409
- @root_validator
421
+ @model_validator(mode="before")
410
422
  def populate_deprecated_fields(cls, values):
411
423
  return set_run_policy_deprecated_fields(values)
412
424
 
@@ -475,18 +487,18 @@ class FlowRun(ObjectBaseModel):
475
487
  run_count: int = Field(
476
488
  default=0, description="The number of times the flow run was executed."
477
489
  )
478
- expected_start_time: Optional[DateTimeTZ] = Field(
490
+ expected_start_time: Optional[DateTime] = Field(
479
491
  default=None,
480
492
  description="The flow run's expected start time.",
481
493
  )
482
- next_scheduled_start_time: Optional[DateTimeTZ] = Field(
494
+ next_scheduled_start_time: Optional[DateTime] = Field(
483
495
  default=None,
484
496
  description="The next time the flow run is scheduled to start.",
485
497
  )
486
- start_time: Optional[DateTimeTZ] = Field(
498
+ start_time: Optional[DateTime] = Field(
487
499
  default=None, description="The actual start time."
488
500
  )
489
- end_time: Optional[DateTimeTZ] = Field(
501
+ end_time: Optional[DateTime] = Field(
490
502
  default=None, description="The actual end time."
491
503
  )
492
504
  total_run_time: datetime.timedelta = Field(
@@ -525,7 +537,7 @@ class FlowRun(ObjectBaseModel):
525
537
  )
526
538
 
527
539
  work_pool_id: Optional[UUID] = Field(
528
- description="The work pool with which the queue is associated."
540
+ default=None, description="The work pool with which the queue is associated."
529
541
  )
530
542
  work_pool_name: Optional[str] = Field(
531
543
  default=None,
@@ -535,7 +547,7 @@ class FlowRun(ObjectBaseModel):
535
547
  state: Optional[State] = Field(
536
548
  default=None,
537
549
  description="The state of the flow run.",
538
- examples=[State(type=StateType.COMPLETED)],
550
+ examples=["State(type=StateType.COMPLETED)"],
539
551
  )
540
552
  job_variables: Optional[dict] = Field(
541
553
  default=None, description="Job variables for the flow run."
@@ -560,12 +572,13 @@ class FlowRun(ObjectBaseModel):
560
572
  """
561
573
  if isinstance(other, FlowRun):
562
574
  exclude_fields = {"estimated_run_time", "estimated_start_time_delta"}
563
- return self.dict(exclude=exclude_fields) == other.dict(
575
+ return self.model_dump(exclude=exclude_fields) == other.model_dump(
564
576
  exclude=exclude_fields
565
577
  )
566
578
  return super().__eq__(other)
567
579
 
568
- @validator("name", pre=True)
580
+ @field_validator("name", mode="before")
581
+ @classmethod
569
582
  def set_default_name(cls, name):
570
583
  return get_or_create_run_name(name)
571
584
 
@@ -598,15 +611,32 @@ class TaskRunPolicy(PrefectBaseModel):
598
611
  default=None, description="Determines the amount a retry should jitter"
599
612
  )
600
613
 
601
- @root_validator
602
- def populate_deprecated_fields(cls, values):
603
- return set_run_policy_deprecated_fields(values)
614
+ @model_validator(mode="after")
615
+ def populate_deprecated_fields(self):
616
+ """
617
+ If deprecated fields are provided, populate the corresponding new fields
618
+ to preserve orchestration behavior.
619
+ """
620
+ # We have marked these fields as deprecated, so we need to filter out the
621
+ # deprecation warnings _we're_ generating here
622
+ with warnings.catch_warnings():
623
+ warnings.simplefilter("ignore", DeprecationWarning)
604
624
 
605
- @validator("retry_delay")
625
+ if not self.retries and self.max_retries != 0:
626
+ self.retries = self.max_retries
627
+
628
+ if not self.retry_delay and self.retry_delay_seconds != 0:
629
+ self.retry_delay = self.retry_delay_seconds
630
+
631
+ return self
632
+
633
+ @field_validator("retry_delay")
634
+ @classmethod
606
635
  def validate_configured_retry_delays(cls, v):
607
636
  return list_length_50_or_less(v)
608
637
 
609
- @validator("retry_jitter_factor")
638
+ @field_validator("retry_jitter_factor")
639
+ @classmethod
610
640
  def validate_jitter_factor(cls, v):
611
641
  return validate_not_negative(v)
612
642
 
@@ -617,9 +647,7 @@ class TaskRunInput(PrefectBaseModel):
617
647
  could include, constants, parameters, or other task runs.
618
648
  """
619
649
 
620
- # freeze TaskRunInputs to allow them to be placed in sets
621
- class Config:
622
- frozen = True
650
+ model_config = ConfigDict(frozen=True)
623
651
 
624
652
  input_type: str
625
653
 
@@ -670,7 +698,7 @@ class TaskRun(ObjectBaseModel):
670
698
  " the task run."
671
699
  ),
672
700
  )
673
- cache_expiration: Optional[DateTimeTZ] = Field(
701
+ cache_expiration: Optional[DateTime] = Field(
674
702
  default=None, description="Specifies when the cached state should expire."
675
703
  )
676
704
  task_version: Optional[str] = Field(
@@ -711,21 +739,21 @@ class TaskRun(ObjectBaseModel):
711
739
  " associated with."
712
740
  ),
713
741
  )
714
- expected_start_time: Optional[DateTimeTZ] = Field(
742
+ expected_start_time: Optional[DateTime] = Field(
715
743
  default=None,
716
744
  description="The task run's expected start time.",
717
745
  )
718
746
 
719
747
  # the next scheduled start time will be populated
720
748
  # whenever the run is in a scheduled state
721
- next_scheduled_start_time: Optional[DateTimeTZ] = Field(
749
+ next_scheduled_start_time: Optional[DateTime] = Field(
722
750
  default=None,
723
751
  description="The next time the task run is scheduled to start.",
724
752
  )
725
- start_time: Optional[DateTimeTZ] = Field(
753
+ start_time: Optional[DateTime] = Field(
726
754
  default=None, description="The actual start time."
727
755
  )
728
- end_time: Optional[DateTimeTZ] = Field(
756
+ end_time: Optional[DateTime] = Field(
729
757
  default=None, description="The actual end time."
730
758
  )
731
759
  total_run_time: datetime.timedelta = Field(
@@ -747,10 +775,11 @@ class TaskRun(ObjectBaseModel):
747
775
  state: Optional[State] = Field(
748
776
  default=None,
749
777
  description="The state of the flow run.",
750
- examples=[State(type=StateType.COMPLETED)],
778
+ examples=["State(type=StateType.COMPLETED)"],
751
779
  )
752
780
 
753
- @validator("name", pre=True)
781
+ @field_validator("name", mode="before")
782
+ @classmethod
754
783
  def set_default_name(cls, name):
755
784
  return get_or_create_run_name(name)
756
785
 
@@ -769,9 +798,7 @@ class Workspace(PrefectBaseModel):
769
798
  workspace_name: str = Field(..., description="The workspace name.")
770
799
  workspace_description: str = Field(..., description="Description of the workspace.")
771
800
  workspace_handle: str = Field(..., description="The workspace's unique handle.")
772
-
773
- class Config:
774
- extra = "ignore"
801
+ model_config = ConfigDict(extra="ignore")
775
802
 
776
803
  @property
777
804
  def handle(self) -> str:
@@ -807,7 +834,7 @@ class Workspace(PrefectBaseModel):
807
834
  class BlockType(ObjectBaseModel):
808
835
  """An ORM representation of a block type"""
809
836
 
810
- name: str = Field(default=..., description="A block type's name")
837
+ name: Name = Field(default=..., description="A block type's name")
811
838
  slug: str = Field(default=..., description="A block type's slug")
812
839
  logo_url: Optional[HttpUrl] = Field(
813
840
  default=None, description="Web URL for the block type's logo"
@@ -827,10 +854,6 @@ class BlockType(ObjectBaseModel):
827
854
  default=False, description="Protected block types cannot be modified via API."
828
855
  )
829
856
 
830
- @validator("name", check_fields=False)
831
- def validate_name_characters(cls, v):
832
- return raise_on_name_with_banned_characters(v)
833
-
834
857
 
835
858
  class BlockSchema(ObjectBaseModel):
836
859
  """A representation of a block schema."""
@@ -856,7 +879,7 @@ class BlockSchema(ObjectBaseModel):
856
879
  class BlockDocument(ObjectBaseModel):
857
880
  """An ORM representation of a block document."""
858
881
 
859
- name: Optional[str] = Field(
882
+ name: Optional[Name] = Field(
860
883
  default=None,
861
884
  description=(
862
885
  "The block document's name. Not required for anonymous block documents."
@@ -885,21 +908,26 @@ class BlockDocument(ObjectBaseModel):
885
908
  ),
886
909
  )
887
910
 
888
- @validator("name", check_fields=False)
889
- def validate_name_characters(cls, v):
890
- # the BlockDocumentCreate subclass allows name=None
891
- # and will inherit this validator
892
- return raise_on_name_with_banned_characters(v)
911
+ _validate_name_format = field_validator("name")(validate_block_document_name)
893
912
 
894
- @root_validator
913
+ @model_validator(mode="before")
895
914
  def validate_name_is_present_if_not_anonymous(cls, values):
896
915
  return validate_name_present_on_nonanonymous_blocks(values)
897
916
 
917
+ @model_serializer(mode="wrap")
918
+ def serialize_data(self, handler, info: SerializationInfo):
919
+ self.data = visit_collection(
920
+ self.data,
921
+ visit_fn=partial(handle_secret_render, context=info.context or {}),
922
+ return_data=True,
923
+ )
924
+ return handler(self)
925
+
898
926
 
899
927
  class Flow(ObjectBaseModel):
900
928
  """An ORM representation of flow data."""
901
929
 
902
- name: str = Field(
930
+ name: Name = Field(
903
931
  default=..., description="The name of the flow", examples=["my-flow"]
904
932
  )
905
933
  tags: List[str] = Field(
@@ -908,19 +936,6 @@ class Flow(ObjectBaseModel):
908
936
  examples=[["tag-1", "tag-2"]],
909
937
  )
910
938
 
911
- @validator("name", check_fields=False)
912
- def validate_name_characters(cls, v):
913
- return raise_on_name_with_banned_characters(v)
914
-
915
-
916
- class MinimalDeploymentSchedule(PrefectBaseModel):
917
- schedule: SCHEDULE_TYPES = Field(
918
- default=..., description="The schedule for the deployment."
919
- )
920
- active: bool = Field(
921
- default=True, description="Whether or not the schedule is active."
922
- )
923
-
924
939
 
925
940
  class DeploymentSchedule(ObjectBaseModel):
926
941
  deployment_id: Optional[UUID] = Field(
@@ -947,10 +962,10 @@ class DeploymentSchedule(ObjectBaseModel):
947
962
  )
948
963
 
949
964
 
950
- class Deployment(DeprecatedInfraOverridesField, ObjectBaseModel):
965
+ class Deployment(ObjectBaseModel):
951
966
  """An ORM representation of deployment data."""
952
967
 
953
- name: str = Field(default=..., description="The name of the deployment.")
968
+ name: Name = Field(default=..., description="The name of the deployment.")
954
969
  version: Optional[str] = Field(
955
970
  default=None, description="An optional version for the deployment."
956
971
  )
@@ -996,7 +1011,7 @@ class Deployment(DeprecatedInfraOverridesField, ObjectBaseModel):
996
1011
  " be scheduled."
997
1012
  ),
998
1013
  )
999
- last_polled: Optional[DateTimeTZ] = Field(
1014
+ last_polled: Optional[DateTime] = Field(
1000
1015
  default=None,
1001
1016
  description="The last time the deployment was polled for status updates.",
1002
1017
  )
@@ -1039,23 +1054,19 @@ class Deployment(DeprecatedInfraOverridesField, ObjectBaseModel):
1039
1054
  default=None,
1040
1055
  description="Optional information about the updater of this deployment.",
1041
1056
  )
1042
- work_queue_id: UUID = Field(
1057
+ work_queue_id: Optional[UUID] = Field(
1043
1058
  default=None,
1044
1059
  description=(
1045
1060
  "The id of the work pool queue to which this deployment is assigned."
1046
1061
  ),
1047
1062
  )
1048
1063
  enforce_parameter_schema: bool = Field(
1049
- default=False,
1064
+ default=True,
1050
1065
  description=(
1051
1066
  "Whether or not the deployment should enforce the parameter schema."
1052
1067
  ),
1053
1068
  )
1054
1069
 
1055
- @validator("name", check_fields=False)
1056
- def validate_name_characters(cls, v):
1057
- return raise_on_name_with_banned_characters(v)
1058
-
1059
1070
 
1060
1071
  class ConcurrencyLimit(ObjectBaseModel):
1061
1072
  """An ORM representation of a concurrency limit."""
@@ -1130,7 +1141,7 @@ class BlockDocumentReference(ObjectBaseModel):
1130
1141
  default=..., description="The name that the reference is nested under"
1131
1142
  )
1132
1143
 
1133
- @root_validator
1144
+ @model_validator(mode="before")
1134
1145
  def validate_parent_and_ref_are_different(cls, values):
1135
1146
  return validate_parent_and_ref_diff(values)
1136
1147
 
@@ -1174,7 +1185,7 @@ class Log(ObjectBaseModel):
1174
1185
  name: str = Field(default=..., description="The logger name.")
1175
1186
  level: int = Field(default=..., description="The log level.")
1176
1187
  message: str = Field(default=..., description="The log message.")
1177
- timestamp: DateTimeTZ = Field(default=..., description="The log timestamp.")
1188
+ timestamp: DateTime = Field(default=..., description="The log timestamp.")
1178
1189
  flow_run_id: Optional[UUID] = Field(
1179
1190
  default=None, description="The flow run ID associated with the log."
1180
1191
  )
@@ -1199,7 +1210,7 @@ class QueueFilter(PrefectBaseModel):
1199
1210
  class WorkQueue(ObjectBaseModel):
1200
1211
  """An ORM representation of a work queue"""
1201
1212
 
1202
- name: str = Field(default=..., description="The name of the work queue.")
1213
+ name: Name = Field(default=..., description="The name of the work queue.")
1203
1214
  description: Optional[str] = Field(
1204
1215
  default="", description="An optional description for the work queue."
1205
1216
  )
@@ -1225,17 +1236,13 @@ class WorkQueue(ObjectBaseModel):
1225
1236
  description="DEPRECATED: Filter criteria for the work queue.",
1226
1237
  deprecated=True,
1227
1238
  )
1228
- last_polled: Optional[DateTimeTZ] = Field(
1239
+ last_polled: Optional[DateTime] = Field(
1229
1240
  default=None, description="The last time an agent polled this queue for work."
1230
1241
  )
1231
1242
  status: Optional[WorkQueueStatus] = Field(
1232
1243
  default=None, description="The queue status."
1233
1244
  )
1234
1245
 
1235
- @validator("name", check_fields=False)
1236
- def validate_name_characters(cls, v):
1237
- return raise_on_name_with_banned_characters(v)
1238
-
1239
1246
 
1240
1247
  class WorkQueueHealthPolicy(PrefectBaseModel):
1241
1248
  maximum_late_runs: Optional[int] = Field(
@@ -1254,7 +1261,7 @@ class WorkQueueHealthPolicy(PrefectBaseModel):
1254
1261
  )
1255
1262
 
1256
1263
  def evaluate_health_status(
1257
- self, late_runs_count: int, last_polled: Optional[DateTimeTZ] = None
1264
+ self, late_runs_count: int, last_polled: Optional[DateTime] = None
1258
1265
  ) -> bool:
1259
1266
  """
1260
1267
  Given empirical information about the state of the work queue, evaluate its health status.
@@ -1289,7 +1296,7 @@ class WorkQueueStatusDetail(PrefectBaseModel):
1289
1296
  late_runs_count: int = Field(
1290
1297
  default=0, description="The number of late flow runs in the work queue."
1291
1298
  )
1292
- last_polled: Optional[DateTimeTZ] = Field(
1299
+ last_polled: Optional[DateTime] = Field(
1293
1300
  default=None, description="The last time an agent polled this queue for work."
1294
1301
  )
1295
1302
  health_check_policy: WorkQueueHealthPolicy = Field(
@@ -1329,7 +1336,8 @@ class FlowRunNotificationPolicy(ObjectBaseModel):
1329
1336
  ],
1330
1337
  )
1331
1338
 
1332
- @validator("message_template")
1339
+ @field_validator("message_template")
1340
+ @classmethod
1333
1341
  def validate_message_template_variables(cls, v):
1334
1342
  return validate_message_template_variables(v)
1335
1343
 
@@ -1347,7 +1355,7 @@ class Agent(ObjectBaseModel):
1347
1355
  work_queue_id: UUID = Field(
1348
1356
  default=..., description="The work queue with which the agent is associated."
1349
1357
  )
1350
- last_activity_time: Optional[DateTimeTZ] = Field(
1358
+ last_activity_time: Optional[DateTime] = Field(
1351
1359
  default=None, description="The last time this agent polled for work."
1352
1360
  )
1353
1361
 
@@ -1355,7 +1363,7 @@ class Agent(ObjectBaseModel):
1355
1363
  class WorkPool(ObjectBaseModel):
1356
1364
  """An ORM representation of a work pool"""
1357
1365
 
1358
- name: str = Field(
1366
+ name: Name = Field(
1359
1367
  description="The name of the work pool.",
1360
1368
  )
1361
1369
  description: Optional[str] = Field(
@@ -1390,11 +1398,8 @@ class WorkPool(ObjectBaseModel):
1390
1398
  def is_managed_pool(self) -> bool:
1391
1399
  return self.type.endswith(":managed")
1392
1400
 
1393
- @validator("name", check_fields=False)
1394
- def validate_name_characters(cls, v):
1395
- return raise_on_name_with_banned_characters(v)
1396
-
1397
- @validator("default_queue_id", always=True)
1401
+ @field_validator("default_queue_id")
1402
+ @classmethod
1398
1403
  def helpful_error_for_missing_default_queue_id(cls, v):
1399
1404
  return validate_default_queue_id_not_none(v)
1400
1405
 
@@ -1421,8 +1426,8 @@ class Worker(ObjectBaseModel):
1421
1426
  )
1422
1427
 
1423
1428
 
1424
- Flow.update_forward_refs()
1425
- FlowRun.update_forward_refs()
1429
+ Flow.model_rebuild()
1430
+ # FlowRun.model_rebuild()
1426
1431
 
1427
1432
 
1428
1433
  class Artifact(ObjectBaseModel):
@@ -1461,7 +1466,8 @@ class Artifact(ObjectBaseModel):
1461
1466
  default=None, description="The task run associated with the artifact."
1462
1467
  )
1463
1468
 
1464
- @validator("metadata_")
1469
+ @field_validator("metadata_")
1470
+ @classmethod
1465
1471
  def validate_metadata_length(cls, v):
1466
1472
  return validate_max_metadata_length(v)
1467
1473
 
@@ -1510,11 +1516,10 @@ class Variable(ObjectBaseModel):
1510
1516
  examples=["my_variable"],
1511
1517
  max_length=MAX_VARIABLE_NAME_LENGTH,
1512
1518
  )
1513
- value: str = Field(
1519
+ value: StrictVariableValue = Field(
1514
1520
  default=...,
1515
1521
  description="The value of the variable",
1516
1522
  examples=["my_value"],
1517
- max_length=MAX_VARIABLE_VALUE_LENGTH,
1518
1523
  )
1519
1524
  tags: List[str] = Field(
1520
1525
  default_factory=list,
@@ -1527,7 +1532,7 @@ class FlowRunInput(ObjectBaseModel):
1527
1532
  flow_run_id: UUID = Field(description="The flow run ID associated with the input.")
1528
1533
  key: str = Field(description="The key of the input.")
1529
1534
  value: str = Field(description="The value of the input.")
1530
- sender: Optional[str] = Field(description="The sender of the input.")
1535
+ sender: Optional[str] = Field(default=None, description="The sender of the input.")
1531
1536
 
1532
1537
  @property
1533
1538
  def decoded_value(self) -> Any:
@@ -1539,7 +1544,8 @@ class FlowRunInput(ObjectBaseModel):
1539
1544
  """
1540
1545
  return orjson.loads(self.value)
1541
1546
 
1542
- @validator("key", check_fields=False)
1547
+ @field_validator("key", check_fields=False)
1548
+ @classmethod
1543
1549
  def validate_name_characters(cls, v):
1544
1550
  raise_on_name_alphanumeric_dashes_only(v)
1545
1551
  return v
@@ -1580,6 +1586,6 @@ class CsrfToken(ObjectBaseModel):
1580
1586
  client: str = Field(
1581
1587
  default=..., description="The client id associated with the CSRF token"
1582
1588
  )
1583
- expiration: DateTimeTZ = Field(
1589
+ expiration: datetime.datetime = Field(
1584
1590
  default=..., description="The expiration time of the CSRF token"
1585
1591
  )