prefect-client 3.3.0__py3-none-any.whl → 3.3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
prefect/_build_info.py CHANGED
@@ -1,5 +1,5 @@
1
1
  # Generated by versioningit
2
- __version__ = "3.3.0"
3
- __build_date__ = "2025-03-31 15:28:57.721236+00:00"
4
- __git_commit__ = "ef73b2c49e26b05c55b52022048da00f0845dcf1"
2
+ __version__ = "3.3.2"
3
+ __build_date__ = "2025-04-03 21:24:32.871912+00:00"
4
+ __git_commit__ = "e49e31850463a0c0db93b4798856247a6d1669a6"
5
5
  __dirty__ = False
@@ -10,12 +10,15 @@ will be calculated 6 months later. Start and end dates are always in the format
10
10
  e.g. Jan 2023.
11
11
  """
12
12
 
13
+ from __future__ import annotations
14
+
13
15
  import datetime
14
16
  import functools
15
17
  import sys
16
18
  import warnings
17
19
  from typing import TYPE_CHECKING, Any, Callable, Optional, Union
18
20
 
21
+ import dateparser
19
22
  from pydantic import BaseModel
20
23
  from typing_extensions import ParamSpec, TypeAlias, TypeVar
21
24
 
@@ -32,6 +35,9 @@ R = TypeVar("R", infer_variance=True)
32
35
  M = TypeVar("M", bound=BaseModel)
33
36
  T = TypeVar("T")
34
37
 
38
+ # Note: A datetime is strongly preferred over a string, but a string is acceptable for
39
+ # backwards compatibility until support is dropped from dateparser in Python 3.15.
40
+ _AcceptableDate: TypeAlias = Optional[Union[datetime.datetime, str]]
35
41
 
36
42
  DEPRECATED_WARNING = (
37
43
  "{name} has been deprecated{when}. It will not be available in new releases after {end_date}."
@@ -51,18 +57,25 @@ class PrefectDeprecationWarning(DeprecationWarning):
51
57
  """
52
58
 
53
59
 
60
+ def _coerce_datetime(
61
+ dt: Optional[_AcceptableDate],
62
+ ) -> Optional[datetime.datetime]:
63
+ if dt is None or isinstance(dt, datetime.datetime):
64
+ return dt
65
+ with warnings.catch_warnings():
66
+ warnings.filterwarnings("ignore", category=DeprecationWarning)
67
+ return dateparser.parse(dt)
68
+
69
+
54
70
  def generate_deprecation_message(
55
71
  name: str,
56
- start_date: Optional[datetime.datetime] = None,
57
- end_date: Optional[datetime.datetime] = None,
72
+ start_date: Optional[_AcceptableDate] = None,
73
+ end_date: Optional[_AcceptableDate] = None,
58
74
  help: str = "",
59
75
  when: str = "",
60
76
  ) -> str:
61
- if start_date is not None and not isinstance(start_date, datetime.datetime):
62
- raise ValueError("Must provide start_date as a datetime")
63
-
64
- if end_date is not None and not isinstance(end_date, datetime.datetime):
65
- raise ValueError("Must provide end_date as a datetime")
77
+ start_date = _coerce_datetime(start_date)
78
+ end_date = _coerce_datetime(end_date)
66
79
 
67
80
  if start_date is None and end_date is None:
