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.
Files changed (242) 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/redis.py +168 -0
  26. prefect/blocks/system.py +22 -11
  27. prefect/blocks/webhook.py +2 -9
  28. prefect/client/base.py +4 -4
  29. prefect/client/cloud.py +8 -13
  30. prefect/client/orchestration.py +362 -340
  31. prefect/client/schemas/actions.py +92 -86
  32. prefect/client/schemas/filters.py +20 -40
  33. prefect/client/schemas/objects.py +158 -152
  34. prefect/client/schemas/responses.py +16 -24
  35. prefect/client/schemas/schedules.py +47 -35
  36. prefect/client/subscriptions.py +2 -2
  37. prefect/client/utilities.py +5 -2
  38. prefect/concurrency/asyncio.py +4 -2
  39. prefect/concurrency/events.py +1 -1
  40. prefect/concurrency/services.py +7 -4
  41. prefect/context.py +195 -27
  42. prefect/deployments/__init__.py +5 -6
  43. prefect/deployments/base.py +7 -5
  44. prefect/deployments/flow_runs.py +185 -0
  45. prefect/deployments/runner.py +50 -45
  46. prefect/deployments/schedules.py +28 -23
  47. prefect/deployments/steps/__init__.py +0 -1
  48. prefect/deployments/steps/core.py +1 -0
  49. prefect/deployments/steps/pull.py +7 -21
  50. prefect/engine.py +12 -2422
  51. prefect/events/actions.py +17 -23
  52. prefect/events/cli/automations.py +19 -6
  53. prefect/events/clients.py +14 -37
  54. prefect/events/filters.py +14 -18
  55. prefect/events/related.py +2 -2
  56. prefect/events/schemas/__init__.py +0 -5
  57. prefect/events/schemas/automations.py +55 -46
  58. prefect/events/schemas/deployment_triggers.py +7 -197
  59. prefect/events/schemas/events.py +36 -65
  60. prefect/events/schemas/labelling.py +10 -14
  61. prefect/events/utilities.py +2 -3
  62. prefect/events/worker.py +2 -3
  63. prefect/filesystems.py +6 -517
  64. prefect/{new_flow_engine.py → flow_engine.py} +315 -74
  65. prefect/flow_runs.py +379 -7
  66. prefect/flows.py +248 -165
  67. prefect/futures.py +187 -345
  68. prefect/infrastructure/__init__.py +0 -27
  69. prefect/infrastructure/provisioners/__init__.py +5 -3
  70. prefect/infrastructure/provisioners/cloud_run.py +11 -6
  71. prefect/infrastructure/provisioners/container_instance.py +11 -7
  72. prefect/infrastructure/provisioners/ecs.py +6 -4
  73. prefect/infrastructure/provisioners/modal.py +8 -5
  74. prefect/input/actions.py +2 -4
  75. prefect/input/run_input.py +9 -9
  76. prefect/logging/formatters.py +0 -2
  77. prefect/logging/handlers.py +3 -11
  78. prefect/logging/loggers.py +2 -2
  79. prefect/manifests.py +2 -1
  80. prefect/records/__init__.py +1 -0
  81. prefect/records/cache_policies.py +179 -0
  82. prefect/records/result_store.py +42 -0
  83. prefect/records/store.py +9 -0
  84. prefect/results.py +43 -39
  85. prefect/runner/runner.py +9 -9
  86. prefect/runner/server.py +6 -10
  87. prefect/runner/storage.py +3 -8
  88. prefect/runner/submit.py +2 -2
  89. prefect/runner/utils.py +2 -2
  90. prefect/serializers.py +24 -35
  91. prefect/server/api/collections_data/views/aggregate-worker-metadata.json +5 -14
  92. prefect/settings.py +76 -136
  93. prefect/states.py +22 -50
  94. prefect/task_engine.py +666 -56
  95. prefect/task_runners.py +272 -300
  96. prefect/task_runs.py +203 -0
  97. prefect/{task_server.py → task_worker.py} +89 -60
  98. prefect/tasks.py +358 -341
  99. prefect/transactions.py +224 -0
  100. prefect/types/__init__.py +61 -82
  101. prefect/utilities/asyncutils.py +195 -136
  102. prefect/utilities/callables.py +121 -41
  103. prefect/utilities/collections.py +23 -38
  104. prefect/utilities/dispatch.py +11 -3
  105. prefect/utilities/dockerutils.py +4 -0
  106. prefect/utilities/engine.py +140 -20
  107. prefect/utilities/importtools.py +26 -27
  108. prefect/utilities/pydantic.py +128 -38
  109. prefect/utilities/schema_tools/hydration.py +5 -1
  110. prefect/utilities/templating.py +12 -2
  111. prefect/variables.py +84 -62
  112. prefect/workers/__init__.py +0 -1
  113. prefect/workers/base.py +26 -18
  114. prefect/workers/process.py +3 -8
  115. prefect/workers/server.py +2 -2
  116. {prefect_client-2.19.4.dist-info → prefect_client-3.0.0rc2.dist-info}/METADATA +23 -21
  117. prefect_client-3.0.0rc2.dist-info/RECORD +179 -0
  118. prefect/_internal/pydantic/_base_model.py +0 -51
  119. prefect/_internal/pydantic/_compat.py +0 -82
  120. prefect/_internal/pydantic/_flags.py +0 -20
  121. prefect/_internal/pydantic/_types.py +0 -8
  122. prefect/_internal/pydantic/utilities/__init__.py +0 -0
  123. prefect/_internal/pydantic/utilities/config_dict.py +0 -72
  124. prefect/_internal/pydantic/utilities/field_validator.py +0 -150
  125. prefect/_internal/pydantic/utilities/model_construct.py +0 -56
  126. prefect/_internal/pydantic/utilities/model_copy.py +0 -55
  127. prefect/_internal/pydantic/utilities/model_dump.py +0 -136
  128. prefect/_internal/pydantic/utilities/model_dump_json.py +0 -112
  129. prefect/_internal/pydantic/utilities/model_fields.py +0 -50
  130. prefect/_internal/pydantic/utilities/model_fields_set.py +0 -29
  131. prefect/_internal/pydantic/utilities/model_json_schema.py +0 -82
  132. prefect/_internal/pydantic/utilities/model_rebuild.py +0 -80
  133. prefect/_internal/pydantic/utilities/model_validate.py +0 -75
  134. prefect/_internal/pydantic/utilities/model_validate_json.py +0 -68
  135. prefect/_internal/pydantic/utilities/model_validator.py +0 -87
  136. prefect/_internal/pydantic/utilities/type_adapter.py +0 -71
  137. prefect/_vendor/__init__.py +0 -0
  138. prefect/_vendor/fastapi/__init__.py +0 -25
  139. prefect/_vendor/fastapi/applications.py +0 -946
  140. prefect/_vendor/fastapi/background.py +0 -3
  141. prefect/_vendor/fastapi/concurrency.py +0 -44
  142. prefect/_vendor/fastapi/datastructures.py +0 -58
  143. prefect/_vendor/fastapi/dependencies/__init__.py +0 -0
  144. prefect/_vendor/fastapi/dependencies/models.py +0 -64
  145. prefect/_vendor/fastapi/dependencies/utils.py +0 -877
  146. prefect/_vendor/fastapi/encoders.py +0 -177
  147. prefect/_vendor/fastapi/exception_handlers.py +0 -40
  148. prefect/_vendor/fastapi/exceptions.py +0 -46
  149. prefect/_vendor/fastapi/logger.py +0 -3
  150. prefect/_vendor/fastapi/middleware/__init__.py +0 -1
  151. prefect/_vendor/fastapi/middleware/asyncexitstack.py +0 -25
  152. prefect/_vendor/fastapi/middleware/cors.py +0 -3
  153. prefect/_vendor/fastapi/middleware/gzip.py +0 -3
  154. prefect/_vendor/fastapi/middleware/httpsredirect.py +0 -3
  155. prefect/_vendor/fastapi/middleware/trustedhost.py +0 -3
  156. prefect/_vendor/fastapi/middleware/wsgi.py +0 -3
  157. prefect/_vendor/fastapi/openapi/__init__.py +0 -0
  158. prefect/_vendor/fastapi/openapi/constants.py +0 -2
  159. prefect/_vendor/fastapi/openapi/docs.py +0 -203
  160. prefect/_vendor/fastapi/openapi/models.py +0 -480
  161. prefect/_vendor/fastapi/openapi/utils.py +0 -485
  162. prefect/_vendor/fastapi/param_functions.py +0 -340
  163. prefect/_vendor/fastapi/params.py +0 -453
  164. prefect/_vendor/fastapi/requests.py +0 -4
  165. prefect/_vendor/fastapi/responses.py +0 -40
  166. prefect/_vendor/fastapi/routing.py +0 -1331
  167. prefect/_vendor/fastapi/security/__init__.py +0 -15
  168. prefect/_vendor/fastapi/security/api_key.py +0 -98
  169. prefect/_vendor/fastapi/security/base.py +0 -6
  170. prefect/_vendor/fastapi/security/http.py +0 -172
  171. prefect/_vendor/fastapi/security/oauth2.py +0 -227
  172. prefect/_vendor/fastapi/security/open_id_connect_url.py +0 -34
  173. prefect/_vendor/fastapi/security/utils.py +0 -10
  174. prefect/_vendor/fastapi/staticfiles.py +0 -1
  175. prefect/_vendor/fastapi/templating.py +0 -3
  176. prefect/_vendor/fastapi/testclient.py +0 -1
  177. prefect/_vendor/fastapi/types.py +0 -3
  178. prefect/_vendor/fastapi/utils.py +0 -235
  179. prefect/_vendor/fastapi/websockets.py +0 -7
  180. prefect/_vendor/starlette/__init__.py +0 -1
  181. prefect/_vendor/starlette/_compat.py +0 -28
  182. prefect/_vendor/starlette/_exception_handler.py +0 -80
  183. prefect/_vendor/starlette/_utils.py +0 -88
  184. prefect/_vendor/starlette/applications.py +0 -261
  185. prefect/_vendor/starlette/authentication.py +0 -159
  186. prefect/_vendor/starlette/background.py +0 -43
  187. prefect/_vendor/starlette/concurrency.py +0 -59
  188. prefect/_vendor/starlette/config.py +0 -151
  189. prefect/_vendor/starlette/convertors.py +0 -87
  190. prefect/_vendor/starlette/datastructures.py +0 -707
  191. prefect/_vendor/starlette/endpoints.py +0 -130
  192. prefect/_vendor/starlette/exceptions.py +0 -60
  193. prefect/_vendor/starlette/formparsers.py +0 -276
  194. prefect/_vendor/starlette/middleware/__init__.py +0 -17
  195. prefect/_vendor/starlette/middleware/authentication.py +0 -52
  196. prefect/_vendor/starlette/middleware/base.py +0 -220
  197. prefect/_vendor/starlette/middleware/cors.py +0 -176
  198. prefect/_vendor/starlette/middleware/errors.py +0 -265
  199. prefect/_vendor/starlette/middleware/exceptions.py +0 -74
  200. prefect/_vendor/starlette/middleware/gzip.py +0 -113
  201. prefect/_vendor/starlette/middleware/httpsredirect.py +0 -19
  202. prefect/_vendor/starlette/middleware/sessions.py +0 -82
  203. prefect/_vendor/starlette/middleware/trustedhost.py +0 -64
  204. prefect/_vendor/starlette/middleware/wsgi.py +0 -147
  205. prefect/_vendor/starlette/requests.py +0 -328
  206. prefect/_vendor/starlette/responses.py +0 -347
  207. prefect/_vendor/starlette/routing.py +0 -933
  208. prefect/_vendor/starlette/schemas.py +0 -154
  209. prefect/_vendor/starlette/staticfiles.py +0 -248
  210. prefect/_vendor/starlette/status.py +0 -199
  211. prefect/_vendor/starlette/templating.py +0 -231
  212. prefect/_vendor/starlette/testclient.py +0 -804
  213. prefect/_vendor/starlette/types.py +0 -30
  214. prefect/_vendor/starlette/websockets.py +0 -193
  215. prefect/agent.py +0 -698
  216. prefect/deployments/deployments.py +0 -1042
  217. prefect/deprecated/__init__.py +0 -0
  218. prefect/deprecated/data_documents.py +0 -350
  219. prefect/deprecated/packaging/__init__.py +0 -12
  220. prefect/deprecated/packaging/base.py +0 -96
  221. prefect/deprecated/packaging/docker.py +0 -146
  222. prefect/deprecated/packaging/file.py +0 -92
  223. prefect/deprecated/packaging/orion.py +0 -80
  224. prefect/deprecated/packaging/serializers.py +0 -171
  225. prefect/events/instrument.py +0 -135
  226. prefect/infrastructure/base.py +0 -323
  227. prefect/infrastructure/container.py +0 -818
  228. prefect/infrastructure/kubernetes.py +0 -920
  229. prefect/infrastructure/process.py +0 -289
  230. prefect/new_task_engine.py +0 -423
  231. prefect/pydantic/__init__.py +0 -76
  232. prefect/pydantic/main.py +0 -39
  233. prefect/software/__init__.py +0 -2
  234. prefect/software/base.py +0 -50
  235. prefect/software/conda.py +0 -199
  236. prefect/software/pip.py +0 -122
  237. prefect/software/python.py +0 -52
  238. prefect/workers/block.py +0 -218
  239. prefect_client-2.19.4.dist-info/RECORD +0 -292
  240. {prefect_client-2.19.4.dist-info → prefect_client-3.0.0rc2.dist-info}/LICENSE +0 -0
  241. {prefect_client-2.19.4.dist-info → prefect_client-3.0.0rc2.dist-info}/WHEEL +0 -0
  242. {prefect_client-2.19.4.dist-info → prefect_client-3.0.0rc2.dist-info}/top_level.txt +0 -0
