prefect-client 3.4.1.dev4__py3-none-any.whl → 3.4.2.dev1__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.4.1.dev4"
3
- __build_date__ = "2025-05-07 08:09:04.443127+00:00"
4
- __git_commit__ = "15e90f75877628d769414cb3382d3aa5b30b50a5"
2
+ __version__ = "3.4.2.dev1"
3
+ __build_date__ = "2025-05-10 08:07:06.027110+00:00"
4
+ __git_commit__ = "f9346cb6934abec911bf71b8a871eeb05300382f"
5
5
  __dirty__ = False
@@ -10,6 +10,7 @@ from pydantic import BaseModel, ConfigDict, Field
10
10
  from rich.repr import RichReprResult
11
11
  from typing_extensions import Self
12
12
 
13
+ from prefect._internal.uuid7 import uuid7
13
14
  from prefect.types._datetime import (
14
15
  DateTime,
15
16
  human_friendly_diff,
@@ -100,7 +101,7 @@ class PrefectBaseModel(BaseModel):
100
101
 
101
102
  class IDBaseModel(PrefectBaseModel):
102
103
  """
103
- A PrefectBaseModel with an auto-generated UUID ID value.
104
+ A PrefectBaseModel with a randomly-generated UUID ID value.
104
105
 
105
106
  The ID is reset on copy() and not included in equality comparisons.
106
107
  """
@@ -109,6 +110,15 @@ class IDBaseModel(PrefectBaseModel):
109
110
  id: UUID = Field(default_factory=uuid4)
110
111
 
111
112
 
113
+ class TimeSeriesBaseModel(IDBaseModel):
114
+ """
115
+ A PrefectBaseModel with a time-oriented UUIDv7 ID value. Used for models that
116
+ operate like timeseries, such as runs, states, and logs.
117
+ """
118
+
119
+ id: UUID = Field(default_factory=uuid7)
120
+
121
+
112
122
  class ObjectBaseModel(IDBaseModel):
113
123
  """
114
124
  A PrefectBaseModel with an auto-generated UUID ID value and created /
@@ -10,7 +10,6 @@ from __future__ import annotations
10
10
 
11
11
  import datetime
12
12
  import os
13
- import re
14
13
  import urllib.parse
15
14
  import warnings
16
15
  from collections.abc import Iterable, Mapping, MutableMapping
@@ -36,60 +35,6 @@ M = TypeVar("M", bound=Mapping[str, Any])
36
35
  MM = TypeVar("MM", bound=MutableMapping[str, Any])
37
36
 
38
37
 
39
- LOWERCASE_LETTERS_NUMBERS_AND_DASHES_ONLY_REGEX = "^[a-z0-9-]*$"
40
- LOWERCASE_LETTERS_NUMBERS_AND_UNDERSCORES_REGEX = "^[a-z0-9_]*$"
41
- SLUG_REGEX = "^[a-z0-9]+([_-]+[a-z0-9]+)*$"
42
-
43
-
44
- @overload
45
- def raise_on_name_alphanumeric_dashes_only(
46
- value: str, field_name: str = ...
47
- ) -> str: ...
48
-
49
-
50
- @overload
51
- def raise_on_name_alphanumeric_dashes_only(
52
- value: None, field_name: str = ...
53
- ) -> None: ...
54
-
55
-
56
- def raise_on_name_alphanumeric_dashes_only(
57
- value: Optional[str], field_name: str = "value"
58
- ) -> Optional[str]:
59
- if value is not None and not bool(
60
- re.match(LOWERCASE_LETTERS_NUMBERS_AND_DASHES_ONLY_REGEX, value)
61
- ):
62
- raise ValueError(
63
- f"{field_name} must only contain lowercase letters, numbers, and dashes."
64
- )
65
- return value
66
-
67
-
68
- @overload
69
- def raise_on_name_alphanumeric_underscores_only(
70
- value: str, field_name: str = ...
71
- ) -> str: ...
72
-
73
-
74
- @overload
75
- def raise_on_name_alphanumeric_underscores_only(
76
- value: None, field_name: str = ...
77
- ) -> None: ...
78
-
79
-
80
- def raise_on_name_alphanumeric_underscores_only(
81
- value: Optional[str], field_name: str = "value"
82
- ) -> Optional[str]:
83
- if value is not None and not re.match(
84
- LOWERCASE_LETTERS_NUMBERS_AND_UNDERSCORES_REGEX, value
85
- ):
86
- raise ValueError(
87
- f"{field_name} must only contain lowercase letters, numbers, and"
88
- " underscores."
89
- )
90
- return value
91
-
92
-
93
38
  def validate_values_conform_to_schema(
94
39
  values: Optional[Mapping[str, Any]],
95
40
  schema: Optional[Mapping[str, Any]],
@@ -611,50 +556,3 @@ def validate_working_dir(v: Optional[Path | str]) -> Optional[Path]:
611
556
  if isinstance(v, str):
612
557
  return relative_path_to_current_platform(v)
613
558
  return v
614
-
615
-
616
- ### UNCATEGORIZED VALIDATORS ###
617
-
618
- # the above categories seem to be getting a bit unwieldy, so this is a temporary
619
- # catch-all for validators until we organize these into files
620
-
621
-
622
- @overload
623
- def validate_block_document_name(value: str) -> str: ...
624
-
625
-
626
- @overload
627
- def validate_block_document_name(value: None) -> None: ...
628
-
629
-
630
- def validate_block_document_name(value: Optional[str]) -> Optional[str]:
631
- if value is not None:
632
- raise_on_name_alphanumeric_dashes_only(value, field_name="Block document name")
633
- return value
634
-
635
-
636
- def validate_artifact_key(value: str) -> str:
637
- raise_on_name_alphanumeric_dashes_only(value, field_name="Artifact key")
638
- return value
639
-
640
-
641
- @overload
642
- def validate_variable_name(value: str) -> str: ...
643
-
644
-
645
- @overload
646
- def validate_variable_name(value: None) -> None: ...
647
-
648
-
649
- def validate_variable_name(value: Optional[str]) -> Optional[str]:
650
- if value is not None:
651
- if not bool(re.match(SLUG_REGEX, value)):
652
- raise ValueError(
653
- "Variable name must only contain lowercase letters, numbers, dashes, and underscores"
654
- )
655
- return value
656
-
657
-
658
- def validate_block_type_slug(value: str):
659
- raise_on_name_alphanumeric_dashes_only(value, field_name="Block type slug")
660
- return value
@@ -0,0 +1,11 @@
1
+ from typing import cast
2
+ from uuid import UUID
3
+
4
+ from uuid_extensions import uuid7 as _uuid7 # pyright: ignore[reportMissingTypeStubs]
5
+
6
+
7
+ def uuid7() -> UUID:
8
+ return cast(UUID, _uuid7())
9
+
10
+
11
+ __all__ = ["uuid7"]
@@ -12,12 +12,8 @@ from prefect._internal.schemas.bases import ActionBaseModel
12
12
  from prefect._internal.schemas.validators import (
13
13
  convert_to_strings,
14
14
  remove_old_deployment_fields,
15
- validate_artifact_key,
16
- validate_block_document_name,
17
- validate_block_type_slug,
18
15
  validate_name_present_on_nonanonymous_blocks,
19
16
  validate_schedule_max_scheduled_runs,
20
- validate_variable_name,
21
17
  )
22
18
  from prefect.client.schemas.objects import (
23
19
  StateDetails,
@@ -34,7 +30,6 @@ from prefect.client.schemas.schedules import (
34
30
  from prefect.schedules import Schedule
35
31
  from prefect.settings import PREFECT_DEPLOYMENT_SCHEDULE_MAX_SCHEDULED_RUNS
36
32
  from prefect.types import (
37
- MAX_VARIABLE_NAME_LENGTH,
38
33
  DateTime,
39
34
  KeyValueLabelsField,
40
35
  Name,
@@ -45,6 +40,12 @@ from prefect.types import (
45
40
  PositiveInteger,
46
41
  StrictVariableValue,
47
42
  )
43
+ from prefect.types.names import (
44
+ ArtifactKey,
45
+ BlockDocumentName,
46
+ BlockTypeSlug,
47
+ VariableName,
48
+ )
48
49
  from prefect.utilities.collections import visit_collection
49
50
  from prefect.utilities.pydantic import get_class_fields_only
50
51
 
@@ -216,7 +217,7 @@ class DeploymentCreate(ActionBaseModel):
216
217
  flow_id: UUID = Field(..., description="The ID of the flow to deploy.")
217
218
  paused: Optional[bool] = Field(default=None)
218
219
  schedules: list[DeploymentScheduleCreate] = Field(
219
- default_factory=list,
220
+ default_factory=lambda: [],
220
221
  description="A list of schedules for the deployment.",
221
222
  )
222
223
  concurrency_limit: Optional[int] = Field(
@@ -537,7 +538,7 @@ class SavedSearchCreate(ActionBaseModel):
537
538
 
538
539
  name: str = Field(default=..., description="The name of the saved search.")
539
540
  filters: list[objects.SavedSearchFilter] = Field(
540
- default_factory=list, description="The filter set for the saved search."
541
+ default_factory=lambda: [], description="The filter set for the saved search."
541
542
  )
542
543
 
543
544
 
@@ -585,7 +586,7 @@ class BlockTypeCreate(ActionBaseModel):
585
586
  """Data used by the Prefect REST API to create a block type."""
586
587
 
587
588
  name: str = Field(default=..., description="A block type's name")
588
- slug: str = Field(default=..., description="A block type's slug")
589
+ slug: BlockTypeSlug = Field(default=..., description="A block type's slug")
589
590
  logo_url: Optional[objects.HttpUrl] = Field(
590
591
  default=None, description="Web URL for the block type's logo"
591
592
  )
@@ -601,9 +602,6 @@ class BlockTypeCreate(ActionBaseModel):
601
602
  description="A code snippet demonstrating use of the corresponding block",
602
603
  )
603
604
 
604
- # validators
605
- _validate_slug_format = field_validator("slug")(validate_block_type_slug)
606
-
607
605
 
608
606
  class BlockTypeUpdate(ActionBaseModel):
609
607
  """Data used by the Prefect REST API to update a block type."""
@@ -638,7 +636,7 @@ class BlockSchemaCreate(ActionBaseModel):
638
636
  class BlockDocumentCreate(ActionBaseModel):
639
637
  """Data used by the Prefect REST API to create a block document."""
640
638
 
641
- name: Optional[Name] = Field(
639
+ name: Optional[BlockDocumentName] = Field(
642
640
  default=None, description="The name of the block document"
643
641
  )
644
642
  data: dict[str, Any] = Field(
@@ -658,8 +656,6 @@ class BlockDocumentCreate(ActionBaseModel):
658
656
  ),
659
657
  )
660
658
 
661
- _validate_name_format = field_validator("name")(validate_block_document_name)
662
-
663
659
  @model_validator(mode="before")
664
660
  def validate_name_is_present_if_not_anonymous(
665
661
  cls, values: dict[str, Any]
@@ -814,7 +810,7 @@ class WorkQueueUpdate(ActionBaseModel):
814
810
  class ArtifactCreate(ActionBaseModel):
815
811
  """Data used by the Prefect REST API to create an artifact."""
816
812
 
817
- key: Optional[str] = Field(default=None)
813
+ key: Optional[ArtifactKey] = Field(default=None)
818
814
  type: Optional[str] = Field(default=None)
819
815
  description: Optional[str] = Field(default=None)
820
816
  data: Optional[Union[dict[str, Any], Any]] = Field(default=None)
@@ -822,8 +818,6 @@ class ArtifactCreate(ActionBaseModel):
822
818
  flow_run_id: Optional[UUID] = Field(default=None)
823
819
  task_run_id: Optional[UUID] = Field(default=None)
824
820
 
825
- _validate_artifact_format = field_validator("key")(validate_artifact_key)
826
-
827
821
 
828
822
  class ArtifactUpdate(ActionBaseModel):
829
823
  """Data used by the Prefect REST API to update an artifact."""
@@ -836,12 +830,7 @@ class ArtifactUpdate(ActionBaseModel):
836
830
  class VariableCreate(ActionBaseModel):
837
831
  """Data used by the Prefect REST API to create a Variable."""
838
832
 
839
- name: str = Field(
840
- default=...,
841
- description="The name of the variable",
842
- examples=["my_variable"],
843
- max_length=MAX_VARIABLE_NAME_LENGTH,
844
- )
833
+ name: VariableName = Field(default=...)
845
834
  value: StrictVariableValue = Field(
846
835
  default=...,
847
836
  description="The value of the variable",
@@ -849,19 +838,11 @@ class VariableCreate(ActionBaseModel):
849
838
  )
850
839
  tags: Optional[list[str]] = Field(default=None)
851
840
 
852
- # validators
853
- _validate_name_format = field_validator("name")(validate_variable_name)
854
-
855
841
 
856
842
  class VariableUpdate(ActionBaseModel):
857
843
  """Data used by the Prefect REST API to update a Variable."""
858
844
 
859
- name: Optional[str] = Field(
860
- default=None,
861
- description="The name of the variable",
862
- examples=["my_variable"],
863
- max_length=MAX_VARIABLE_NAME_LENGTH,
864
- )
845
+ name: Optional[VariableName] = Field(default=None)
865
846
  value: StrictVariableValue = Field(
866
847
  default=None,
867
848
  description="The value of the variable",
@@ -869,9 +850,6 @@ class VariableUpdate(ActionBaseModel):
869
850
  )
870
851
  tags: Optional[list[str]] = Field(default=None)
871
852
 
872
- # validators
873
- _validate_name_format = field_validator("name")(validate_variable_name)
874
-
875
853
 
876
854
  class GlobalConcurrencyLimitCreate(ActionBaseModel):
877
855
  """Data used by the Prefect REST API to create a global concurrency limit."""
@@ -15,10 +15,11 @@ from typing import (
15
15
  Union,
16
16
  overload,
17
17
  )
18
- from uuid import UUID, uuid4
18
+ from uuid import UUID
19
19
 
20
20
  import orjson
21
21
  from pydantic import (
22
+ AfterValidator,
22
23
  ConfigDict,
23
24
  Discriminator,
24
25
  Field,
@@ -35,20 +36,23 @@ from typing_extensions import Literal, Self, TypeVar
35
36
 
36
37
  from prefect._internal.compatibility.async_dispatch import async_dispatch
37
38
  from prefect._internal.compatibility.migration import getattr_migration
38
- from prefect._internal.schemas.bases import ObjectBaseModel, PrefectBaseModel
39
+ from prefect._internal.schemas.bases import (
40
+ ObjectBaseModel,
41
+ PrefectBaseModel,
42
+ TimeSeriesBaseModel,
43
+ )
39
44
  from prefect._internal.schemas.fields import CreatedBy, UpdatedBy
40
45
  from prefect._internal.schemas.validators import (
41
46
  get_or_create_run_name,
42
47
  list_length_50_or_less,
43
- raise_on_name_alphanumeric_dashes_only,
44
48
  set_run_policy_deprecated_fields,
45
- validate_block_document_name,
46
49
  validate_default_queue_id_not_none,
47
50
  validate_max_metadata_length,
48
51
  validate_name_present_on_nonanonymous_blocks,
49
52
  validate_not_negative,
50
53
  validate_parent_and_ref_diff,
51
54
  )
55
+ from prefect._internal.uuid7 import uuid7
52
56
  from prefect._result_records import ResultRecordMetadata
53
57
  from prefect.client.schemas.schedules import SCHEDULE_TYPES
54
58
  from prefect.settings import PREFECT_CLOUD_API_URL, PREFECT_CLOUD_UI_URL
@@ -61,6 +65,10 @@ from prefect.types import (
61
65
  StrictVariableValue,
62
66
  )
63
67
  from prefect.types._datetime import DateTime, now
68
+ from prefect.types.names import (
69
+ BlockDocumentName,
70
+ raise_on_name_alphanumeric_dashes_only,
71
+ )
64
72
  from prefect.utilities.asyncutils import run_coro_as_sync
65
73
  from prefect.utilities.collections import AutoEnum, visit_collection
66
74
  from prefect.utilities.names import generate_slug
@@ -181,7 +189,7 @@ def data_discriminator(x: Any) -> str:
181
189
  return "Any"
182
190
 
183
191
 
184
- class State(ObjectBaseModel, Generic[R]):
192
+ class State(TimeSeriesBaseModel, ObjectBaseModel, Generic[R]):
185
193
  """
186
194
  The state of a run.
187
195
  """
@@ -412,7 +420,7 @@ class State(ObjectBaseModel, Generic[R]):
412
420
  """
413
421
  return self.model_copy(
414
422
  update={
415
- "id": uuid4(),
423
+ "id": uuid7(),
416
424
  "created": now("UTC"),
417
425
  "updated": now("UTC"),
418
426
  "timestamp": now("UTC"),
@@ -508,7 +516,7 @@ class FlowRunPolicy(PrefectBaseModel):
508
516
  return values
509
517
 
510
518
 
511
- class FlowRun(ObjectBaseModel):
519
+ class FlowRun(TimeSeriesBaseModel, ObjectBaseModel):
512
520
  name: str = Field(
513
521
  default_factory=lambda: generate_slug(2),
514
522
  description=(
@@ -764,7 +772,7 @@ class Constant(TaskRunInput):
764
772
  type: str
765
773
 
766
774
 
767
- class TaskRun(ObjectBaseModel):
775
+ class TaskRun(TimeSeriesBaseModel, ObjectBaseModel):
768
776
  name: str = Field(
769
777
  default_factory=lambda: generate_slug(2), examples=["my-task-run"]
770
778
  )
@@ -1000,7 +1008,7 @@ class BlockSchema(ObjectBaseModel):
1000
1008
  class BlockDocument(ObjectBaseModel):
1001
1009
  """An ORM representation of a block document."""
1002
1010
 
1003
- name: Optional[Name] = Field(
1011
+ name: Optional[BlockDocumentName] = Field(
1004
1012
  default=None,
1005
1013
  description=(
1006
1014
  "The block document's name. Not required for anonymous block documents."
@@ -1029,8 +1037,6 @@ class BlockDocument(ObjectBaseModel):
1029
1037
  ),
1030
1038
  )
1031
1039
 
1032
- _validate_name_format = field_validator("name")(validate_block_document_name)
1033
-
1034
1040
  @model_validator(mode="before")
1035
1041
  @classmethod
1036
1042
  def validate_name_is_present_if_not_anonymous(
@@ -1133,7 +1139,8 @@ class Deployment(ObjectBaseModel):
1133
1139
  default=None, description="The concurrency limit for the deployment."
1134
1140
  )
1135
1141
  schedules: list[DeploymentSchedule] = Field(
1136
- default_factory=list, description="A list of schedules for the deployment."
1142
+ default_factory=lambda: [],
1143
+ description="A list of schedules for the deployment.",
1137
1144
  )
1138
1145
  job_variables: dict[str, Any] = Field(
1139
1146
  default_factory=dict,
@@ -1219,7 +1226,7 @@ class ConcurrencyLimit(ObjectBaseModel):
1219
1226
  )
1220
1227
  concurrency_limit: int = Field(default=..., description="The concurrency limit.")
1221
1228
  active_slots: list[UUID] = Field(
1222
- default_factory=list,
1229
+ default_factory=lambda: [],
1223
1230
  description="A list of active run ids using a concurrency slot",
1224
1231
  )
1225
1232
 
@@ -1300,11 +1307,12 @@ class SavedSearch(ObjectBaseModel):
1300
1307
 
1301
1308
  name: str = Field(default=..., description="The name of the saved search.")
1302
1309
  filters: list[SavedSearchFilter] = Field(
1303
- default_factory=list, description="The filter set for the saved search."
1310
+ default_factory=lambda: [],
1311
+ description="The filter set for the saved search.",
1304
1312
  )
1305
1313
 
1306
1314
 
1307
- class Log(ObjectBaseModel):
1315
+ class Log(TimeSeriesBaseModel, ObjectBaseModel):
1308
1316
  """An ORM representation of log data."""
1309
1317
 
1310
1318
  name: str = Field(default=..., description="The logger name.")
@@ -1644,7 +1652,9 @@ class Variable(ObjectBaseModel):
1644
1652
 
1645
1653
  class FlowRunInput(ObjectBaseModel):
1646
1654
  flow_run_id: UUID = Field(description="The flow run ID associated with the input.")
1647
- key: str = Field(description="The key of the input.")
1655
+ key: Annotated[str, AfterValidator(raise_on_name_alphanumeric_dashes_only)] = Field(
1656
+ description="The key of the input."
1657
+ )
1648
1658
  value: str = Field(description="The value of the input.")
1649
1659
  sender: Optional[str] = Field(default=None, description="The sender of the input.")
1650
1660
 
@@ -1658,12 +1668,6 @@ class FlowRunInput(ObjectBaseModel):
1658
1668
  """
1659
1669
  return orjson.loads(self.value)
1660
1670
 
1661
- @field_validator("key", check_fields=False)
1662
- @classmethod
1663
- def validate_name_characters(cls, v: str) -> str:
1664
- raise_on_name_alphanumeric_dashes_only(v)
1665
- return v
1666
-
1667
1671
 
1668
1672
  class GlobalConcurrencyLimit(ObjectBaseModel):
1669
1673
  """An ORM representation of a global concurrency limit"""
prefect/events/filters.py CHANGED
@@ -1,5 +1,7 @@
1
+ from __future__ import annotations
2
+
1
3
  import datetime
2
- from typing import Optional
4
+ from typing import Optional, Union
3
5
  from uuid import UUID
4
6
 
5
7
  from pydantic import Field
@@ -43,11 +45,21 @@ class EventDataFilter(PrefectBaseModel, extra="forbid"): # type: ignore[call-ar
43
45
  """A base class for filtering event data."""
44
46
 
45
47
  def get_filters(self) -> list["EventDataFilter"]:
46
- filters: list["EventDataFilter"] = [
47
- filter
48
- for filter in [getattr(self, name) for name in type(self).model_fields]
49
- if isinstance(filter, EventDataFilter)
50
- ]
48
+ filters: list[EventDataFilter] = []
49
+ for filter in [
50
+ getattr(self, name) for name in self.__class__.model_fields.keys()
51
+ ]:
52
+ # Any embedded list of filters are flattened and thus ANDed together
53
+ subfilters: list[EventDataFilter] = (
54
+ filter if isinstance(filter, list) else [filter]
55
+ )
56
+
57
+ for subfilter in subfilters:
58
+ if not isinstance(subfilter, EventDataFilter):
59
+ continue
60
+
61
+ filters.append(subfilter)
62
+
51
63
  return filters
52
64
 
53
65
  def includes(self, event: Event) -> bool:
@@ -233,18 +245,20 @@ class EventFilter(EventDataFilter):
233
245
  default=None,
234
246
  description="Filter criteria for the event name",
235
247
  )
236
- any_resource: Optional[EventAnyResourceFilter] = Field(
237
- default=None,
238
- description="Filter criteria for any resource involved in the event",
239
- )
240
248
  resource: Optional[EventResourceFilter] = Field(
241
249
  default=None,
242
250
  description="Filter criteria for the resource of the event",
243
251
  )
244
- related: Optional[EventRelatedFilter] = Field(
252
+ related: Optional[Union[EventRelatedFilter, list[EventRelatedFilter]]] = Field(
245
253
  default=None,
246
254
  description="Filter criteria for the related resources of the event",
247
255
  )
256
+ any_resource: Optional[
257
+ Union[EventAnyResourceFilter, list[EventAnyResourceFilter]]
258
+ ] = Field(
259
+ default=None,
260
+ description="Filter criteria for any resource involved in the event",
261
+ )
248
262
  id: EventIDFilter = Field(
249
263
  default_factory=lambda: EventIDFilter(id=[]),
250
264
  description="Filter criteria for the events' ID",
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  import abc
2
4
  import textwrap
3
5
  from datetime import timedelta
@@ -103,7 +105,7 @@ class ResourceTrigger(Trigger, abc.ABC):
103
105
  default_factory=lambda: ResourceSpecification.model_validate({}),
104
106
  description="Labels for resources which this trigger will match.",
105
107
  )
106
- match_related: ResourceSpecification = Field(
108
+ match_related: Union[ResourceSpecification, list[ResourceSpecification]] = Field(
107
109
  default_factory=lambda: ResourceSpecification.model_validate({}),
108
110
  description="Labels for related resources which this trigger will match.",
109
111
  )
@@ -13,7 +13,7 @@ from typing import (
13
13
  Tuple,
14
14
  Union,
15
15
  )
16
- from uuid import UUID, uuid4
16
+ from uuid import UUID
17
17
 
18
18
  from pydantic import (
19
19
  AfterValidator,
@@ -26,6 +26,7 @@ from typing_extensions import Annotated, Self
26
26
 
27
27
  import prefect.types._datetime
28
28
  from prefect._internal.schemas.bases import PrefectBaseModel
29
+ from prefect._internal.uuid7 import uuid7
29
30
  from prefect.logging import get_logger
30
31
  from prefect.settings import (
31
32
  PREFECT_EVENTS_MAXIMUM_LABELS_PER_RESOURCE,
@@ -135,7 +136,7 @@ class Event(PrefectBaseModel):
135
136
  description="An open-ended set of data describing what happened",
136
137
  )
137
138
  id: UUID = Field(
138
- default_factory=uuid4,
139
+ default_factory=uuid7,
139
140
  description="The client-provided identifier of this event",
140
141
  )
141
142
  follows: Optional[UUID] = Field(
@@ -3,7 +3,7 @@ Routes for interacting with work queue objects.
3
3
  """
4
4
 
5
5
  from typing import TYPE_CHECKING, List, Optional
6
- from uuid import UUID, uuid4
6
+ from uuid import UUID
7
7
 
8
8
  import sqlalchemy as sa
9
9
  from fastapi import (
@@ -20,6 +20,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
20
20
  import prefect.server.api.dependencies as dependencies
21
21
  import prefect.server.models as models
22
22
  import prefect.server.schemas as schemas
23
+ from prefect._internal.uuid7 import uuid7
23
24
  from prefect.server.api.validation import validate_job_variable_defaults_for_work_pool
24
25
  from prefect.server.database import PrefectDBInterface, provide_database_interface
25
26
  from prefect.server.models.deployments import mark_deployments_ready
@@ -184,7 +185,7 @@ async def create_work_pool(
184
185
  )
185
186
 
186
187
  await emit_work_pool_status_event(
187
- event_id=uuid4(),
188
+ event_id=uuid7(),
188
189
  occurred=now("UTC"),
189
190
  pre_update_work_pool=None,
190
191
  work_pool=model,
prefect/task_runners.py CHANGED
@@ -21,6 +21,7 @@ from typing import (
21
21
 
22
22
  from typing_extensions import ParamSpec, Self, TypeVar
23
23
 
24
+ from prefect._internal.uuid7 import uuid7
24
25
  from prefect.client.schemas.objects import TaskRunInput
25
26
  from prefect.exceptions import MappingLengthMismatch, MappingMissingIterable
26
27
  from prefect.futures import (
@@ -290,7 +291,7 @@ class ThreadPoolTaskRunner(TaskRunner[PrefectConcurrentFuture[R]]):
290
291
  from prefect.context import FlowRunContext
291
292
  from prefect.task_engine import run_task_async, run_task_sync
292
293
 
293
- task_run_id = uuid.uuid4()
294
+ task_run_id = uuid7()
294
295
  cancel_event = threading.Event()
295
296
  self._cancel_events[task_run_id] = cancel_event
296
297
  context = copy_context()
prefect/tasks.py CHANGED
@@ -32,6 +32,7 @@ from uuid import UUID, uuid4
32
32
  from typing_extensions import Literal, ParamSpec, Self, TypeAlias, TypeIs
33
33
 
34
34
  import prefect.states
35
+ from prefect._internal.uuid7 import uuid7
35
36
  from prefect.cache_policies import DEFAULT, NO_CACHE, CachePolicy
36
37
  from prefect.client.orchestration import get_client
37
38
  from prefect.client.schemas import TaskRun
@@ -953,7 +954,7 @@ class Task(Generic[P, R]):
953
954
  if flow_run_context and flow_run_context.flow_run
954
955
  else None
955
956
  )
956
- task_run_id = id or uuid4()
957
+ task_run_id = id or uuid7()
957
958
  state = prefect.states.Pending(
958
959
  state_details=StateDetails(
959
960
  task_run_id=task_run_id,
prefect/types/__init__.py CHANGED
@@ -1,13 +1,21 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from functools import partial
4
- from typing import Annotated, Any, Dict, List, Optional, Set, TypeVar, Union
4
+ from typing import Annotated, Any, Optional, TypeVar, Union, cast
5
+ from uuid import UUID
5
6
  from typing_extensions import Literal
6
7
  import orjson
7
8
  import pydantic
8
9
 
9
-
10
10
  from ._datetime import DateTime, Date
11
+ from .names import (
12
+ Name,
13
+ NameOrEmpty,
14
+ NonEmptyishName,
15
+ BANNED_CHARACTERS,
16
+ WITHOUT_BANNED_CHARACTERS,
17
+ MAX_VARIABLE_NAME_LENGTH,
18
+ )
11
19
  from pydantic import (
12
20
  BeforeValidator,
13
21
  Field,
@@ -21,7 +29,6 @@ from zoneinfo import available_timezones
21
29
 
22
30
  T = TypeVar("T")
23
31
 
24
- MAX_VARIABLE_NAME_LENGTH = 255
25
32
  MAX_VARIABLE_VALUE_LENGTH = 5000
26
33
 
27
34
  NonNegativeInteger = Annotated[int, Field(ge=0)]
@@ -39,37 +46,14 @@ TimeZone = Annotated[
39
46
  ]
40
47
 
41
48
 
42
- BANNED_CHARACTERS = ["/", "%", "&", ">", "<"]
43
-
44
- WITHOUT_BANNED_CHARACTERS = r"^[^" + "".join(BANNED_CHARACTERS) + "]+$"
45
- Name = Annotated[str, Field(pattern=WITHOUT_BANNED_CHARACTERS)]
46
-
47
- WITHOUT_BANNED_CHARACTERS_EMPTY_OK = r"^[^" + "".join(BANNED_CHARACTERS) + "]*$"
48
- NameOrEmpty = Annotated[str, Field(pattern=WITHOUT_BANNED_CHARACTERS_EMPTY_OK)]
49
-
50
-
51
- def non_emptyish(value: str) -> str:
52
- if not value.strip("' \""):
53
- raise ValueError("name cannot be an empty string")
54
-
55
- return value
56
-
57
-
58
- NonEmptyishName = Annotated[
59
- str,
60
- Field(pattern=WITHOUT_BANNED_CHARACTERS),
61
- BeforeValidator(non_emptyish),
62
- ]
63
-
64
-
65
49
  VariableValue = Union[
66
50
  StrictStr,
67
51
  StrictInt,
68
52
  StrictBool,
69
53
  StrictFloat,
70
54
  None,
71
- Dict[str, Any],
72
- List[Any],
55
+ dict[str, Any],
56
+ list[Any],
73
57
  ]
74
58
 
75
59
 
@@ -100,24 +84,24 @@ def cast_none_to_empty_dict(value: Any) -> dict[str, Any]:
100
84
 
101
85
 
102
86
  KeyValueLabels = Annotated[
103
- Dict[str, Union[StrictBool, StrictInt, StrictFloat, str]],
87
+ dict[str, Union[StrictBool, StrictInt, StrictFloat, str]],
104
88
  BeforeValidator(cast_none_to_empty_dict),
105
89
  ]
106
90
 
107
91
 
108
92
  ListOfNonEmptyStrings = Annotated[
109
- List[str],
93
+ list[str],
110
94
  BeforeValidator(lambda x: [str(s) for s in x if str(s).strip()]),
111
95
  ]
112
96
 
113
97
 
114
- class SecretDict(pydantic.Secret[Dict[str, Any]]):
98
+ class SecretDict(pydantic.Secret[dict[str, Any]]):
115
99
  pass
116
100
 
117
101
 
118
102
  def validate_set_T_from_delim_string(
119
- value: Union[str, T, Set[T], None], type_: type[T], delim: str | None = None
120
- ) -> Set[T]:
103
+ value: Union[str, T, set[T], None], type_: Any, delim: str | None = None
104
+ ) -> set[T]:
121
105
  """
122
106
  "no-info" before validator useful in scooping env vars
123
107
 
@@ -131,20 +115,20 @@ def validate_set_T_from_delim_string(
131
115
  delim = delim or ","
132
116
  if isinstance(value, str):
133
117
  return {T_adapter.validate_strings(s.strip()) for s in value.split(delim)}
134
- errors = []
118
+ errors: list[pydantic.ValidationError] = []
135
119
  try:
136
120
  return {T_adapter.validate_python(value)}
137
121
  except pydantic.ValidationError as e:
138
122
  errors.append(e)
139
123
  try:
140
- return TypeAdapter(Set[type_]).validate_python(value)
124
+ return TypeAdapter(set[type_]).validate_python(value)
141
125
  except pydantic.ValidationError as e:
142
126
  errors.append(e)
143
127
  raise ValueError(f"Invalid set[{type_}]: {errors}")
144
128
 
145
129
 
146
130
  ClientRetryExtraCodes = Annotated[
147
- Union[str, StatusCode, Set[StatusCode], None],
131
+ Union[str, StatusCode, set[StatusCode], None],
148
132
  BeforeValidator(partial(validate_set_T_from_delim_string, type_=StatusCode)),
149
133
  ]
150
134
 
@@ -170,11 +154,15 @@ KeyValueLabelsField = Annotated[
170
154
 
171
155
 
172
156
  __all__ = [
157
+ "BANNED_CHARACTERS",
158
+ "WITHOUT_BANNED_CHARACTERS",
173
159
  "ClientRetryExtraCodes",
174
160
  "Date",
175
161
  "DateTime",
176
162
  "LogLevel",
177
163
  "KeyValueLabelsField",
164
+ "MAX_VARIABLE_NAME_LENGTH",
165
+ "MAX_VARIABLE_VALUE_LENGTH",
178
166
  "NonNegativeInteger",
179
167
  "PositiveInteger",
180
168
  "ListOfNonEmptyStrings",
prefect/types/names.py ADDED
@@ -0,0 +1,139 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ from functools import partial
5
+ from typing import Annotated, overload
6
+
7
+ from pydantic import AfterValidator, BeforeValidator, Field
8
+
9
+ LOWERCASE_LETTERS_NUMBERS_AND_DASHES_ONLY_REGEX = "^[a-z0-9-]*$"
10
+ LOWERCASE_LETTERS_NUMBERS_AND_UNDERSCORES_REGEX = "^[a-z0-9_]*$"
11
+ LOWERCASE_LETTERS_NUMBERS_AND_DASHES_OR_UNDERSCORES_REGEX = "^[a-z0-9-_]*$"
12
+
13
+
14
+ @overload
15
+ def raise_on_name_alphanumeric_dashes_only(
16
+ value: str, field_name: str = ...
17
+ ) -> str: ...
18
+
19
+
20
+ @overload
21
+ def raise_on_name_alphanumeric_dashes_only(
22
+ value: None, field_name: str = ...
23
+ ) -> None: ...
24
+
25
+
26
+ def raise_on_name_alphanumeric_dashes_only(
27
+ value: str | None, field_name: str = "value"
28
+ ) -> str | None:
29
+ if value is not None and not bool(
30
+ re.match(LOWERCASE_LETTERS_NUMBERS_AND_DASHES_ONLY_REGEX, value)
31
+ ):
32
+ raise ValueError(
33
+ f"{field_name} must only contain lowercase letters, numbers, and dashes."
34
+ )
35
+ return value
36
+
37
+
38
+ @overload
39
+ def raise_on_name_alphanumeric_underscores_only(
40
+ value: str, field_name: str = ...
41
+ ) -> str: ...
42
+
43
+
44
+ @overload
45
+ def raise_on_name_alphanumeric_underscores_only(
46
+ value: None, field_name: str = ...
47
+ ) -> None: ...
48
+
49
+
50
+ def raise_on_name_alphanumeric_underscores_only(
51
+ value: str | None, field_name: str = "value"
52
+ ) -> str | None:
53
+ if value is not None and not re.match(
54
+ LOWERCASE_LETTERS_NUMBERS_AND_UNDERSCORES_REGEX, value
55
+ ):
56
+ raise ValueError(
57
+ f"{field_name} must only contain lowercase letters, numbers, and"
58
+ " underscores."
59
+ )
60
+ return value
61
+
62
+
63
+ def raise_on_name_alphanumeric_dashes_underscores_only(
64
+ value: str, field_name: str = "value"
65
+ ) -> str:
66
+ if not re.match(LOWERCASE_LETTERS_NUMBERS_AND_DASHES_OR_UNDERSCORES_REGEX, value):
67
+ raise ValueError(
68
+ f"{field_name} must only contain lowercase letters, numbers, and"
69
+ " dashes or underscores."
70
+ )
71
+ return value
72
+
73
+
74
+ BANNED_CHARACTERS = ["/", "%", "&", ">", "<"]
75
+
76
+ WITHOUT_BANNED_CHARACTERS = r"^[^" + "".join(BANNED_CHARACTERS) + "]+$"
77
+ Name = Annotated[str, Field(pattern=WITHOUT_BANNED_CHARACTERS)]
78
+
79
+ WITHOUT_BANNED_CHARACTERS_EMPTY_OK = r"^[^" + "".join(BANNED_CHARACTERS) + "]*$"
80
+ NameOrEmpty = Annotated[str, Field(pattern=WITHOUT_BANNED_CHARACTERS_EMPTY_OK)]
81
+
82
+
83
+ def non_emptyish(value: str) -> str:
84
+ if not value.strip("' \""):
85
+ raise ValueError("name cannot be an empty string")
86
+
87
+ return value
88
+
89
+
90
+ NonEmptyishName = Annotated[
91
+ str,
92
+ Field(pattern=WITHOUT_BANNED_CHARACTERS),
93
+ BeforeValidator(non_emptyish),
94
+ ]
95
+
96
+
97
+ ### specific names
98
+
99
+ BlockDocumentName = Annotated[
100
+ Name,
101
+ AfterValidator(
102
+ partial(
103
+ raise_on_name_alphanumeric_dashes_only, field_name="Block document name"
104
+ )
105
+ ),
106
+ ]
107
+
108
+
109
+ BlockTypeSlug = Annotated[
110
+ str,
111
+ AfterValidator(
112
+ partial(raise_on_name_alphanumeric_dashes_only, field_name="Block type slug")
113
+ ),
114
+ ]
115
+
116
+ ArtifactKey = Annotated[
117
+ str,
118
+ AfterValidator(
119
+ partial(raise_on_name_alphanumeric_dashes_only, field_name="Artifact key")
120
+ ),
121
+ ]
122
+
123
+ MAX_VARIABLE_NAME_LENGTH = 255
124
+
125
+
126
+ VariableName = Annotated[
127
+ str,
128
+ AfterValidator(
129
+ partial(
130
+ raise_on_name_alphanumeric_dashes_underscores_only,
131
+ field_name="Variable name",
132
+ )
133
+ ),
134
+ Field(
135
+ max_length=MAX_VARIABLE_NAME_LENGTH,
136
+ description="The name of the variable",
137
+ examples=["my_variable"],
138
+ ),
139
+ ]
prefect/workers/base.py CHANGED
@@ -697,6 +697,25 @@ class BaseWorker(abc.ABC, Generic[C, V, R]):
697
697
  "Workers must implement a method for running submitted flow runs"
698
698
  )
699
699
 
700
+ async def _initiate_run(
701
+ self,
702
+ flow_run: "FlowRun",
703
+ configuration: C,
704
+ ) -> None:
705
+ """
706
+ This method is called by the worker to initiate a flow run and should return as
707
+ soon as possible.
708
+
709
+ This method is used in `.submit` to allow non-blocking submission of flows. For
710
+ workers that wait for completion in their `run` method, this method should be
711
+ implemented to return immediately.
712
+
713
+ If this method is not implemented, `.submit` will fall back to the `.run` method.
714
+ """
715
+ raise NotImplementedError(
716
+ "This worker has not implemented `_initiate_run`. Please use `run` instead."
717
+ )
718
+
700
719
  async def submit(
701
720
  self,
702
721
  flow: "Flow[..., FR]",
@@ -866,16 +885,19 @@ class BaseWorker(abc.ABC, Generic[C, V, R]):
866
885
  try:
867
886
  # Call the implementation-specific run method with the constructed configuration. This is where the
868
887
  # rubber meets the road.
869
- result = await self.run(flow_run, configuration)
870
-
871
- if result.status_code != 0:
872
- await self._propose_crashed_state(
873
- flow_run,
874
- (
875
- "Flow run infrastructure exited with non-zero status code"
876
- f" {result.status_code}."
877
- ),
878
- )
888
+ try:
889
+ await self._initiate_run(flow_run, configuration)
890
+ except NotImplementedError:
891
+ result = await self.run(flow_run, configuration)
892
+
893
+ if result.status_code != 0:
894
+ await self._propose_crashed_state(
895
+ flow_run,
896
+ (
897
+ "Flow run infrastructure exited with non-zero status code"
898
+ f" {result.status_code}."
899
+ ),
900
+ )
879
901
  except Exception as exc:
880
902
  # This flow run was being submitted and did not start successfully
881
903
  logger.exception(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: prefect-client
3
- Version: 3.4.1.dev4
3
+ Version: 3.4.2.dev1
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
@@ -60,6 +60,7 @@ Requires-Dist: sniffio<2.0.0,>=1.3.0
60
60
  Requires-Dist: toml>=0.10.0
61
61
  Requires-Dist: typing-extensions<5.0.0,>=4.10.0
62
62
  Requires-Dist: ujson<6.0.0,>=5.8.0
63
+ Requires-Dist: uuid7>=0.1.0
63
64
  Requires-Dist: uvicorn!=0.29.0,>=0.14.0
64
65
  Requires-Dist: websockets<16.0,>=13.0
65
66
  Requires-Dist: whenever<0.9.0,>=0.7.3; python_version >= '3.13'
@@ -1,7 +1,7 @@
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=QcFtoY6cMGvzPP_9d4qiiLL87zxdwx9Cl4dxKsa7CyA,185
4
+ prefect/_build_info.py,sha256=oEBqFEWr4MAbqSh23R4ZfwEbnn2QVv87z2Tt5eis5VM,185
5
5
  prefect/_result_records.py,sha256=S6QmsODkehGVSzbMm6ig022PYbI6gNKz671p_8kBYx4,7789
6
6
  prefect/_versioning.py,sha256=YqR5cxXrY4P6LM1Pmhd8iMo7v_G2KJpGNdsf4EvDFQ0,14132
7
7
  prefect/_waiters.py,sha256=Ia2ITaXdHzevtyWIgJoOg95lrEXQqNEOquHvw3T33UQ,9026
@@ -25,10 +25,10 @@ prefect/schedules.py,sha256=dhq4OhImRvcmtxF7UH1m8RbwYdHT5RQsp_FrxVXfODE,7289
25
25
  prefect/serializers.py,sha256=QI0oEal_BO4HQaWSjr6ReSwT55Hn4sbSOXxGgQI1-y0,9249
26
26
  prefect/states.py,sha256=rh7l1bnIYpTXdlXt5nnpz66y9KLjBWAJrN9Eo5RwgQs,26023
27
27
  prefect/task_engine.py,sha256=j0rr8IyBinJmKPD-486RYWKZakhifkEE9ppPCJ9Es-U,62463
28
- prefect/task_runners.py,sha256=vzJ1kiW1z90Fkkg21QNhPwjfLoDy6rVsUAToXqb6FUE,16206
28
+ prefect/task_runners.py,sha256=PozMYXXjiy5pMStifjdBTnLRTtP9uRuBa86KgafpPkQ,16243
29
29
  prefect/task_runs.py,sha256=7LIzfo3fondCyEUpU05sYFN5IfpZigBDXrhG5yc-8t0,9039
30
30
  prefect/task_worker.py,sha256=gMj_rl4EjTrnJ5YSOXinC6y-7KSK7fRQt_UYbZbrrV8,17879
31
- prefect/tasks.py,sha256=DODF_1xPDQVvj_paJDWm43RS46Jdx9_7b2huqT_QyiM,74778
31
+ prefect/tasks.py,sha256=b140EJQ72kGBA0jg3O-B_IgEudsfG8j1PcK_I6PJaQQ,74820
32
32
  prefect/transactions.py,sha256=uIoPNudzJzH6NrMJhrgr5lyh6JxOJQqT1GvrXt69yNw,26068
33
33
  prefect/variables.py,sha256=dCK3vX7TbkqXZhnNT_v7rcGh3ISRqoR6pJVLpoll3Js,8342
34
34
  prefect/_experimental/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -43,6 +43,7 @@ prefect/_internal/_logging.py,sha256=Igy2tCM2Hv9wNiDPcee0s5N1fTc6oRP7OffCJBqAekY
43
43
  prefect/_internal/integrations.py,sha256=U4cZMDbnilzZSKaMxvzZcSL27a1tzRMjDoTfr2ul_eY,231
44
44
  prefect/_internal/pytz.py,sha256=Sy_cD-Hkmo_Yrhx2Jucy7DgTRhvO8ZD0whW1ywbSg_U,13765
45
45
  prefect/_internal/retries.py,sha256=pMHofrTQPDSxbVWclDwXbfhFKaDC6sxe1DkUOWugV6k,3040
46
+ prefect/_internal/uuid7.py,sha256=-Wl5rFozDSKRyhSfa9WT8BK1U5Rq8ehEgZB5aV5lodU,211
46
47
  prefect/_internal/compatibility/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
48
  prefect/_internal/compatibility/async_dispatch.py,sha256=cUXOqSeseMUaje9oYUzasVPtNttyiHvrqfJl0zK66XI,2949
48
49
  prefect/_internal/compatibility/deprecated.py,sha256=YUK1IGOgZrDh6dYRez-9IYTB1eqNC19QiSKbBDl88Qs,9305
@@ -63,10 +64,10 @@ prefect/_internal/pydantic/v1_schema.py,sha256=wSyQr3LUbIh0R9LsZ6ItmLnQeAS8dxVMN
63
64
  prefect/_internal/pydantic/v2_schema.py,sha256=n56GUlGSUeNZLpMphHliN5ksryVdE9OQHoVir2hGXoA,3224
64
65
  prefect/_internal/pydantic/v2_validated_func.py,sha256=Ld8OtPFF7Ci-gHHmKhSMizBxzuIBOQ6kuIFNRh0vRVY,3731
65
66
  prefect/_internal/schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
- prefect/_internal/schemas/bases.py,sha256=JqcZazL5Cp2hZ8Hssu8R2SVXRxHfbdRbTqmvwDYSzyk,4291
67
+ prefect/_internal/schemas/bases.py,sha256=wYBIa5f5BwiKid7Rwp90gqxs7mt4qGBURdtv5dgWJxk,4583
67
68
  prefect/_internal/schemas/fields.py,sha256=m4LrFNz8rA9uBhMk9VyQT6FIXmV_EVAW92hdXeSvHbY,837
68
69
  prefect/_internal/schemas/serializers.py,sha256=G_RGHfObjisUiRvd29p-zc6W4bwt5rE1OdR6TXNrRhQ,825
69
- prefect/_internal/schemas/validators.py,sha256=Pe78HTN1TQQbpkLx66smzx2udv5rGxdaqn1ZsR1zlJs,19328
70
+ prefect/_internal/schemas/validators.py,sha256=bOtuOYHWfRo-i6zqkE-wvCMXQ3Yww-itj86QLp3yu3Y,16681
70
71
  prefect/_vendor/croniter/__init__.py,sha256=NUFzdbyPcTQhIOFtzmFM0nbClAvBbKh2mlnTBa6NfHU,523
71
72
  prefect/_vendor/croniter/croniter.py,sha256=eJ2HzStNAYV-vNiLOgDXl4sYWWHOsSA0dgwbkQoguhY,53009
72
73
  prefect/blocks/__init__.py,sha256=D0hB72qMfgqnBB2EMZRxUxlX9yLfkab5zDChOwJZmkY,220
@@ -112,9 +113,9 @@ prefect/client/orchestration/_variables/client.py,sha256=wKBbZBLGgs5feDCil-xxKt3
112
113
  prefect/client/orchestration/_work_pools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
113
114
  prefect/client/orchestration/_work_pools/client.py,sha256=s1DfUQQBgB2sLiVVPhLNTlkueUDE6uFsh4mAzcSA1OE,19881
114
115
  prefect/client/schemas/__init__.py,sha256=InZcDzdeWA2oaV0TlyvoMcyLcbi_aaqU1U9D6Gx-eoU,2747
115
- prefect/client/schemas/actions.py,sha256=EigGRTOwa_aWBMfqiTvNaUO8e78M1kIxorEzp1bigcI,33148
116
+ prefect/client/schemas/actions.py,sha256=E46Mdq7vAq8hhYmMj6zqUF20uAPXZricViZcIYmgEf0,32443
116
117
  prefect/client/schemas/filters.py,sha256=qa--NNZduuSOcL1xw-YMd4FVIKMrDnBwPPY4m5Di0GA,35963
117
- prefect/client/schemas/objects.py,sha256=NevDxRA0TEmM0W01q-FMOHVsW7c76vuwk9puJpFneZE,57850
118
+ prefect/client/schemas/objects.py,sha256=e5CMS6FhuYqTmxXK1U80eH5zEC0YkZ_vS_aJdr0VA5o,57912
118
119
  prefect/client/schemas/responses.py,sha256=Zdcx7jlIaluEa2uYIOE5mK1HsJvWPErRAcaWM20oY_I,17336
119
120
  prefect/client/schemas/schedules.py,sha256=sxLFk0SmFY7X1Y9R9HyGDqOS3U5NINBWTciUU7vTTic,14836
120
121
  prefect/client/schemas/sorting.py,sha256=L-2Mx-igZPtsUoRUguTcG3nIEstMEMPD97NwPM2Ox5s,2579
@@ -149,16 +150,16 @@ prefect/docker/docker_image.py,sha256=bR_pEq5-FDxlwTj8CP_7nwZ_MiGK6KxIi8v7DRjy1K
149
150
  prefect/events/__init__.py,sha256=GtKl2bE--pJduTxelH2xy7SadlLJmmis8WR1EYixhuA,2094
150
151
  prefect/events/actions.py,sha256=A7jS8bo4zWGnrt3QfSoQs0uYC1xfKXio3IfU0XtTb5s,9129
151
152
  prefect/events/clients.py,sha256=e3A6cKxi-fG2TkFedaRuC472hIM3VgaVxI6mcPP41kY,27613
152
- prefect/events/filters.py,sha256=2hVfzc3Rdgy0mBHDutWxT__LJY0zpVM8greWX3y6kjM,8233
153
+ prefect/events/filters.py,sha256=tnAbA4Z0Npem8Jbin-qqe38K_4a-4YdpU-Oc4u8Y95Q,8697
153
154
  prefect/events/related.py,sha256=CTeexYUmmA93V4gsR33GIFmw-SS-X_ouOpRg-oeq-BU,6672
154
155
  prefect/events/utilities.py,sha256=ww34bTMENCNwcp6RhhgzG0KgXOvKGe0MKmBdSJ8NpZY,3043
155
156
  prefect/events/worker.py,sha256=HjbibR0_J1W1nnNMZDFTXAbB0cl_cFGaFI87DvNGcnI,4557
156
157
  prefect/events/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
157
158
  prefect/events/cli/automations.py,sha256=uCX3NnypoI25TmyAoyL6qYhanWjZbJ2watwv1nfQMxs,11513
158
159
  prefect/events/schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
159
- prefect/events/schemas/automations.py,sha256=5uYx18sVf8Mqx-KtfcSGli8x4GkNPUHC8LZZfsDzeBo,14568
160
+ prefect/events/schemas/automations.py,sha256=UHrV572HB5Icb1LuOUkMIdDrMDsxW1GhIiST-qzUlFs,14640
160
161
  prefect/events/schemas/deployment_triggers.py,sha256=OX9g9eHe0nqJ3PtVEzqs9Ub2LaOHMA4afLZSvSukKGU,3191
161
- prefect/events/schemas/events.py,sha256=jqZPBXPEnJUCXbk9OM0geJr94trM7jHrk9yvzt6hTbA,9235
162
+ prefect/events/schemas/events.py,sha256=r8sSx2Q1A0KIofnZR_Bri7YT1wzXKV3YS-LnxpeIXHE,9270
162
163
  prefect/events/schemas/labelling.py,sha256=bU-XYaHXhI2MEBIHngth96R9D02m8HHb85KNcHZ_1Gc,3073
163
164
  prefect/infrastructure/__init__.py,sha256=dPvG1jDGD5HSH7aM2utwtk6RaJ9qg13XjkA0lAIgQmY,287
164
165
  prefect/infrastructure/base.py,sha256=dPvG1jDGD5HSH7aM2utwtk6RaJ9qg13XjkA0lAIgQmY,287
@@ -226,7 +227,7 @@ prefect/server/api/templates.py,sha256=92bLFfcahZUp5PVNTZPjl8uJSDj4ZYRTVdmTzZXkE
226
227
  prefect/server/api/validation.py,sha256=HxSNyH8yb_tI-kOfjXESRjJp6WQK6hYWBJsaBxUvY34,14490
227
228
  prefect/server/api/variables.py,sha256=SJaKuqInfQIEdMlJOemptBDN43KLFhlf_u9QwupDu7A,6185
228
229
  prefect/server/api/work_queues.py,sha256=wBcbmkZDaQ5Ddi9wc8tNs6kYG_FdNtYwTCR0VkhPj2o,7588
229
- prefect/server/api/workers.py,sha256=-y8J9R47zeINvA07wd5P-5PCHjZmJVMm81CdfKMraww,24086
230
+ prefect/server/api/workers.py,sha256=8EVPnGv9wAC3YBWIoUx70OS7zfhRKjoXAAECFWKBMg0,24121
230
231
  prefect/server/api/collections_data/views/aggregate-worker-metadata.json,sha256=f6t13GRkIcLqGYB3OnXluAHEFoSqZM2SQP22vpcu0Mk,79793
231
232
  prefect/server/api/static/prefect-logo-mark-gradient.png,sha256=ylRjJkI_JHCw8VbQasNnXQHwZW-sH-IQiUGSD3aWP1E,73430
232
233
  prefect/server/api/ui/__init__.py,sha256=TCXO4ZUZCqCbm2QoNvWNTErkzWiX2nSACuO-0Tiomvg,93
@@ -276,9 +277,10 @@ prefect/telemetry/logging.py,sha256=ktIVTXbdZ46v6fUhoHNidFrpvpNJR-Pj-hQ4V9b40W4,
276
277
  prefect/telemetry/processors.py,sha256=jw6j6LviOVxw3IBJe7cSjsxFk0zzY43jUmy6C9pcfCE,2272
277
278
  prefect/telemetry/run_telemetry.py,sha256=_FbjiPqPemu4xvZuI2YBPwXeRJ2BcKRJ6qgO4UMzKKE,8571
278
279
  prefect/telemetry/services.py,sha256=DxgNNDTeWNtHBtioX8cjua4IrCbTiJJdYecx-gugg-w,2358
279
- prefect/types/__init__.py,sha256=yBjKxiQmSC7jXoo0UNmM3KZil1NBFS-BWGPfwSEaoJo,4621
280
+ prefect/types/__init__.py,sha256=SwyWpbxSevAKU9lWpfauD61whUP7kksvfx-mtq3UE6E,4288
280
281
  prefect/types/_datetime.py,sha256=ZE-4YK5XJuyxnp5pqldZwtIjkxCpxDGnCSfZiTl7-TU,7566
281
282
  prefect/types/entrypoint.py,sha256=2FF03-wLPgtnqR_bKJDB2BsXXINPdu8ptY9ZYEZnXg8,328
283
+ prefect/types/names.py,sha256=CMMZD928iiod2UvB0qrsfXEBC5jj_bO0ge1fFXcrtgM,3450
282
284
  prefect/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
283
285
  prefect/utilities/_ast.py,sha256=sgEPUWElih-3cp4PoAy1IOyPtu8E27lL0Dldf3ijnYY,4905
284
286
  prefect/utilities/_deprecated.py,sha256=b3pqRSoFANdVJAc8TJkygBcP-VjZtLJUxVIWC7kwspI,1303
@@ -313,13 +315,13 @@ prefect/utilities/schema_tools/__init__.py,sha256=At3rMHd2g_Em2P3_dFQlFgqR_EpBwr
313
315
  prefect/utilities/schema_tools/hydration.py,sha256=NkRhWkNfxxFmVGhNDfmxdK_xeKaEhs3a42q83Sg9cT4,9436
314
316
  prefect/utilities/schema_tools/validation.py,sha256=Wix26IVR-ZJ32-6MX2pHhrwm3reB-Q4iB6_phn85OKE,10743
315
317
  prefect/workers/__init__.py,sha256=EaM1F0RZ-XIJaGeTKLsXDnfOPHzVWk5bk0_c4BVS44M,64
316
- prefect/workers/base.py,sha256=gqXHTFFhjIzCZoBh4FDlA8AAm4l2j6GW6wS7Q7Hbb20,61504
318
+ prefect/workers/base.py,sha256=_Puzm_f2Q7YLI89G_u9oM3esvwUWIKZ3fpfPqi-KMQk,62358
317
319
  prefect/workers/block.py,sha256=dPvG1jDGD5HSH7aM2utwtk6RaJ9qg13XjkA0lAIgQmY,287
318
320
  prefect/workers/cloud.py,sha256=dPvG1jDGD5HSH7aM2utwtk6RaJ9qg13XjkA0lAIgQmY,287
319
321
  prefect/workers/process.py,sha256=Yi5D0U5AQ51wHT86GdwtImXSefe0gJf3LGq4r4z9zwM,11090
320
322
  prefect/workers/server.py,sha256=2pmVeJZiVbEK02SO6BEZaBIvHMsn6G8LzjW8BXyiTtk,1952
321
323
  prefect/workers/utilities.py,sha256=VfPfAlGtTuDj0-Kb8WlMgAuOfgXCdrGAnKMapPSBrwc,2483
322
- prefect_client-3.4.1.dev4.dist-info/METADATA,sha256=MGFEKoWTbDHQ_jlNcHTQ1oKdHbzNWuRs2tn0ETq9ZyU,7471
323
- prefect_client-3.4.1.dev4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
324
- prefect_client-3.4.1.dev4.dist-info/licenses/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
325
- prefect_client-3.4.1.dev4.dist-info/RECORD,,
324
+ prefect_client-3.4.2.dev1.dist-info/METADATA,sha256=ZCG3razh5vFcIxm1RVw6hjjhjZIgKCGjQZyVhHstS8c,7499
325
+ prefect_client-3.4.2.dev1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
326
+ prefect_client-3.4.2.dev1.dist-info/licenses/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
327
+ prefect_client-3.4.2.dev1.dist-info/RECORD,,