68
81
  raise ValueError(
@@ -87,8 +100,8 @@ def generate_deprecation_message(
87
100
 
88
101
  def deprecated_callable(
89
102
  *,
90
- start_date: Optional[datetime.datetime] = None,
91
- end_date: Optional[datetime.datetime] = None,
103
+ start_date: Optional[_AcceptableDate] = None,
104
+ end_date: Optional[_AcceptableDate] = None,
92
105
  stacklevel: int = 2,
93
106
  help: str = "",
94
107
  ) -> Callable[[Callable[P, R]], Callable[P, R]]:
@@ -112,8 +125,8 @@ def deprecated_callable(
112
125
 
113
126
  def deprecated_class(
114
127
  *,
115
- start_date: Optional[datetime.datetime] = None,
116
- end_date: Optional[datetime.datetime] = None,
128
+ start_date: Optional[_AcceptableDate] = None,
129
+ end_date: Optional[_AcceptableDate] = None,
117
130
  stacklevel: int = 2,
118
131
  help: str = "",
119
132
  ) -> Callable[[type[T]], type[T]]:
@@ -141,8 +154,8 @@ def deprecated_class(
141
154
  def deprecated_parameter(
142
155
  name: str,
143
156
  *,
144
- start_date: Optional[datetime.datetime] = None,
145
- end_date: Optional[datetime.datetime] = None,
157
+ start_date: Optional[_AcceptableDate] = None,
158
+ end_date: Optional[_AcceptableDate] = None,
146
159
  stacklevel: int = 2,
147
160
  help: str = "",
148
161
  when: Optional[Callable[[Any], bool]] = None,
@@ -197,8 +210,8 @@ JsonDict: TypeAlias = dict[str, JsonValue]
197
210
  def deprecated_field(
198
211
  name: str,
199
212
  *,
200
- start_date: Optional[datetime.datetime] = None,
201
- end_date: Optional[datetime.datetime] = None,
213
+ start_date: Optional[_AcceptableDate] = None,
214
+ end_date: Optional[_AcceptableDate] = None,
202
215
  when_message: str = "",
203
216
  help: str = "",
204
217
  when: Optional[Callable[[Any], bool]] = None,
@@ -242,7 +255,7 @@ def deprecated_field(
242
255
 
243
256
  cls_init(__pydantic_self__, **data)
244
257
 
245
- field = __pydantic_self__.model_fields.get(name)
258
+ field = __pydantic_self__.__class__.model_fields.get(name)
246
259
  if field is not None:
247
260
  json_schema_extra = field.json_schema_extra or {}
248
261
 
@@ -279,9 +292,7 @@ def inject_renamed_module_alias_finder():
279
292
  sys.meta_path.insert(0, AliasedModuleFinder(DEPRECATED_MODULE_ALIASES))
280
293
 
281
294
 
282
- def register_renamed_module(
283
- old_name: str, new_name: str, start_date: datetime.datetime
284
- ):
295
+ def register_renamed_module(old_name: str, new_name: str, start_date: _AcceptableDate):
285
296
  """
286
297
  Register a renamed module.
287
298
 
@@ -374,8 +374,11 @@ class Call(Generic[T]):
374
374
 
375
375
  except CancelledError:
376
376
  # Report cancellation
377
- if TYPE_CHECKING:
378
- assert cancel_scope is not None
377
+ # in rare cases, enforce_sync_deadline raises CancelledError
378
+ # prior to yielding
379
+ if cancel_scope is None:
380
+ self.future.cancel()
381
+ return None
379
382
  if cancel_scope.timedout():
380
383
  setattr(self.future, "_timed_out", True)
381
384
  self.future.cancel()
@@ -106,4 +106,5 @@ def create_v2_schema(
106
106
  # ensure backwards compatibility by copying $defs into definitions
107
107
  if "$defs" in schema:
108
108
  schema["definitions"] = schema["$defs"]
109
+
109
110
  return schema
@@ -64,7 +64,7 @@ class PrefectBaseModel(BaseModel):
64
64
 
65
65
  def __rich_repr__(self) -> RichReprResult:
66
66
  # Display all of the fields in the model if they differ from the default value
67
- for name, field in self.model_fields.items():
67
+ for name, field in type(self).model_fields.items():
68
68
  value = getattr(self, name)
69
69
 
70
70
  # Simplify the display of some common fields
@@ -90,7 +90,9 @@ class PrefectBaseModel(BaseModel):
90
90
  """
91
91
  return self.model_copy(
92
92
  update={
93
- field: self.model_fields[field].get_default(call_default_factory=True)
93
+ field: type(self)
94
+ .model_fields[field]
95
+ .get_default(call_default_factory=True)
94
96
  for field in self._reset_fields
95
97
  }
96
98
  )
prefect/blocks/core.py CHANGED
@@ -18,6 +18,7 @@ from typing import (
18
18
  Optional,
19
19
  TypeVar,
20
20
  Union,
21
+ cast,
21
22
  get_origin,
22
23
  )
23
24
  from uuid import UUID, uuid4
@@ -169,14 +170,13 @@ def _collect_secret_fields(
169
170
  return
170
171
 
171
172
  if type_ in (SecretStr, SecretBytes) or (
172
- isinstance(type_, type)
173
+ isinstance(type_, type) # type: ignore[unnecessaryIsInstance]
173
174
  and getattr(type_, "__module__", None) == "pydantic.types"
174
175
  and getattr(type_, "__name__", None) == "Secret"
175
176
  ):
176
177
  secrets.append(name)
177
178
  elif type_ == SecretDict:
178
- # Append .* to field name to signify that all values under this
179
- # field are secret and should be obfuscated.
179
+ # Append .* to field name to signify that all values under a given key are secret and should be obfuscated.
180
180
  secrets.append(f"{name}.*")
181
181
  elif Block.is_block_class(type_):
182
182
  secrets.extend(
@@ -371,7 +371,7 @@ class Block(BaseModel, ABC):
371
371
  visit_fn=partial(handle_secret_render, context=ctx),
372
372
  return_data=True,
373
373
  )
374
- for field_name in self.model_fields
374
+ for field_name in type(self).model_fields
375
375
  }
376
376
  )
377
377
  if extra_fields := {
@@ -1501,14 +1501,7 @@ class Block(BaseModel, ABC):
1501
1501
  if "$defs" in schema:
1502
1502
  schema["definitions"] = schema.pop("$defs")
1503
1503
 
1504
- # we aren't expecting these additional fields in the schema
1505
- if "additionalProperties" in schema:
1506
- schema.pop("additionalProperties")
1507
-
1508
- for _, definition in schema.get("definitions", {}).items():
1509
- if "additionalProperties" in definition:
1510
- definition.pop("additionalProperties")
1511
-
1504
+ schema = remove_nested_keys(["additionalProperties"], schema)
1512
1505
  return schema
1513
1506
 
1514
1507
  @classmethod
@@ -1521,6 +1514,7 @@ class Block(BaseModel, ABC):
1521
1514
  context: dict[str, Any] | None = None,
1522
1515
  ) -> Self:
1523
1516
  if isinstance(obj, dict):
1517
+ obj = cast(dict[str, Any], obj)
1524
1518
  extra_serializer_fields = {
1525
1519
  "_block_document_id",
1526
1520
  "_block_document_name",
@@ -1530,7 +1524,10 @@ class Block(BaseModel, ABC):
1530
1524
  obj.pop(field, None)
1531
1525
 
1532
1526
  return super().model_validate(
1533
- obj, strict=strict, from_attributes=from_attributes, context=context
1527
+ obj,
1528
+ strict=strict,
1529
+ from_attributes=from_attributes,
1530
+ context=context,
1534
1531
  )
1535
1532
 
1536
1533
  def model_dump(
prefect/client/base.py CHANGED
@@ -222,6 +222,10 @@ class PrefectHttpxAsyncClient(httpx.AsyncClient):
222
222
  if the request either raises an exception listed in `retry_exceptions` or
223
223
  receives a response with a status code listed in `retry_codes`.
224
224
 
225
+ Retries are not counted against the limit if the response headers contains
226
+ a reserved value, indicating that the server is undergoing maintenance. These
227
+ requests will retry indefinitely until the header is no longer returned.
228
+
225
229
  Retries will be delayed based on either the retry header (preferred) or
226
230
  exponential backoff if a retry header is not provided.
227
231
  """
@@ -239,18 +243,21 @@ class PrefectHttpxAsyncClient(httpx.AsyncClient):
239
243
  await self._add_csrf_headers(request=request)
240
244
 
241
245
  while try_count <= PREFECT_CLIENT_MAX_RETRIES.value():
242
- try_count += 1
243
246
  retry_seconds = None
244
247
  exc_info = None
245
248
 
246
249
  try:
247
250
  response = await send(request, *send_args, **send_kwargs)
248
251
  except retry_exceptions: # type: ignore
252
+ try_count += 1
249
253
  if try_count > PREFECT_CLIENT_MAX_RETRIES.value():
250
254
  raise
251
255
  # Otherwise, we will ignore this error but capture the info for logging
252
256
  exc_info = sys.exc_info()
253
257
  else:
258
+ if response.headers.get("Prefect-Maintenance") != "true":
259
+ try_count += 1
260
+
254
261
  # We got a response; check if it's a CSRF error, otherwise
255
262
  # return immediately if it is not retryable
256
263
  if (
@@ -441,6 +448,10 @@ class PrefectHttpxSyncClient(httpx.Client):
441
448
  if the request either raises an exception listed in `retry_exceptions` or
442
449
  receives a response with a status code listed in `retry_codes`.
443
450
 
451
+ Retries are not counted against the limit if the response headers contains
452
+ a reserved value, indicating that the server is undergoing maintenance. These
453
+ requests will retry indefinitely until the header is no longer returned.
454
+
444
455
  Retries will be delayed based on either the retry header (preferred) or
445
456
  exponential backoff if a retry header is not provided.
446
457
  """
@@ -458,18 +469,21 @@ class PrefectHttpxSyncClient(httpx.Client):
458
469
  self._add_csrf_headers(request=request)
459
470
 
460
471
  while try_count <= PREFECT_CLIENT_MAX_RETRIES.value():
461
- try_count += 1
462
472
  retry_seconds = None
463
473
  exc_info = None
464
474
 
465
475
  try:
466
476
  response = send(request, *send_args, **send_kwargs)
467
477
  except retry_exceptions: # type: ignore
478
+ try_count += 1
468
479
  if try_count > PREFECT_CLIENT_MAX_RETRIES.value():
469
480
  raise
470
481
  # Otherwise, we will ignore this error but capture the info for logging
471
482
  exc_info = sys.exc_info()
472
483
  else:
484
+ if response.headers.get("Prefect-Maintenance") != "true":
485
+ try_count += 1
486
+
473
487
  # We got a response; check if it's a CSRF error, otherwise
474
488
  # return immediately if it is not retryable
475
489
  if (
@@ -1,3 +1,4 @@
1
+ from __future__ import annotations
1
2
  import asyncio
2
3
  import base64
3
4
  import datetime
@@ -1164,6 +1165,10 @@ class PrefectClient(
1164
1165
  def client_version(self) -> str:
1165
1166
  return prefect.__version__
1166
1167
 
1168
+ @property
1169
+ def loop(self) -> asyncio.AbstractEventLoop | None:
1170
+ return self._loop
1171
+
1167
1172
  async def raise_for_api_version_mismatch(self) -> None:
1168
1173
  # Cloud is always compatible as a server
1169
1174
  if self.server_type == ServerType.CLOUD:
@@ -29,6 +29,7 @@ if TYPE_CHECKING:
29
29
  from prefect.client.schemas.objects import (
30
30
  ConcurrencyOptions,
31
31
  DeploymentSchedule,
32
+ VersionInfo,
32
33
  )
33
34
  from prefect.client.schemas.responses import (
34
35
  DeploymentResponse,
@@ -48,6 +49,7 @@ class DeploymentClient(BaseClient):
48
49
  flow_id: "UUID",
49
50
  name: str,
50
51
  version: str | None = None,
52
+ version_info: "VersionInfo | None" = None,
51
53
  schedules: list["DeploymentScheduleCreate"] | None = None,
52
54
  concurrency_limit: int | None = None,
53
55
  concurrency_options: "ConcurrencyOptions | None" = None,
@@ -65,6 +67,9 @@ class DeploymentClient(BaseClient):
65
67
  pull_steps: list[dict[str, Any]] | None = None,
66
68
  enforce_parameter_schema: bool | None = None,
67
69
  job_variables: dict[str, Any] | None = None,
70
+ branch: str | None = None,
71
+ base: UUID | None = None,
72
+ root: UUID | None = None,
68
73
  ) -> "UUID":
69
74
  """
70
75
  Create a deployment.
@@ -99,6 +104,7 @@ class DeploymentClient(BaseClient):
99
104
  flow_id=flow_id,
100
105
  name=name,
101
106
  version=version,
107
+ version_info=version_info,
102
108
  parameters=dict(parameters or {}),
103
109
  tags=list(tags or []),
104
110
  work_queue_name=work_queue_name,
@@ -115,6 +121,9 @@ class DeploymentClient(BaseClient):
115
121
  concurrency_options=concurrency_options,
116
122
  pull_steps=pull_steps,
117
123
  enforce_parameter_schema=enforce_parameter_schema,
124
+ branch=branch,
125
+ base=base,
126
+ root=root,
118
127
  )
119
128
 
120
129
  if work_pool_name is not None:
@@ -123,20 +132,29 @@ class DeploymentClient(BaseClient):
123
132
  # Exclude newer fields that are not set to avoid compatibility issues
124
133
  exclude = {
125
134
  field
126
- for field in ["work_pool_name", "work_queue_name"]
135
+ for field in [
136
+ "work_pool_name",
137
+ "work_queue_name",
138
+ ]
127
139
  if field not in deployment_create.model_fields_set
128
140
  }
129
141
 
130
- if deployment_create.paused is None:
131
- exclude.add("paused")
132
-
133
- if deployment_create.pull_steps is None:
134
- exclude.add("pull_steps")
142
+ exclude_if_none = [
143
+ "paused",
144
+ "pull_steps",
145
+ "enforce_parameter_schema",
146
+ "version_info",
147
+ "branch",
148
+ "base",
149
+ "root",
150
+ ]
135
151
 
136
- if deployment_create.enforce_parameter_schema is None:
137
- exclude.add("enforce_parameter_schema")
152
+ for field in exclude_if_none:
153
+ if getattr(deployment_create, field) is None:
154
+ exclude.add(field)
138
155
 
139
156
  json = deployment_create.model_dump(mode="json", exclude=exclude)
157
+
140
158
  response = self.request(
141
159
  "POST",
142
160
  "/deployments/",
@@ -593,6 +611,7 @@ class DeploymentAsyncClient(BaseAsyncClient):
593
611
  flow_id: "UUID",
594
612
  name: str,
595
613
  version: str | None = None,
614
+ version_info: "VersionInfo | None" = None,
596
615
  schedules: list["DeploymentScheduleCreate"] | None = None,
597
616
  concurrency_limit: int | None = None,
598
617
  concurrency_options: "ConcurrencyOptions | None" = None,
@@ -610,6 +629,9 @@ class DeploymentAsyncClient(BaseAsyncClient):
610
629
  pull_steps: list[dict[str, Any]] | None = None,
611
630
  enforce_parameter_schema: bool | None = None,
612
631
  job_variables: dict[str, Any] | None = None,
632
+ branch: str | None = None,
633
+ base: UUID | None = None,
634
+ root: UUID | None = None,
613
635
  ) -> "UUID":
614
636
  """
615
637
  Create a deployment.
@@ -644,6 +666,7 @@ class DeploymentAsyncClient(BaseAsyncClient):
644
666
  flow_id=flow_id,
645
667
  name=name,
646
668
  version=version,
669
+ version_info=version_info,
647
670
  parameters=dict(parameters or {}),
648
671
  tags=list(tags or []),
649
672
  work_queue_name=work_queue_name,
@@ -660,6 +683,9 @@ class DeploymentAsyncClient(BaseAsyncClient):
660
683
  concurrency_options=concurrency_options,
661
684
  pull_steps=pull_steps,
662
685
  enforce_parameter_schema=enforce_parameter_schema,
686
+ branch=branch,
687
+ base=base,
688
+ root=root,
663
689
  )
664
690
 
665
691
  if work_pool_name is not None:
@@ -668,20 +694,29 @@ class DeploymentAsyncClient(BaseAsyncClient):
668
694
  # Exclude newer fields that are not set to avoid compatibility issues
669
695
  exclude = {
670
696
  field
671
- for field in ["work_pool_name", "work_queue_name"]
697
+ for field in [
698
+ "work_pool_name",
699
+ "work_queue_name",
700
+ ]
672
701
  if field not in deployment_create.model_fields_set
673
702
  }
674
703
 
675
- if deployment_create.paused is None:
676
- exclude.add("paused")
677
-
678
- if deployment_create.pull_steps is None:
679
- exclude.add("pull_steps")
704
+ exclude_if_none = [
705
+ "paused",
706
+ "pull_steps",
707
+ "enforce_parameter_schema",
708
+ "version_info",
709
+ "branch",
710
+ "base",
711
+ "root",
712
+ ]
680
713
 
681
- if deployment_create.enforce_parameter_schema is None:
682
- exclude.add("enforce_parameter_schema")
714
+ for field in exclude_if_none:
715
+ if getattr(deployment_create, field) is None:
716
+ exclude.add(field)
683
717
 
684
718
  json = deployment_create.model_dump(mode="json", exclude=exclude)
719
+
685
720
  response = await self.request(
686
721
  "POST",
687
722
  "/deployments/",
@@ -253,13 +253,29 @@ class DeploymentCreate(ActionBaseModel):
253
253
  infrastructure_document_id: Optional[UUID] = Field(default=None)
254
254
  description: Optional[str] = Field(default=None)
255
255
  path: Optional[str] = Field(default=None)
256
- version: Optional[str] = Field(default=None)
257
256
  entrypoint: Optional[str] = Field(default=None)
258
257
  job_variables: dict[str, Any] = Field(
259
258
  default_factory=dict,
260
259
  description="Overrides to apply to flow run infrastructure at runtime.",
261
260
  )
262
261
 
262
+ # Versionining
263
+ version: Optional[str] = Field(default=None)
264
+ version_info: Optional[objects.VersionInfo] = Field(
265
+ default=None, description="Version information for the deployment."
266
+ )
267
+
268
+ # Branching
269
+ branch: Optional[str] = Field(
270
+ default=None, description="The branch of the deployment."
271
+ )
272
+ base: Optional[UUID] = Field(
273
+ default=None, description="The base deployment of the deployment."
274
+ )
275
+ root: Optional[UUID] = Field(
276
+ default=None, description="The root deployment of the deployment."
277
+ )
278
+
263
279
  def check_valid_configuration(self, base_job_template: dict[str, Any]) -> None:
264
280
  """Check that the combination of base_job_template defaults
265
281
  and job_variables conforms to the specified schema.
@@ -289,6 +305,9 @@ class DeploymentUpdate(ActionBaseModel):
289
305
  return remove_old_deployment_fields(values)
290
306
 
291
307
  version: Optional[str] = Field(default=None)
308
+ version_info: Optional[objects.VersionInfo] = Field(
309
+ default=None, description="Version information for the deployment."
310
+ )
292
311
  description: Optional[str] = Field(default=None)
293
312
  parameters: Optional[dict[str, Any]] = Field(
294
313
  default=None,
@@ -414,7 +414,7 @@ class State(ObjectBaseModel, Generic[R]):
414
414
  database again. The 'timestamp' is reset using the default factory.
415
415
  """
416
416
  update = {
417
- "timestamp": self.model_fields["timestamp"].get_default(),
417
+ "timestamp": type(self).model_fields["timestamp"].get_default(),
418
418
  **(update or {}),
419
419
  }
420
420
  return super().model_copy(update=update, deep=deep)
@@ -1102,6 +1102,11 @@ class DeploymentSchedule(ObjectBaseModel):
1102
1102
  )
1103
1103
 
1104
1104
 
1105
+ class VersionInfo(PrefectBaseModel, extra="allow"):
1106
+ type: str = Field(default=..., description="The type of version info.")
1107
+ version: str = Field(default=..., description="The version of the deployment.")
1108
+
1109
+
1105
1110
  class Deployment(ObjectBaseModel):
1106
1111
  """An ORM representation of deployment data."""
1107
1112
 
@@ -1109,6 +1114,12 @@ class Deployment(ObjectBaseModel):
1109
1114
  version: Optional[str] = Field(
1110
1115
  default=None, description="An optional version for the deployment."
1111
1116
  )
1117
+ version_id: Optional[UUID] = Field(
1118
+ default=None, description="The ID of the current version of the deployment."
1119
+ )
1120
+ version_info: Optional[VersionInfo] = Field(
1121
+ default=None, description="A description of this version of the deployment."
1122
+ )
1112
1123
  description: Optional[str] = Field(
1113
1124
  default=None, description="A description for the deployment."
1114
1125
  )
@@ -1,5 +1,5 @@
1
1
  import datetime
2
- from typing import Any, ClassVar, Generic, Optional, TypeVar, Union
2
+ from typing import TYPE_CHECKING, Any, ClassVar, Generic, Optional, TypeVar, Union
3
3
  from uuid import UUID
4
4
 
5
5
  from pydantic import ConfigDict, Field
@@ -12,6 +12,9 @@ from prefect.types import DateTime, KeyValueLabelsField
12
12
  from prefect.utilities.collections import AutoEnum
13
13
  from prefect.utilities.names import generate_slug
14
14
 
15
+ if TYPE_CHECKING:
16
+ from prefect.events.schemas.events import RelatedResource
17
+
15
18
  T = TypeVar("T")
16
19
 
17
20
 
@@ -308,6 +311,12 @@ class DeploymentResponse(ObjectBaseModel):
308
311
  version: Optional[str] = Field(
309
312
  default=None, description="An optional version for the deployment."
310
313
  )
314
+ version_id: Optional[UUID] = Field(
315
+ default=None, description="The ID of the current version of the deployment."
316
+ )
317
+ version_info: Optional[objects.VersionInfo] = Field(
318
+ default=None, description="A description of this version of the deployment."
319
+ )
311
320
  description: Optional[str] = Field(
312
321
  default=None, description="A description for the deployment."
313
322
  )
@@ -420,6 +429,22 @@ class DeploymentResponse(ObjectBaseModel):
420
429
  description="Current status of the deployment.",
421
430
  )
422
431
 
432
+ def as_related_resource(self, role: str = "deployment") -> "RelatedResource":
433
+ from prefect.events.schemas.events import RelatedResource
434
+
435
+ labels = {
436
+ "prefect.resource.id": f"prefect.deployment.{self.id}",
437
+ "prefect.resource.role": role,
438
+ "prefect.resource.name": self.name,
439
+ }
440
+
441
+ if self.version_id and self.version_info:
442
+ labels["prefect.deployment.version-id"] = str(self.version_id)
443
+ labels["prefect.deployment.version-type"] = self.version_info.type
444
+ labels["prefect.deployment.version"] = self.version_info.version
445
+
446
+ return RelatedResource(labels)
447
+
423
448
 
424
449
  class MinimalConcurrencyLimitResponse(PrefectBaseModel):
425
450
  model_config: ClassVar[ConfigDict] = ConfigDict(extra="ignore")
prefect/context.py CHANGED
@@ -6,6 +6,7 @@ These contexts should never be directly mutated by the user.
6
6
  For more user-accessible information about the current run, see [`prefect.runtime`](../runtime/flow_run).
7
7
  """
8
8
 
9
+ import asyncio
9
10
  import os
10
11
  import sys
11
12
  import warnings
@@ -294,7 +295,7 @@ class AsyncClientContext(ContextModel):
294
295
  @asynccontextmanager
295
296
  async def get_or_create(cls) -> AsyncGenerator[Self, None]:
296
297
  ctx = cls.get()
297
- if ctx:
298
+ if ctx and asyncio.get_running_loop() is ctx.client.loop:
298
299
  yield ctx
299
300
  else:
300
301
  async with cls() as ctx:
prefect/events/filters.py CHANGED
@@ -45,7 +45,7 @@ class EventDataFilter(PrefectBaseModel, extra="forbid"): # type: ignore[call-ar
45
45
  def get_filters(self) -> list["EventDataFilter"]:
46
46
  filters: list["EventDataFilter"] = [
47
47
  filter
48
- for filter in [getattr(self, name) for name in self.model_fields]
48
+ for filter in [getattr(self, name) for name in type(self).model_fields]
49
49
  if isinstance(filter, EventDataFilter)
50
50
  ]
51
51
  return filters
prefect/events/related.py CHANGED
@@ -33,7 +33,7 @@ RESOURCE_CACHE: RelatedResourceCache = {}
33
33
 
34
34
  def tags_as_related_resources(tags: Iterable[str]) -> List[RelatedResource]:
35
35
  return [
36
- RelatedResource.model_validate(
36
+ RelatedResource(
37
37
  {
38
38
  "prefect.resource.id": f"prefect.tag.{tag}",
39
39
  "prefect.resource.role": "tag",
@@ -44,9 +44,11 @@ def tags_as_related_resources(tags: Iterable[str]) -> List[RelatedResource]:
44
44
 
45
45
 
46
46
  def object_as_related_resource(kind: str, role: str, object: Any) -> RelatedResource:
47
- resource_id = f"prefect.{kind}.{object.id}"
47
+ if as_related_resource := getattr(object, "as_related_resource", None):
48
+ return as_related_resource(role=role)
48
49
 
49
- return RelatedResource.model_validate(
50
+ resource_id = f"prefect.{kind}.{object.id}"
51
+ return RelatedResource(
50
52
  {
51
53
  "prefect.resource.id": resource_id,
52
54
  "prefect.resource.role": role,
prefect/flows.py CHANGED
@@ -272,10 +272,11 @@ class Flow(Generic[P, R]):
272
272
 
273
273
  if isinstance(fn, classmethod):
274
274
  fn = cast(Callable[P, R], fn.__func__)
275
+ self._isclassmethod = True
275
276
 
276
277
  if isinstance(fn, staticmethod):
277
278
  fn = cast(Callable[P, R], fn.__func__)
278
- setattr(fn, "__prefect_static__", True)
279
+ self._isstaticmethod = True
279
280
 
280
281
  if not callable(fn):
281
282
  raise TypeError("'fn' must be callable")
@@ -405,11 +406,11 @@ class Flow(Generic[P, R]):
405
406
 
406
407
  @property
407
408
  def isclassmethod(self) -> bool:
408
- return hasattr(self.fn, "__prefect_cls__")
409
+ return getattr(self, "_isclassmethod", False)
409
410
 
410
411
  @property
411
412
  def isstaticmethod(self) -> bool:
412
- return getattr(self.fn, "__prefect_static__", False)
413
+ return getattr(self, "_isstaticmethod", False)
413
414
 
414
415
  def __get__(self, instance: Any, owner: Any) -> "Flow[P, R]":
415
416
  """
@@ -417,21 +418,20 @@ class Flow(Generic[P, R]):
417
418
  When an instance method is loaded, this method is called with the "self" instance as
418
419
  an argument. We return a copy of the flow with that instance bound to the flow's function.
419
420
  """
420
- if self.isstaticmethod:
421
- return self
422
-
423
421
  # wrapped function is a classmethod
424
- if instance is None:
425
- bound_flow = copy(self)
426
- setattr(bound_flow.fn, "__prefect_cls__", owner)
427
- return bound_flow
422
+ if self.isclassmethod:
423
+ bound_task = copy(self)
424
+ setattr(bound_task.fn, "__prefect_cls__", owner)
425
+ return bound_task
428
426
 
429
- # if the flow is being accessed on an instance, bind the instance to the __prefect_self__ attribute
430
- # of the flow's function. This will allow it to be automatically added to the flow's parameters
431
- else:
432
- bound_flow = copy(self)
433
- setattr(bound_flow.fn, "__prefect_self__", instance)
434
- return bound_flow
427
+ # if the task is being accessed on an instance, bind the instance to the __prefect_self__ attribute
428
+ # of the task's function. This will allow it to be automatically added to the task's parameters
429
+ if instance:
430
+ bound_task = copy(self)
431
+ bound_task.fn.__prefect_self__ = instance # type: ignore[attr-defined]
432
+ return bound_task
433
+
434
+ return self
435
435
 
436
436
  def with_options(
437
437
  self,
@@ -636,7 +636,8 @@ class Flow(Generic[P, R]):
636
636
  cast_parameters = {
637
637
  k: v
638
638
  for k, v in dict(iter(model)).items()
639
- if k in model.model_fields_set or model.model_fields[k].default_factory
639
+ if k in model.model_fields_set
640
+ or type(model).model_fields[k].default_factory
640
641
  }
641
642
  return cast_parameters
642
643
 
prefect/runner/runner.py CHANGED
@@ -1158,15 +1158,7 @@ class Runner:
1158
1158
 
1159
1159
  flow, deployment = await self._get_flow_and_deployment(flow_run)
1160
1160
  if deployment:
1161
- related.append(
1162
- RelatedResource(
1163
- {
1164
- "prefect.resource.id": f"prefect.deployment.{deployment.id}",
1165
- "prefect.resource.role": "deployment",
1166
- "prefect.resource.name": deployment.name,
1167
- }
1168
- )
1169
- )
1161
+ related.append(deployment.as_related_resource())
1170
1162
  tags.extend(deployment.tags)
1171
1163
  if flow:
1172
1164
  related.append(
@@ -1211,15 +1203,7 @@ class Runner:
1211
1203
  related: list[RelatedResource] = []
1212
1204
  tags: list[str] = []
1213
1205
  if deployment:
1214
- related.append(
1215
- RelatedResource(
1216
- {
1217
- "prefect.resource.id": f"prefect.deployment.{deployment.id}",
1218
- "prefect.resource.role": "deployment",
1219
- "prefect.resource.name": deployment.name,
1220
- }
1221
- )
1222
- )
1206
+ related.append(deployment.as_related_resource())
1223
1207
  tags.extend(deployment.tags)
1224
1208
  if flow:
1225
1209
  related.append(
prefect/schedules.py CHANGED
@@ -47,7 +47,7 @@ class Schedule:
47
47
  anchor_date: datetime.datetime = dataclasses.field(
48
48
  default_factory=partial(datetime.datetime.now, tz=datetime.timezone.utc)
49
49
  )
50
- day_or: bool = False
50
+ day_or: bool = True
51
51
  active: bool = True
52
52
  parameters: dict[str, Any] = dataclasses.field(default_factory=dict)
53
53
  slug: str | None = None
@@ -73,7 +73,7 @@ def Cron(
73
73
  cron: str,
74
74
  /,
75
75
  timezone: str | None = None,
76
- day_or: bool = False,
76
+ day_or: bool = True,
77
77
  active: bool = True,
78
78
  parameters: dict[str, Any] | None = None,
79
79
  slug: str | None = None,
@@ -181,12 +181,12 @@ async def update_flow_run(
181
181
 
182
182
  @router.post("/count")
183
183
  async def count_flow_runs(
184
- flows: schemas.filters.FlowFilter = None,
185
- flow_runs: schemas.filters.FlowRunFilter = None,
186
- task_runs: schemas.filters.TaskRunFilter = None,
187
- deployments: schemas.filters.DeploymentFilter = None,
188
- work_pools: schemas.filters.WorkPoolFilter = None,
189
- work_pool_queues: schemas.filters.WorkQueueFilter = None,
184
+ flows: Optional[schemas.filters.FlowFilter] = None,
185
+ flow_runs: Optional[schemas.filters.FlowRunFilter] = None,
186
+ task_runs: Optional[schemas.filters.TaskRunFilter] = None,
187
+ deployments: Optional[schemas.filters.DeploymentFilter] = None,
188
+ work_pools: Optional[schemas.filters.WorkPoolFilter] = None,
189
+ work_pool_queues: Optional[schemas.filters.WorkQueueFilter] = None,
190
190
  db: PrefectDBInterface = Depends(provide_database_interface),
191
191
  ) -> int:
192
192
  """
@@ -279,12 +279,12 @@ async def flow_run_history(
279
279
  json_schema_extra={"format": "time-delta"},
280
280
  alias="history_interval_seconds",
281
281
  ),
282
- flows: schemas.filters.FlowFilter = None,
283
- flow_runs: schemas.filters.FlowRunFilter = None,
284
- task_runs: schemas.filters.TaskRunFilter = None,
285
- deployments: schemas.filters.DeploymentFilter = None,
286
- work_pools: schemas.filters.WorkPoolFilter = None,
287
- work_queues: schemas.filters.WorkQueueFilter = None,
282
+ flows: Optional[schemas.filters.FlowFilter] = None,
283
+ flow_runs: Optional[schemas.filters.FlowRunFilter] = None,
284
+ task_runs: Optional[schemas.filters.TaskRunFilter] = None,
285
+ deployments: Optional[schemas.filters.DeploymentFilter] = None,
286
+ work_pools: Optional[schemas.filters.WorkPoolFilter] = None,
287
+ work_queues: Optional[schemas.filters.WorkQueueFilter] = None,
288
288
  db: PrefectDBInterface = Depends(provide_database_interface),
289
289
  ) -> List[schemas.responses.HistoryResponse]:
290
290
  """
@@ -293,6 +293,7 @@ async def flow_run_history(
293
293
  if isinstance(history_interval, float):
294
294
  history_interval = datetime.timedelta(seconds=history_interval)
295
295
 
296
+ assert isinstance(history_interval, datetime.timedelta)
296
297
  if history_interval < datetime.timedelta(seconds=1):
297
298
  raise HTTPException(
298
299
  status.HTTP_422_UNPROCESSABLE_ENTITY,
@@ -351,8 +352,8 @@ async def read_flow_run_graph_v1(
351
352
  @router.get("/{id:uuid}/graph-v2", tags=["Flow Run Graph"])
352
353
  async def read_flow_run_graph_v2(
353
354
  flow_run_id: UUID = Path(..., description="The flow run id", alias="id"),
354
- since: DateTime = Query(
355
- default=jsonable_encoder(DateTime.min),
355
+ since: datetime.datetime = Query(
356
+ default=jsonable_encoder(datetime.datetime.min),
356
357
  description="Only include runs that start or end after this time.",
357
358
  ),
358
359
  db: PrefectDBInterface = Depends(provide_database_interface),
@@ -36,7 +36,7 @@ async def run_history(
36
36
  deployments: Optional[schemas.filters.DeploymentFilter] = None,
37
37
  work_pools: Optional[schemas.filters.WorkPoolFilter] = None,
38
38
  work_queues: Optional[schemas.filters.WorkQueueFilter] = None,
39
- ) -> List[schemas.responses.HistoryResponse]:
39
+ ) -> list[schemas.responses.HistoryResponse]:
40
40
  """
41
41
  Produce a history of runs aggregated by interval and state
42
42
  """
@@ -1,8 +1,9 @@
1
1
  from datetime import datetime
2
2
  from typing import TYPE_CHECKING, List, Optional
3
+ from uuid import UUID
3
4
 
4
5
  import sqlalchemy as sa
5
- from fastapi import Depends, HTTPException, status
6
+ from fastapi import Depends, HTTPException, Path, status
6
7
  from pydantic import Field, model_serializer
7
8
 
8
9
  import prefect.server.schemas as schemas
@@ -173,3 +174,22 @@ async def read_task_run_counts_by_state(
173
174
  task_run_filter=task_runs,
174
175
  deployment_filter=deployments,
175
176
  )
177
+
178
+
179
+ @router.get("/{id}")
180
+ async def read_task_run_with_flow_run_name(
181
+ task_run_id: UUID = Path(..., description="The task run id", alias="id"),
182
+ db: PrefectDBInterface = Depends(provide_database_interface),
183
+ ) -> schemas.ui.UITaskRun:
184
+ """
185
+ Get a task run by id.
186
+ """
187
+ async with db.session_context() as session:
188
+ task_run = await models.task_runs.read_task_run_with_flow_run_name(
189
+ session=session, task_run_id=task_run_id
190
+ )
191
+
192
+ if not task_run:
193
+ raise HTTPException(status.HTTP_404_NOT_FOUND, detail="Task not found")
194
+
195
+ return schemas.ui.UITaskRun.model_validate(task_run)
prefect/settings/base.py CHANGED
@@ -101,7 +101,7 @@ class PrefectBaseSettings(BaseSettings):
101
101
  context={"include_secrets": include_secrets},
102
102
  )
103
103
  env_variables: dict[str, str] = {}
104
- for key in self.model_fields.keys():
104
+ for key in type(self).model_fields.keys():
105
105
  if isinstance(child_settings := getattr(self, key), PrefectBaseSettings):
106
106
  child_env = child_settings.to_environment_variables(
107
107
  exclude_unset=exclude_unset,
@@ -110,7 +110,7 @@ class PrefectBaseSettings(BaseSettings):
110
110
  )
111
111
  env_variables.update(child_env)
112
112
  elif (value := env.get(key)) is not None:
113
- validation_alias = self.model_fields[key].validation_alias
113
+ validation_alias = type(self).model_fields[key].validation_alias
114
114
  if include_aliases and validation_alias is not None:
115
115
  if isinstance(validation_alias, AliasChoices):
116
116
  for alias in validation_alias.choices:
@@ -134,9 +134,9 @@ class PrefectBaseSettings(BaseSettings):
134
134
  def ser_model(
135
135
  self, handler: SerializerFunctionWrapHandler, info: SerializationInfo
136
136
  ) -> Any:
137
- jsonable_self = handler(self)
137
+ jsonable_self: dict[str, Any] = handler(self)
138
138
  # iterate over fields to ensure child models that have been updated are also included
139
- for key in self.model_fields.keys():
139
+ for key in type(self).model_fields.keys():
140
140
  if info.exclude and key in info.exclude:
141
141
  continue
142
142
  if info.include and key not in info.include:
@@ -276,12 +276,17 @@ class Settings(PrefectBaseSettings):
276
276
  for r in restore_defaults or []:
277
277
  path = r.accessor.split(".")
278
278
  model = self
279
+ model_cls = model.__class__
280
+ model_fields = model_cls.model_fields
279
281
  for key in path[:-1]:
280
- model = model.model_fields[key].annotation
281
- assert model is not None, f"Invalid setting path: {r.accessor}"
282
-
283
- model_field = model.model_fields[path[-1]]
284
- assert model is not None, f"Invalid setting path: {r.accessor}"
282
+ model_field = model_fields[key]
283
+ model_cls = model_field.annotation
284
+ if model_cls is None:
285
+ raise ValueError(f"Invalid setting path: {r.accessor}")
286
+ model_fields = model_cls.model_fields
287
+
288
+ model_field = model_fields[path[-1]]
289
+ assert model_field is not None, f"Invalid setting path: {r.accessor}"
285
290
  if hasattr(model_field, "default"):
286
291
  default = model_field.default
287
292
  elif (
prefect/tasks.py CHANGED
@@ -382,10 +382,11 @@ class Task(Generic[P, R]):
382
382
 
383
383
  if isinstance(fn, classmethod):
384
384
  fn = cast(Callable[P, R], fn.__func__)
385
+ self._isclassmethod = True
385
386
 
386
387
  if isinstance(fn, staticmethod):
387
388
  fn = cast(Callable[P, R], fn.__func__)
388
- setattr(fn, "__prefect_static__", True)
389
+ self._isstaticmethod = True
389
390
 
390
391
  if not callable(fn):
391
392
  raise TypeError("'fn' must be callable")
@@ -547,11 +548,11 @@ class Task(Generic[P, R]):
547
548
 
548
549
  @property
549
550
  def isclassmethod(self) -> bool:
550
- return hasattr(self.fn, "__prefect_cls__")
551
+ return getattr(self, "_isclassmethod", False)
551
552
 
552
553
  @property
553
554
  def isstaticmethod(self) -> bool:
554
- return getattr(self.fn, "__prefect_static__", False)
555
+ return getattr(self, "_isstaticmethod", False)
555
556
 
556
557
  def __get__(self, instance: Any, owner: Any) -> "Task[P, R]":
557
558
  """
@@ -559,23 +560,21 @@ class Task(Generic[P, R]):
559
560
  When an instance method is loaded, this method is called with the "self" instance as
560
561
  an argument. We return a copy of the task with that instance bound to the task's function.
561
562
  """
562
-
563
- if self.isstaticmethod:
564
- return self
565
-
566
563
  # wrapped function is a classmethod
567
- if not instance:
564
+ if self.isclassmethod:
568
565
  bound_task = copy(self)
569
566
  setattr(bound_task.fn, "__prefect_cls__", owner)
570
567
  return bound_task
571
568
 
572
569
  # if the task is being accessed on an instance, bind the instance to the __prefect_self__ attribute
573
570
  # of the task's function. This will allow it to be automatically added to the task's parameters
574
- else:
571
+ if instance:
575
572
  bound_task = copy(self)
576
573
  bound_task.fn.__prefect_self__ = instance # type: ignore[attr-defined]
577
574
  return bound_task
578
575
 
576
+ return self
577
+
579
578
  def with_options(
580
579
  self,
581
580
  *,
@@ -130,7 +130,7 @@ def end_of_period(dt: datetime.datetime, period: str) -> datetime.datetime:
130
130
  ValueError: If an invalid unit is specified.
131
131
  """
132
132
  if sys.version_info >= (3, 13):
133
- from whenever import Weekday, ZonedDateTime
133
+ from whenever import Weekday, ZonedDateTime, days
134
134
 
135
135
  if not isinstance(dt.tzinfo, ZoneInfo):
136
136
  zdt = ZonedDateTime.from_py_datetime(
@@ -150,8 +150,8 @@ def end_of_period(dt: datetime.datetime, period: str) -> datetime.datetime:
150
150
  days_till_end_of_week: int = (
151
151
  Weekday.SUNDAY.value - zdt.date().day_of_week().value
152
152
  )
153
+ zdt = zdt + days(days_till_end_of_week)
153
154
  zdt = zdt.replace(
154
- day=zdt.day + days_till_end_of_week,
155
155
  hour=23,
156
156
  minute=59,
157
157
  second=59,
@@ -63,7 +63,7 @@ def get_call_parameters(
63
63
  """
64
64
  if hasattr(fn, "__prefect_self__"):
65
65
  call_args = (getattr(fn, "__prefect_self__"), *call_args)
66
- if hasattr(fn, "__prefect_cls__"):
66
+ elif hasattr(fn, "__prefect_cls__"):
67
67
  call_args = (getattr(fn, "__prefect_cls__"), *call_args)
68
68
 
69
69
  try:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: prefect-client
3
- Version: 3.3.0
3
+ Version: 3.3.2
4
4
  Summary: Workflow orchestration and management.
5
5
  Project-URL: Changelog, https://github.com/PrefectHQ/prefect/releases
6
6
  Project-URL: Documentation, https://docs.prefect.io
@@ -26,6 +26,7 @@ Requires-Dist: asgi-lifespan<3.0,>=1.0
26
26
  Requires-Dist: cachetools<6.0,>=5.3
27
27
  Requires-Dist: cloudpickle<4.0,>=2.0
28
28
  Requires-Dist: coolname<3.0.0,>=1.0.4
29
+ Requires-Dist: dateparser<2.0.0,>=1.1.1
29
30
  Requires-Dist: exceptiongroup>=1.0.0
30
31
  Requires-Dist: fastapi<1.0.0,>=0.111.0
31
32
  Requires-Dist: fsspec>=2022.5.0
@@ -1,33 +1,33 @@
1
1
  prefect/.prefectignore,sha256=awSprvKT0vI8a64mEOLrMxhxqcO-b0ERQeYpA2rNKVQ,390
2
2
  prefect/__init__.py,sha256=iCdcC5ZmeewikCdnPEP6YBAjPNV5dvfxpYCTpw30Hkw,3685
3
3
  prefect/__main__.py,sha256=WFjw3kaYJY6pOTA7WDOgqjsz8zUEUZHCcj3P5wyVa-g,66
4
- prefect/_build_info.py,sha256=YvpGLTpFxGQ_grDGKBX2Gt1wo6CZtiqYmzZ5LKEPXlY,180
4
+ prefect/_build_info.py,sha256=473OUpqqyTyKvJsXN8EGGpANJ_OK3HinkV88WnKjNJ4,180
5
5
  prefect/_result_records.py,sha256=S6QmsODkehGVSzbMm6ig022PYbI6gNKz671p_8kBYx4,7789
6
6
  prefect/_waiters.py,sha256=Ia2ITaXdHzevtyWIgJoOg95lrEXQqNEOquHvw3T33UQ,9026
7
7
  prefect/agent.py,sha256=dPvG1jDGD5HSH7aM2utwtk6RaJ9qg13XjkA0lAIgQmY,287
8
8
  prefect/artifacts.py,sha256=dMBUOAWnUamzjb5HSqwB5-GR2Qb-Gxee26XG5NDCUuw,22720
9
9
  prefect/automations.py,sha256=ZzPxn2tINdlXTQo805V4rIlbXuNWxd7cdb3gTJxZIeY,12567
10
10
  prefect/cache_policies.py,sha256=Kwdei4JjitNfx42OepKpDNxwPtEwRgUUAn_soxsnNzI,12699
11
- prefect/context.py,sha256=u1IMAe-X2__pJceNrELI_9aoAam0og9hz47QEyM6mUY,23733
11
+ prefect/context.py,sha256=LYEOlz7ZkuSDj7TmrE4mByy3N3TquFkIE2hEy0WHW1Y,23798
12
12
  prefect/engine.py,sha256=uB5JN4l045i5JTlRQNT1x7MwlSiGQ5Bop2Q6jHHOgxY,3699
13
13
  prefect/exceptions.py,sha256=wZLQQMRB_DyiYkeEdIC5OKwbba5A94Dlnics-lrWI7A,11581
14
14
  prefect/filesystems.py,sha256=v5YqGB4uXf9Ew2VuB9VCSkawvYMMVvEtZf7w1VmAmr8,18036
15
15
  prefect/flow_engine.py,sha256=hZpTYEtwTPMtwVoTCrfD93igN7rlKeG_0kyCvdU4aYE,58876
16
16
  prefect/flow_runs.py,sha256=dbHcXsOq1UsNM7vyJV9gboCTylmdUwQ_-W4NQt4R4ds,17267
17
- prefect/flows.py,sha256=wDVMQ67YSgzJR_jwSBjmLQ2zAtIKP7xN_R1UG7an-yk,109495
17
+ prefect/flows.py,sha256=0Es8TYUUEItxAz6G50eUmlIAXDaUTh4U0dQvgUyW2rk,109529
18
18
  prefect/futures.py,sha256=ZD5rdgUHA4sfxwHaPToumOUKlyn4d989JHR7eI97-Hs,23271
19
19
  prefect/main.py,sha256=8V-qLB4GjEVCkGRgGXeaIk-JIXY8Z9FozcNluj4Sm9E,2589
20
20
  prefect/plugins.py,sha256=FPRLR2mWVBMuOnlzeiTD9krlHONZH2rtYLD753JQDNQ,2516
21
21
  prefect/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  prefect/results.py,sha256=9mMOOZsj8ueqEch3oqxCaZPhF6D76Sn3P5TkqgVpbg8,36679
23
- prefect/schedules.py,sha256=9ufG4jhIA_R7vS9uXqnnZEgB7Ts922KMhNacWcveVgA,7291
23
+ prefect/schedules.py,sha256=dhq4OhImRvcmtxF7UH1m8RbwYdHT5RQsp_FrxVXfODE,7289
24
24
  prefect/serializers.py,sha256=QI0oEal_BO4HQaWSjr6ReSwT55Hn4sbSOXxGgQI1-y0,9249
25
25
  prefect/states.py,sha256=IOfdOJCbgz2G94VCMknX2dheP1bJ6w9rYm62SF2dGQ8,26021
26
26
  prefect/task_engine.py,sha256=IIvDRl2bnnO3aKXTmtWsz0pnV8kL7xjOaUyJTlL6LaM,61491
27
27
  prefect/task_runners.py,sha256=Ce_ngocfq_X-NA5zhPj13IdVmzZ5h6gXlmfxYWs2AXA,15828
28
28
  prefect/task_runs.py,sha256=7LIzfo3fondCyEUpU05sYFN5IfpZigBDXrhG5yc-8t0,9039
29
29
  prefect/task_worker.py,sha256=gMj_rl4EjTrnJ5YSOXinC6y-7KSK7fRQt_UYbZbrrV8,17879
30
- prefect/tasks.py,sha256=do0oWfp-VPTAVZsd1HstCtUyHbA5t4_ySmhr0mDW-2Q,74946
30
+ prefect/tasks.py,sha256=X83KIVowu-c-EDFbmh4ZurEVtEKTyUSkQ8Elo0nWy4k,74946
31
31
  prefect/transactions.py,sha256=BYvxr4ZSFmYDCODPhH8DO1_51inH35oJ75ZZOd_GI_w,16341
32
32
  prefect/variables.py,sha256=dCK3vX7TbkqXZhnNT_v7rcGh3ISRqoR6pJVLpoll3Js,8342
33
33
  prefect/_experimental/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -43,11 +43,11 @@ prefect/_internal/pytz.py,sha256=Sy_cD-Hkmo_Yrhx2Jucy7DgTRhvO8ZD0whW1ywbSg_U,137
43
43
  prefect/_internal/retries.py,sha256=pMHofrTQPDSxbVWclDwXbfhFKaDC6sxe1DkUOWugV6k,3040
44
44
  prefect/_internal/compatibility/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
45
  prefect/_internal/compatibility/async_dispatch.py,sha256=cUXOqSeseMUaje9oYUzasVPtNttyiHvrqfJl0zK66XI,2949
46
- prefect/_internal/compatibility/deprecated.py,sha256=cvislmRJ28SONsgxDwjgKj17j39P3kHt005loyOIkP0,8921
46
+ prefect/_internal/compatibility/deprecated.py,sha256=YUK1IGOgZrDh6dYRez-9IYTB1eqNC19QiSKbBDl88Qs,9305
47
47
  prefect/_internal/compatibility/migration.py,sha256=Z_r28B90ZQkSngXjr4I_9zA6P74_u48mtp2jYWB9zGg,6797
48
48
  prefect/_internal/concurrency/__init__.py,sha256=YlTwU9ryjPNwbJa45adLJY00t_DGCh1QrdtY9WdVFfw,2140
49
49
  prefect/_internal/concurrency/api.py,sha256=9MuQ0icQVTxwxChujn9mnv0WXRqwToysQy9GWC3sJRg,7352
50
- prefect/_internal/concurrency/calls.py,sha256=B7yNQUkLgwu6BUaNMtVAZaK7IoTkGtHIJHsYjKaDAnE,16467
50
+ prefect/_internal/concurrency/calls.py,sha256=DkXNOpOrEM8IhFNE7E_ondwg1gcBeceLgoWPH3F2ExM,16596
51
51
  prefect/_internal/concurrency/cancellation.py,sha256=stCN22-S0f_kZPk50hCEEYzH35fBel3Nthq86FrW0MU,18675
52
52
  prefect/_internal/concurrency/event_loop.py,sha256=N6SyBV0vaSF5HD4_JM8zL7oBGd2nMuEKkeSPnBZdHw4,2136
53
53
  prefect/_internal/concurrency/inspection.py,sha256=wUWVbHi4G-BxuuYFWhTNmo5yc1C651lQrp5OMiHPU1E,3545
@@ -58,10 +58,10 @@ prefect/_internal/concurrency/waiters.py,sha256=mhXpQk8swcUAxBk7f7kGn1fqy44XcFyn
58
58
  prefect/_internal/pydantic/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
59
59
  prefect/_internal/pydantic/schemas.py,sha256=tsRKq5yEIgiRbWMl3BPnbfNaKyDN6pq8WSs0M8SQMm4,452
60
60
  prefect/_internal/pydantic/v1_schema.py,sha256=wSyQr3LUbIh0R9LsZ6ItmLnQeAS8dxVMNpIb-4aPvjM,1175
61
- prefect/_internal/pydantic/v2_schema.py,sha256=lh-dnIoZigHJ6e1K89BVy0zDw3R0vQV9ih3ZC7s7i-Q,3223
61
+ prefect/_internal/pydantic/v2_schema.py,sha256=n56GUlGSUeNZLpMphHliN5ksryVdE9OQHoVir2hGXoA,3224
62
62
  prefect/_internal/pydantic/v2_validated_func.py,sha256=Ld8OtPFF7Ci-gHHmKhSMizBxzuIBOQ6kuIFNRh0vRVY,3731
63
63
  prefect/_internal/schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
- prefect/_internal/schemas/bases.py,sha256=NtamY7NIpQJP0XtTxTj2oHHu9PjXXYi3d7Lgi2V1iYQ,4245
64
+ prefect/_internal/schemas/bases.py,sha256=JqcZazL5Cp2hZ8Hssu8R2SVXRxHfbdRbTqmvwDYSzyk,4291
65
65
  prefect/_internal/schemas/fields.py,sha256=m4LrFNz8rA9uBhMk9VyQT6FIXmV_EVAW92hdXeSvHbY,837
66
66
  prefect/_internal/schemas/serializers.py,sha256=G_RGHfObjisUiRvd29p-zc6W4bwt5rE1OdR6TXNrRhQ,825
67
67
  prefect/_internal/schemas/validators.py,sha256=ty9hpmfiNEWpENgeBGrgs94j192L8SpLJ0bhFHeXV_8,19733
@@ -69,20 +69,20 @@ prefect/_vendor/croniter/__init__.py,sha256=NUFzdbyPcTQhIOFtzmFM0nbClAvBbKh2mlnT
69
69
  prefect/_vendor/croniter/croniter.py,sha256=eJ2HzStNAYV-vNiLOgDXl4sYWWHOsSA0dgwbkQoguhY,53009
70
70
  prefect/blocks/__init__.py,sha256=D0hB72qMfgqnBB2EMZRxUxlX9yLfkab5zDChOwJZmkY,220
71
71
  prefect/blocks/abstract.py,sha256=mpOAWopSR_RrzdxeurBTXVSKisP8ne-k8LYos-tp7go,17021
72
- prefect/blocks/core.py,sha256=CgxU59KUWiHLWUdTxOSDOfHkfFAyjLXc7eibmFc_xCo,62186
72
+ prefect/blocks/core.py,sha256=Z-vC0wP-c1mQUDc-0qgBloLba5OKfJ3hJtDinJyZOH0,62045
73
73
  prefect/blocks/fields.py,sha256=1m507VVmkpOnMF_7N-qboRjtw4_ceIuDneX3jZ3Jm54,63
74
74
  prefect/blocks/notifications.py,sha256=UpNNxc4Bwx0nSlDj-vZQOv2XyUCUB2PaO4uBPO1Y6XM,34162
75
75
  prefect/blocks/redis.py,sha256=lt_f1SIcS5OVvthCY6KRWiy5DyUZNRlHqkKhKF25P8c,5770
76
76
  prefect/blocks/system.py,sha256=4KiUIy5zizMqfGJrxvi9GLRLcMj4BjAXARxCUEmgbKI,5041
77
77
  prefect/blocks/webhook.py,sha256=hRpMGamOpS2HSM0iPU2ylVGnDWtWUPo6sIU3O24lIa0,2558
78
78
  prefect/client/__init__.py,sha256=bDeOC_I8_la5dwCAfxKzYSTSAr2tlq5HpxJgVoCCdAs,675
79
- prefect/client/base.py,sha256=HWfabmDRu2YX6G6X4XXAwvjQtaYdSjo3-OovzAM0mis,25539
79
+ prefect/client/base.py,sha256=7VAMyoy8KtmtI-H8KYsI16_uw9TlrXSrcxChFuMp65Q,26269
80
80
  prefect/client/cloud.py,sha256=jnFgg0osMVDGbLjdWkDX3rQg_0pI_zvfSlU480XCWGQ,6523
81
81
  prefect/client/collections.py,sha256=t9XkVU_onQMZ871L21F1oZnAiPSQeeVfd_MuDEBS3iM,1050
82
82
  prefect/client/constants.py,sha256=Z_GG8KF70vbbXxpJuqW5pLnwzujTVeHbcYYRikNmGH0,29
83
83
  prefect/client/subscriptions.py,sha256=b2gjoWjrTjshnv_s6zlPN3t0JIe2EKAdMqEzj3-kc6w,3879
84
84
  prefect/client/utilities.py,sha256=UEJD6nwYg2mD8-GSmru-E2ofXaBlmSFZ2-8T_5rIK6c,3472
85
- prefect/client/orchestration/__init__.py,sha256=_TYB6Dm_rrBJbOXAkxI4uby63Z6rW-YrQOXDVrfLfMs,60675
85
+ prefect/client/orchestration/__init__.py,sha256=1GHRA9-JWPBX6oSVNytQ1qL6epFeslRT2oBgZdFDJ68,60807
86
86
  prefect/client/orchestration/base.py,sha256=HM6ryHBZSzuHoCFQM9u5qR5k1dN9Bbr_ah6z1UPNbZQ,1542
87
87
  prefect/client/orchestration/routes.py,sha256=JFG1OWUBfrxPKW8Q7XWItlhOrSZ67IOySSoFZ6mxzm0,4364
88
88
  prefect/client/orchestration/_artifacts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -98,7 +98,7 @@ prefect/client/orchestration/_blocks_types/client.py,sha256=alA4xD-yp3mycAbzMyRu
98
98
  prefect/client/orchestration/_concurrency_limits/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
99
99
  prefect/client/orchestration/_concurrency_limits/client.py,sha256=r_oyY7hQbgyG1rntwe7WWcsraQHBKhk6MOPFUAHWiVc,23678
100
100
  prefect/client/orchestration/_deployments/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
101
- prefect/client/orchestration/_deployments/client.py,sha256=DfL6eiMaPkYBwCmkMcjKnyVIvE1qC8Xo14h2YqJhFsI,40769
101
+ prefect/client/orchestration/_deployments/client.py,sha256=GmKUbUB0gdFoPzp7zZVf1kQilErzhW09ivZPZ05-Zew,41548
102
102
  prefect/client/orchestration/_flow_runs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
103
103
  prefect/client/orchestration/_flow_runs/client.py,sha256=fjh5J-LG8tsny7BGYEvynbuGuHDAudYHpx-PamL0GYQ,32220
104
104
  prefect/client/orchestration/_flows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -110,10 +110,10 @@ prefect/client/orchestration/_variables/client.py,sha256=wKBbZBLGgs5feDCil-xxKt3
110
110
  prefect/client/orchestration/_work_pools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
111
111
  prefect/client/orchestration/_work_pools/client.py,sha256=s1DfUQQBgB2sLiVVPhLNTlkueUDE6uFsh4mAzcSA1OE,19881
112
112
  prefect/client/schemas/__init__.py,sha256=InZcDzdeWA2oaV0TlyvoMcyLcbi_aaqU1U9D6Gx-eoU,2747
113
- prefect/client/schemas/actions.py,sha256=I8LGTyDBrV4eXI_VSq8nQz5jUuOUAn1A0Q5JsPgCa2A,33032
113
+ prefect/client/schemas/actions.py,sha256=n8f-qNQs-mSca_zYdpZSR4A4OwnT6pylkjVc2VwFZBc,33684
114
114
  prefect/client/schemas/filters.py,sha256=zaiDkalrIpKjd38V4aP1GHlqD24KTPCZiKtPyX69ZWE,36607
115
- prefect/client/schemas/objects.py,sha256=H5VEfe3VZejD1KC4Gcb9KxTQ-YULiRIWJRtZoJ-2kH8,58508
116
- prefect/client/schemas/responses.py,sha256=iTXTiUhdRL7PxNyJXMZ4ngT7C8SepT_z7g_pnUnVlzo,15629
115
+ prefect/client/schemas/objects.py,sha256=qEV2lIdK6JGGhNsAiUDsvtPbjdIZZABqdjnA8cMsnak,58999
116
+ prefect/client/schemas/responses.py,sha256=9x8gP2O52xEf40EbnSKaKwxS1vIg347t8CqgHGMYCNg,16664
117
117
  prefect/client/schemas/schedules.py,sha256=sxLFk0SmFY7X1Y9R9HyGDqOS3U5NINBWTciUU7vTTic,14836
118
118
  prefect/client/schemas/sorting.py,sha256=L-2Mx-igZPtsUoRUguTcG3nIEstMEMPD97NwPM2Ox5s,2579
119
119
  prefect/client/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -147,8 +147,8 @@ prefect/docker/docker_image.py,sha256=bR_pEq5-FDxlwTj8CP_7nwZ_MiGK6KxIi8v7DRjy1K
147
147
  prefect/events/__init__.py,sha256=GtKl2bE--pJduTxelH2xy7SadlLJmmis8WR1EYixhuA,2094
148
148
  prefect/events/actions.py,sha256=A7jS8bo4zWGnrt3QfSoQs0uYC1xfKXio3IfU0XtTb5s,9129
149
149
  prefect/events/clients.py,sha256=XA33NpeRdgVglt7J47uFdpASa1bCvcKWyxsxQt3vEPQ,27290
150
- prefect/events/filters.py,sha256=cZ9KnQyWpIHshpAJ95nF5JosCag48enI5cBfKd2JNXA,8227
151
- prefect/events/related.py,sha256=nthW3toCPacIL1xkWeV_BG30X6hF4vF2rJHAgqtDXXU,6580
150
+ prefect/events/filters.py,sha256=2hVfzc3Rdgy0mBHDutWxT__LJY0zpVM8greWX3y6kjM,8233
151
+ prefect/events/related.py,sha256=CTeexYUmmA93V4gsR33GIFmw-SS-X_ouOpRg-oeq-BU,6672
152
152
  prefect/events/utilities.py,sha256=ww34bTMENCNwcp6RhhgzG0KgXOvKGe0MKmBdSJ8NpZY,3043
153
153
  prefect/events/worker.py,sha256=HjbibR0_J1W1nnNMZDFTXAbB0cl_cFGaFI87DvNGcnI,4557
154
154
  prefect/events/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -182,7 +182,7 @@ prefect/logging/highlighters.py,sha256=BCf_LNhFInIfGPqwuu8YVrGa4wVxNc4YXo2pYgftp
182
182
  prefect/logging/loggers.py,sha256=rwFJv0i3dhdKr25XX-xUkQy4Vv4dy18bTy366jrC0OQ,12741
183
183
  prefect/logging/logging.yml,sha256=tT7gTyC4NmngFSqFkCdHaw7R0GPNPDDsTCGZQByiJAQ,3169
184
184
  prefect/runner/__init__.py,sha256=pQBd9wVrUVUDUFJlgiweKSnbahoBZwqnd2O2jkhrULY,158
185
- prefect/runner/runner.py,sha256=Zx3ATmAh6J5PCuGKzxQXUzCgZDlYNMyX7l_RU-02mI8,65477
185
+ prefect/runner/runner.py,sha256=eT0TtLjkxzTTCrJBwpPg7m_QFkCU9VaJY75BFBZKjLY,64895
186
186
  prefect/runner/server.py,sha256=vyqMlUVVq6_Te1feny0G9qE8zJCYREZaF9ZstDuGvJQ,11327
187
187
  prefect/runner/storage.py,sha256=L7aSjie5L6qbXYCDqYDX3ouQ_NsNMlmfjPeaWOC-ncs,28043
188
188
  prefect/runner/submit.py,sha256=MtUrEKi4XznXXkDasILYYhY2w_DC2RcAL2hPJUgkgNo,8815
@@ -209,12 +209,12 @@ prefect/server/api/deployments.py,sha256=d-GAbVP3T0RVkkz6VN5nsQN7XU7fTjQg-vzYxuo
209
209
  prefect/server/api/events.py,sha256=3-Qdt6ORxFv3nLoogQqvd72zEulJSoAmcqZto2OULuk,9907
210
210
  prefect/server/api/flow_run_notification_policies.py,sha256=F8xNm6bgZTC3nFe9xCUJS4NlU9tLXZ8fShtJqmhT2m4,4828
211
211
  prefect/server/api/flow_run_states.py,sha256=lIdxVE9CqLgtDCuH9bTaKkzHNL81FPrr11liPzvONrw,1661
212
- prefect/server/api/flow_runs.py,sha256=X3PKGoqlF5tsKhwcslBynmQpi2b5DygeD2TvJqCvFgE,33511
212
+ prefect/server/api/flow_runs.py,sha256=W_9S7MGrTnUnY5NJdjn13LKdRWeUcyzj8lKx0i1BfH0,33709
213
213
  prefect/server/api/flows.py,sha256=Bz0ISh-9oY0W1X3mqA631_8678pQ6tuRGMpSgWAfxOc,7018
214
214
  prefect/server/api/logs.py,sha256=0z78tM2B5sRgJWYRWJn5lHhRoLtZB_OU3C-uALV8tOs,1571
215
215
  prefect/server/api/middleware.py,sha256=WkyuyeJIfo9Q0GAIVU5gO6yIGNVwoHwuBah5AB5oUyw,2733
216
216
  prefect/server/api/root.py,sha256=CeumFYIM_BDvPicJH9ry5PO_02PZTLeMqbLMGGTh90o,942
217
- prefect/server/api/run_history.py,sha256=FHepAgo1AYFeuh7rrAVzo_o3hu8Uc8-4DeH5aD5VGgw,5995
217
+ prefect/server/api/run_history.py,sha256=EW-GTPxZAQ5zXiAqHzmS-iAN_Bn6ZSgVQksDT-ZTsyc,5995
218
218
  prefect/server/api/saved_searches.py,sha256=UjoqLLe245QVIs6q5Vk4vdODCOoYzciEEjhi7B8sYCE,3233
219
219
  prefect/server/api/server.py,sha256=CIpLoiRUCuW345trzwr_Z8v53Kw_2RBqe3ppGvkjSx0,32940
220
220
  prefect/server/api/task_run_states.py,sha256=e63OPpxPudv_CIB5oKr8Z8rfQ-Osjm9Zq0iHe8obnMo,1647
@@ -231,9 +231,9 @@ prefect/server/api/ui/__init__.py,sha256=TCXO4ZUZCqCbm2QoNvWNTErkzWiX2nSACuO-0Ti
231
231
  prefect/server/api/ui/flow_runs.py,sha256=ALmUFY4WrJggN1ha0z-tqXeddG2GptswbPnB7iYixUM,4172
232
232
  prefect/server/api/ui/flows.py,sha256=W4kwqOCJ_2vROmMCmemH2Mq3uWbWZyu5q5uTZPBdYwk,5902
233
233
  prefect/server/api/ui/schemas.py,sha256=NVWA1RFnHW-MMU1s6WbNmp_S5mhbrN-_P41I4O2XtMg,2085
234
- prefect/server/api/ui/task_runs.py,sha256=dKVNe4EjmMrXH-VtsRoFTKJEBbl35upGHAW2C_AhKKM,6664
234
+ prefect/server/api/ui/task_runs.py,sha256=6CMrHmY-ybJGHXz7YlVVP2ZTmvq7w-XA9GUHqCcw_7o,7319
235
235
  prefect/settings/__init__.py,sha256=3jDLzExmq9HsRWo1kTSE16BO_3B3JlVsk5pR0s4PWEQ,2136
236
- prefect/settings/base.py,sha256=e5huXB_cWgw_N6QWuRNSWMjW6B-g261RbiQ-6RoWFVE,9667
236
+ prefect/settings/base.py,sha256=HGukXOXOokfqmrVirgejNskKtf1x2QheZ-ldRakxPJA,9701
237
237
  prefect/settings/constants.py,sha256=5NjVLG1Km9J9I-a6wrq-qmi_dTkPdwEk3IrY9bSxWvw,281
238
238
  prefect/settings/context.py,sha256=yKxnaDJHX8e2jmAVtw1RF9o7X4V3AOcz61sVeQyPX2c,2195
239
239
  prefect/settings/legacy.py,sha256=KG00GwaURl1zbwfCKAjwNRdJjB2UdTyo80gYF7U60jk,5693
@@ -251,7 +251,7 @@ prefect/settings/models/flows.py,sha256=kQ_sCA7TUqaEs9wWuGHkGQOuAIEZ5elD4UzeKRe0
251
251
  prefect/settings/models/internal.py,sha256=KUb16dg3lH5gwlnUnVJub6JHFXHRyZf1voINBvC_Ysc,718
252
252
  prefect/settings/models/logging.py,sha256=Sj9GDNr5QMFaP6CN0WJyfpwhpOk4p1yhv45dyQMRzHM,4729
253
253
  prefect/settings/models/results.py,sha256=VWFplQSSJyc0LXnziw1H5b3N_PDS32QBe_q2MWwYni0,1484
254
- prefect/settings/models/root.py,sha256=b9ZamM-BcD75Xsk0pZej3o2ix2kHkTP14hhITveFcTo,16549
254
+ prefect/settings/models/root.py,sha256=HpXt_I6T_kJw6QAxez4pCZl8p058etihzJbBNRylN3c,16767
255
255
  prefect/settings/models/runner.py,sha256=rD8OmNLwILmqnGe9YkM1dWKsulx3clYm4LI5N9vD5yM,1991
256
256
  prefect/settings/models/tasks.py,sha256=XA83-EmWv1FKvODSzvI1cvS3tGEbNs2qtdh0AbUdblQ,3640
257
257
  prefect/settings/models/testing.py,sha256=j9YH_WkB14iEzOjUtTmvY978qRSbgCypFSEi_cOs8no,1820
@@ -275,7 +275,7 @@ prefect/telemetry/processors.py,sha256=jw6j6LviOVxw3IBJe7cSjsxFk0zzY43jUmy6C9pcf
275
275
  prefect/telemetry/run_telemetry.py,sha256=_FbjiPqPemu4xvZuI2YBPwXeRJ2BcKRJ6qgO4UMzKKE,8571
276
276
  prefect/telemetry/services.py,sha256=DxgNNDTeWNtHBtioX8cjua4IrCbTiJJdYecx-gugg-w,2358
277
277
  prefect/types/__init__.py,sha256=yBjKxiQmSC7jXoo0UNmM3KZil1NBFS-BWGPfwSEaoJo,4621
278
- prefect/types/_datetime.py,sha256=NdlwqXTee_EJqgAUIh80xSPPUUvvuE_57ocs828Tk4o,7289
278
+ prefect/types/_datetime.py,sha256=Cy6z7MxPDV_-jH2vxqC3PNA2G74IdUDIB07Jaakdj5w,7294
279
279
  prefect/types/entrypoint.py,sha256=2FF03-wLPgtnqR_bKJDB2BsXXINPdu8ptY9ZYEZnXg8,328
280
280
  prefect/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
281
281
  prefect/utilities/_deprecated.py,sha256=b3pqRSoFANdVJAc8TJkygBcP-VjZtLJUxVIWC7kwspI,1303
@@ -283,7 +283,7 @@ prefect/utilities/_engine.py,sha256=9GW4X1lyAbmPwCuXXIubVJ7Z0DMT3dykkEUtp9tm5hI,
283
283
  prefect/utilities/_git.py,sha256=bPYWQdr9xvH0BqxR1ll1RkaSb3x0vhwylhYD5EilkKU,863
284
284
  prefect/utilities/annotations.py,sha256=0Elqgq6LR7pQqezNqT5wb6U_0e2pDO_zx6VseVL6kL8,4396
285
285
  prefect/utilities/asyncutils.py,sha256=xcfeNym2j3WH4gKXznON2hI1PpUTcwr_BGc16IQS3C4,19789
286
- prefect/utilities/callables.py,sha256=YiNdLzsOQfUsTa6bIU3TIMAuZWRiZVevYUQX2cSv5gY,25833
286
+ prefect/utilities/callables.py,sha256=xK1zWWcNPkFM4a0Yq8MaMyx9p_4F74DnDYoQ8zEkzZI,25835
287
287
  prefect/utilities/collections.py,sha256=c3nPLPWqIZQQdNuHs_nrbQJwuhQSX4ivUl-h9LtzXto,23243
288
288
  prefect/utilities/compat.py,sha256=nnPA3lf2f4Y-l645tYFFNmj5NDPaYvjqa9pbGKZ3WKE,582
289
289
  prefect/utilities/context.py,sha256=23SDMgdt07SjmB1qShiykHfGgiv55NBzdbMXM3fE9CI,1447
@@ -316,7 +316,7 @@ prefect/workers/cloud.py,sha256=dPvG1jDGD5HSH7aM2utwtk6RaJ9qg13XjkA0lAIgQmY,287
316
316
  prefect/workers/process.py,sha256=uxOwcqA2Ps-V-W6WeSdKCQMINrCxBEVx1K1Un8pb7vs,8973
317
317
  prefect/workers/server.py,sha256=2pmVeJZiVbEK02SO6BEZaBIvHMsn6G8LzjW8BXyiTtk,1952
318
318
  prefect/workers/utilities.py,sha256=VfPfAlGtTuDj0-Kb8WlMgAuOfgXCdrGAnKMapPSBrwc,2483
319
- prefect_client-3.3.0.dist-info/METADATA,sha256=1u64NIfd917nrg-CjmHQTxkh-8BuaPDFBgby2yKCREg,7411
320
- prefect_client-3.3.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
321
- prefect_client-3.3.0.dist-info/licenses/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
322
- prefect_client-3.3.0.dist-info/RECORD,,
319
+ prefect_client-3.3.2.dist-info/METADATA,sha256=PVg2Snt8oK_bXqIqzmErcZ6jQQs9hmsoEfBG9YbSXXs,7451
320
+ prefect_client-3.3.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
321
+ prefect_client-3.3.2.dist-info/licenses/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
322
+ prefect_client-3.3.2.dist-info/RECORD,,