@@ -2,19 +2,13 @@ import datetime
2
2
  from typing import Any, Dict, List, Optional, TypeVar, Union
3
3
  from uuid import UUID
4
4
 
5
- from prefect._internal.compatibility.deprecated import DeprecatedInfraOverridesField
6
- from prefect._internal.pydantic import HAS_PYDANTIC_V2
7
-
8
- if HAS_PYDANTIC_V2:
9
- from pydantic.v1 import Field
10
- else:
11
- from pydantic import Field
12
-
5
+ from pydantic import ConfigDict, Field
6
+ from pydantic_extra_types.pendulum_dt import DateTime
13
7
  from typing_extensions import Literal
14
8
 
15
9
  import prefect.client.schemas.objects as objects
16
10
  from prefect._internal.schemas.bases import ObjectBaseModel, PrefectBaseModel
17
- from prefect._internal.schemas.fields import CreatedBy, DateTimeTZ, UpdatedBy
11
+ from prefect._internal.schemas.fields import CreatedBy, UpdatedBy
18
12
  from prefect.client.schemas.schedules import SCHEDULE_TYPES
19
13
  from prefect.utilities.collections import AutoEnum
20
14
  from prefect.utilities.names import generate_slug
@@ -120,10 +114,10 @@ class HistoryResponseState(PrefectBaseModel):
120
114
  class HistoryResponse(PrefectBaseModel):
121
115
  """Represents a history of aggregation states over an interval"""
122
116
 
123
- interval_start: DateTimeTZ = Field(
117
+ interval_start: DateTime = Field(
124
118
  default=..., description="The start date of the interval."
125
119
  )
126
- interval_end: DateTimeTZ = Field(
120
+ interval_end: DateTime = Field(
127
121
  default=..., description="The end date of the interval."
128
122
  )
129
123
  states: List[HistoryResponseState] = Field(
@@ -147,8 +141,7 @@ class OrchestrationResult(PrefectBaseModel):
147
141
 
148
142
 
149
143
  class WorkerFlowRunResponse(PrefectBaseModel):
150
- class Config:
151
- arbitrary_types_allowed = True
144
+ model_config = ConfigDict(arbitrary_types_allowed=True)
152
145
 
153
146
  work_pool_id: UUID
154
147
  work_queue_id: UUID
@@ -219,18 +212,18 @@ class FlowRunResponse(ObjectBaseModel):
219
212
  run_count: int = Field(
220
213
  default=0, description="The number of times the flow run was executed."
221
214
  )
222
- expected_start_time: Optional[DateTimeTZ] = Field(
215
+ expected_start_time: Optional[DateTime] = Field(
223
216
  default=None,
224
217
  description="The flow run's expected start time.",
225
218
  )
226
- next_scheduled_start_time: Optional[DateTimeTZ] = Field(
219
+ next_scheduled_start_time: Optional[DateTime] = Field(
227
220
  default=None,
228
221
  description="The next time the flow run is scheduled to start.",
229
222
  )
230
- start_time: Optional[DateTimeTZ] = Field(
223
+ start_time: Optional[DateTime] = Field(
231
224
  default=None, description="The actual start time."
232
225
  )
233
- end_time: Optional[DateTimeTZ] = Field(
226
+ end_time: Optional[DateTime] = Field(
234
227
  default=None, description="The actual end time."
235
228
  )
236
229
  total_run_time: datetime.timedelta = Field(
@@ -279,7 +272,7 @@ class FlowRunResponse(ObjectBaseModel):
279
272
  state: Optional[objects.State] = Field(
280
273
  default=None,
281
274
  description="The state of the flow run.",
282
- examples=[objects.State(type=objects.StateType.COMPLETED)],
275
+ examples=["objects.State(type=objects.StateType.COMPLETED)"],
283
276
  )
284
277
  job_variables: Optional[dict] = Field(
285
278
  default=None, description="Job variables for the flow run."
@@ -304,13 +297,13 @@ class FlowRunResponse(ObjectBaseModel):
304
297
  """
305
298
  if isinstance(other, objects.FlowRun):
306
299
  exclude_fields = {"estimated_run_time", "estimated_start_time_delta"}
307
- return self.dict(exclude=exclude_fields) == other.dict(
300
+ return self.model_dump(exclude=exclude_fields) == other.model_dump(
308
301
  exclude=exclude_fields
309
302
  )
310
303
  return super().__eq__(other)
311
304
 
312
305
 
313
- class DeploymentResponse(DeprecatedInfraOverridesField, ObjectBaseModel):
306
+ class DeploymentResponse(ObjectBaseModel):
314
307
  name: str = Field(default=..., description="The name of the deployment.")
315
308
  version: Optional[str] = Field(
316
309
  default=None, description="An optional version for the deployment."
@@ -357,7 +350,7 @@ class DeploymentResponse(DeprecatedInfraOverridesField, ObjectBaseModel):
357
350
  " be scheduled."
358
351
  ),
359
352
  )
360
- last_polled: Optional[DateTimeTZ] = Field(
353
+ last_polled: Optional[DateTime] = Field(
361
354
  default=None,
362
355
  description="The last time the deployment was polled for status updates.",
363
356
  )
@@ -407,7 +400,7 @@ class DeploymentResponse(DeprecatedInfraOverridesField, ObjectBaseModel):
407
400
  ),
408
401
  )
409
402
  enforce_parameter_schema: bool = Field(
410
- default=False,
403
+ default=True,
411
404
  description=(
412
405
  "Whether or not the deployment should enforce the parameter schema."
413
406
  ),
@@ -423,8 +416,7 @@ class DeploymentResponse(DeprecatedInfraOverridesField, ObjectBaseModel):
423
416
 
424
417
 
425
418
  class MinimalConcurrencyLimitResponse(PrefectBaseModel):
426
- class Config:
427
- extra = "ignore" # 2024/4/1
419
+ model_config = ConfigDict(extra="ignore")
428
420
 
429
421
  id: UUID
430
422
  name: str
@@ -3,28 +3,21 @@ Schedule schemas
3
3
  """
4
4
 
5
5
  import datetime
6
- from typing import Optional, Union
6
+ from typing import Annotated, Optional, Union
7
7
 
8
8
  import dateutil
9
9
  import dateutil.rrule
10
10
  import pendulum
11
+ from pydantic import AfterValidator, ConfigDict, Field, field_validator, model_validator
12
+ from pydantic_extra_types.pendulum_dt import DateTime
11
13
 
12
- from prefect._internal.pydantic import HAS_PYDANTIC_V2
13
14
  from prefect._internal.schemas.bases import PrefectBaseModel
14
- from prefect._internal.schemas.fields import DateTimeTZ
15
15
  from prefect._internal.schemas.validators import (
16
16
  default_anchor_date,
17
17
  default_timezone,
18
18
  validate_cron_string,
19
19
  validate_rrule_string,
20
- validate_rrule_timezone,
21
20
  )
22
- from prefect.types import PositiveDuration
23
-
24
- if HAS_PYDANTIC_V2:
25
- from pydantic.v1 import Field, validator
26
- else:
27
- from pydantic import Field, validator
28
21
 
29
22
  MAX_ITERATIONS = 1000
30
23
  # approx. 1 years worth of RDATEs + buffer
@@ -55,26 +48,24 @@ class IntervalSchedule(PrefectBaseModel):
55
48
 
56
49
  Args:
57
50
  interval (datetime.timedelta): an interval to schedule on
58
- anchor_date (DateTimeTZ, optional): an anchor date to schedule increments against;
51
+ anchor_date (DateTime, optional): an anchor date to schedule increments against;
59
52
  if not provided, the current timestamp will be used
60
53
  timezone (str, optional): a valid timezone string
61
54
  """
62
55
 
63
- class Config:
64
- extra = "forbid"
65
- exclude_none = True
56
+ model_config = ConfigDict(extra="forbid", exclude_none=True)
66
57
 
67
- interval: PositiveDuration
68
- anchor_date: Optional[DateTimeTZ] = None
58
+ interval: datetime.timedelta = Field(gt=datetime.timedelta(0))
59
+ anchor_date: Annotated[DateTime, AfterValidator(default_anchor_date)] = Field(
60
+ default_factory=lambda: pendulum.now("UTC"),
61
+ examples=["2020-01-01T00:00:00Z"],
62
+ )
69
63
  timezone: Optional[str] = Field(default=None, examples=["America/New_York"])
70
64
 
71
- @validator("anchor_date", always=True)
72
- def validate_anchor_date(cls, v):
73
- return default_anchor_date(v)
74
-
75
- @validator("timezone", always=True)
76
- def validate_default_timezone(cls, v, values):
77
- return default_timezone(v, values=values)
65
+ @model_validator(mode="after")
66
+ def validate_timezone(self):
67
+ self.timezone = default_timezone(self.timezone, self.model_dump())
68
+ return self
78
69
 
79
70
 
80
71
  class CronSchedule(PrefectBaseModel):
@@ -102,8 +93,7 @@ class CronSchedule(PrefectBaseModel):
102
93
 
103
94
  """
104
95
 
105
- class Config:
106
- extra = "forbid"
96
+ model_config = ConfigDict(extra="forbid")
107
97
 
108
98
  cron: str = Field(default=..., examples=["0 0 * * *"])
109
99
  timezone: Optional[str] = Field(default=None, examples=["America/New_York"])
@@ -114,11 +104,13 @@ class CronSchedule(PrefectBaseModel):
114
104
  ),
115
105
  )
116
106
 
117
- @validator("timezone")
107
+ @field_validator("timezone")
108
+ @classmethod
118
109
  def valid_timezone(cls, v):
119
110
  return default_timezone(v)
120
111
 
121
- @validator("cron")
112
+ @field_validator("cron")
113
+ @classmethod
122
114
  def valid_cron_string(cls, v):
123
115
  return validate_cron_string(v)
124
116
 
@@ -146,13 +138,15 @@ class RRuleSchedule(PrefectBaseModel):
146
138
  timezone (str, optional): a valid timezone string
147
139
  """
148
140
 
149
- class Config:
150
- extra = "forbid"
141
+ model_config = ConfigDict(extra="forbid")
151
142
 
152
143
  rrule: str
153
- timezone: Optional[str] = Field(default=None, examples=["America/New_York"])
144
+ timezone: Optional[str] = Field(
145
+ default="UTC", examples=["America/New_York"], validate_default=True
146
+ )
154
147
 
155
- @validator("rrule")
148
+ @field_validator("rrule")
149
+ @classmethod
156
150
  def validate_rrule_str(cls, v):
157
151
  return validate_rrule_string(v)
158
152
 
@@ -259,14 +253,30 @@ class RRuleSchedule(PrefectBaseModel):
259
253
 
260
254
  return rrule
261
255
 
262
- @validator("timezone", always=True)
256
+ @field_validator("timezone")
263
257
  def valid_timezone(cls, v):
264
- return validate_rrule_timezone(v)
258
+ """
259
+ Validate that the provided timezone is a valid IANA timezone.
260
+
261
+ Unfortunately this list is slightly different from the list of valid
262
+ timezones in pendulum that we use for cron and interval timezone validation.
263
+ """
264
+ from prefect._internal.pytz import HAS_PYTZ
265
+
266
+ if HAS_PYTZ:
267
+ import pytz
268
+ else:
269
+ from prefect._internal import pytz
270
+
271
+ if v and v not in pytz.all_timezones_set:
272
+ raise ValueError(f'Invalid timezone: "{v}"')
273
+ elif v is None:
274
+ return "UTC"
275
+ return v
265
276
 
266
277
 
267
278
  class NoSchedule(PrefectBaseModel):
268
- class Config:
269
- extra = "forbid"
279
+ model_config = ConfigDict(extra="forbid")
270
280
 
271
281
 
272
282
  SCHEDULE_TYPES = Union[IntervalSchedule, CronSchedule, RRuleSchedule, NoSchedule]
@@ -308,6 +318,8 @@ def construct_schedule(
308
318
  if interval:
309
319
  if isinstance(interval, (int, float)):
310
320
  interval = datetime.timedelta(seconds=interval)
321
+ if not anchor_date:
322
+ anchor_date = DateTime.now()
311
323
  schedule = IntervalSchedule(
312
324
  interval=interval, anchor_date=anchor_date, timezone=timezone
313
325
  )
@@ -4,7 +4,7 @@ from typing import Any, Dict, Generic, List, Optional, Type, TypeVar
4
4
  import orjson
5
5
  import websockets
6
6
  import websockets.exceptions
7
- from prefect._vendor.starlette.status import WS_1008_POLICY_VIOLATION
7
+ from starlette.status import WS_1008_POLICY_VIOLATION
8
8
  from typing_extensions import Self
9
9
 
10
10
  from prefect._internal.schemas.bases import IDBaseModel
@@ -48,7 +48,7 @@ class Subscription(Generic[S]):
48
48
 
49
49
  await self._websocket.send(orjson.dumps({"type": "ack"}).decode())
50
50
 
51
- return self.model.parse_raw(message)
51
+ return self.model.model_validate_json(message)
52
52
  except (
53
53
  ConnectionRefusedError,
54
54
  websockets.exceptions.ConnectionClosedError,
@@ -42,12 +42,15 @@ def get_or_create_client(
42
42
  if client is not None:
43
43
  return client, True
44
44
  from prefect._internal.concurrency.event_loop import get_running_loop
45
- from prefect.context import FlowRunContext, TaskRunContext
45
+ from prefect.context import ClientContext, FlowRunContext, TaskRunContext
46
46
 
47
+ client_context = ClientContext.get()
47
48
  flow_run_context = FlowRunContext.get()
48
49
  task_run_context = TaskRunContext.get()
49
50
 
50
- if (
51
+ if client_context and client_context.async_client._loop == get_running_loop():
52
+ return client_context.async_client, True
53
+ elif (
51
54
  flow_run_context
52
55
  and getattr(flow_run_context.client, "_loop", None) == get_running_loop()
53
56
  ):
@@ -11,7 +11,7 @@ except ImportError:
11
11
  # pendulum < 3
12
12
  from pendulum.period import Period as Interval # type: ignore
13
13
 
14
- from prefect import get_client
14
+ from prefect.client.orchestration import get_client
15
15
  from prefect.client.schemas.responses import MinimalConcurrencyLimitResponse
16
16
  from prefect.utilities.timeout import timeout_async
17
17
 
@@ -117,4 +117,6 @@ async def _release_concurrency_slots(
117
117
  def _response_to_minimal_concurrency_limit_response(
118
118
  response: httpx.Response,
119
119
  ) -> List[MinimalConcurrencyLimitResponse]:
120
- return [MinimalConcurrencyLimitResponse.parse_obj(obj_) for obj_ in response.json()]
120
+ return [
121
+ MinimalConcurrencyLimitResponse.model_validate(obj_) for obj_ in response.json()
122
+ ]
@@ -20,7 +20,7 @@ def _emit_concurrency_event(
20
20
  }
21
21
 
22
22
  related = [
23
- RelatedResource.parse_obj(
23
+ RelatedResource.model_validate(
24
24
  {
25
25
  "prefect.resource.id": f"prefect.concurrency-limit.{limit.id}",
26
26
  "prefect.resource.role": "concurrency-limit",
@@ -2,23 +2,26 @@ import asyncio
2
2
  import concurrent.futures
3
3
  from contextlib import asynccontextmanager
4
4
  from typing import (
5
+ TYPE_CHECKING,
5
6
  FrozenSet,
6
7
  Tuple,
7
8
  )
8
9
 
9
10
  import httpx
10
- from prefect._vendor.starlette import status
11
+ from starlette import status
11
12
 
12
- from prefect import get_client
13
13
  from prefect._internal.concurrency import logger
14
14
  from prefect._internal.concurrency.services import QueueService
15
- from prefect.client.orchestration import PrefectClient
15
+ from prefect.client.orchestration import get_client
16
+
17
+ if TYPE_CHECKING:
18
+ from prefect.client.orchestration import PrefectClient
16
19
 
17
20
 
18
21
  class ConcurrencySlotAcquisitionService(QueueService):
19
22
  def __init__(self, concurrency_limit_names: FrozenSet[str]):
20
23
  super().__init__(concurrency_limit_names)
21
- self._client: PrefectClient
24
+ self._client: "PrefectClient"
22
25
  self.concurrency_limit_names = sorted(list(concurrency_limit_names))
23
26
 
24
27
  @asynccontextmanager