prefect-client 3.1.9__py3-none-any.whl → 3.1.10__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/_version.py CHANGED
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2024-12-20T16:33:15-0500",
11
+ "date": "2024-12-24T22:58:40-0800",
12
12
  "dirty": true,
13
13
  "error": null,
14
- "full-revisionid": "e1fe79439b319ce5478aa5f8bd4e836ed4f8a0f5",
15
- "version": "3.1.9"
14
+ "full-revisionid": "b11b56fc6143df2bd4c7018f7a974dc656fe9aa3",
15
+ "version": "3.1.10"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
prefect/artifacts.py CHANGED
@@ -2,19 +2,20 @@
2
2
  Interface for creating and reading artifacts.
3
3
  """
4
4
 
5
- from __future__ import annotations
6
-
5
+ import asyncio
7
6
  import json # noqa: I001
8
7
  import math
9
8
  import warnings
10
- from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union
9
+ from typing import TYPE_CHECKING, Any, Optional, Union
11
10
  from uuid import UUID
12
11
 
12
+ from typing_extensions import Self
13
+
13
14
  from prefect.client.schemas.actions import ArtifactCreate as ArtifactRequest
14
15
  from prefect.client.schemas.actions import ArtifactUpdate
15
16
  from prefect.client.schemas.filters import ArtifactFilter, ArtifactFilterKey
16
17
  from prefect.client.schemas.sorting import ArtifactSort
17
- from prefect.client.utilities import get_or_create_client, inject_client
18
+ from prefect.client.utilities import get_or_create_client
18
19
  from prefect.logging.loggers import get_logger
19
20
  from prefect.utilities.asyncutils import sync_compatible
20
21
  from prefect.utilities.context import get_task_and_flow_run_ids
@@ -22,8 +23,6 @@ from prefect.utilities.context import get_task_and_flow_run_ids
22
23
  logger = get_logger("artifacts")
23
24
 
24
25
  if TYPE_CHECKING:
25
- from typing_extensions import Self
26
-
27
26
  from prefect.client.orchestration import PrefectClient
28
27
  from prefect.client.schemas.objects import Artifact as ArtifactResponse
29
28
 
@@ -43,7 +42,7 @@ class Artifact(ArtifactRequest):
43
42
 
44
43
  @sync_compatible
45
44
  async def create(
46
- self: "Self",
45
+ self: Self,
47
46
  client: Optional["PrefectClient"] = None,
48
47
  ) -> "ArtifactResponse":
49
48
  """
@@ -95,16 +94,15 @@ class Artifact(ArtifactRequest):
95
94
  (ArtifactResponse, optional): The artifact (if found).
96
95
  """
97
96
  client, _ = get_or_create_client(client)
98
- return next(
99
- iter(
100
- await client.read_artifacts(
101
- limit=1,
102
- sort=ArtifactSort.UPDATED_DESC,
103
- artifact_filter=ArtifactFilter(key=ArtifactFilterKey(any_=[key])),
104
- )
97
+ filter_key_value = None if key is None else [key]
98
+ artifacts = await client.read_artifacts(
99
+ limit=1,
100
+ sort=ArtifactSort.UPDATED_DESC,
101
+ artifact_filter=ArtifactFilter(
102
+ key=ArtifactFilterKey(any_=filter_key_value)
105
103
  ),
106
- None,
107
104
  )
105
+ return None if not artifacts else artifacts[0]
108
106
 
109
107
  @classmethod
110
108
  @sync_compatible
@@ -112,10 +110,10 @@ class Artifact(ArtifactRequest):
112
110
  cls,
113
111
  key: Optional[str] = None,
114
112
  description: Optional[str] = None,
115
- data: Optional[Union[Dict[str, Any], Any]] = None,
113
+ data: Optional[Union[dict[str, Any], Any]] = None,
116
114
  client: Optional["PrefectClient"] = None,
117
115
  **kwargs: Any,
118
- ) -> Tuple["ArtifactResponse", bool]:
116
+ ) -> tuple["ArtifactResponse", bool]:
119
117
  """
120
118
  A method to get or create an artifact.
121
119
 
@@ -128,18 +126,20 @@ class Artifact(ArtifactRequest):
128
126
  Returns:
129
127
  (ArtifactResponse): The artifact, either retrieved or created.
130
128
  """
131
- artifact = await cls.get(key, client)
129
+ artifact_coro = cls.get(key, client)
130
+ if TYPE_CHECKING:
131
+ assert asyncio.iscoroutine(artifact_coro)
132
+ artifact = await artifact_coro
132
133
  if artifact:
133
134
  return artifact, False
134
- else:
135
- return (
136
- await cls(key=key, description=description, data=data, **kwargs).create(
137
- client
138
- ),
139
- True,
140
- )
141
135
 
142
- async def format(self) -> Optional[Union[Dict[str, Any], Any]]:
136
+ new_artifact = cls(key=key, description=description, data=data, **kwargs)
137
+ create_coro = new_artifact.create(client)
138
+ if TYPE_CHECKING:
139
+ assert asyncio.iscoroutine(create_coro)
140
+ return await create_coro, True
141
+
142
+ async def format(self) -> Optional[Union[dict[str, Any], Any]]:
143
143
  return json.dumps(self.data)
144
144
 
145
145
 
@@ -165,13 +165,13 @@ class MarkdownArtifact(Artifact):
165
165
 
166
166
 
167
167
  class TableArtifact(Artifact):
168
- table: Union[Dict[str, List[Any]], List[Dict[str, Any]], List[List[Any]]]
168
+ table: Union[dict[str, list[Any]], list[dict[str, Any]], list[list[Any]]]
169
169
  type: Optional[str] = "table"
170
170
 
171
171
  @classmethod
172
172
  def _sanitize(
173
- cls, item: Union[Dict[str, Any], List[Any], float]
174
- ) -> Union[Dict[str, Any], List[Any], int, float, None]:
173
+ cls, item: Union[dict[str, Any], list[Any], float]
174
+ ) -> Union[dict[str, Any], list[Any], int, float, None]:
175
175
  """
176
176
  Sanitize NaN values in a given item.
177
177
  The item can be a dict, list or float.
@@ -230,39 +230,6 @@ class ImageArtifact(Artifact):
230
230
  return self.image_url
231
231
 
232
232
 
233
- @inject_client
234
- async def _create_artifact(
235
- type: str,
236
- key: Optional[str] = None,
237
- description: Optional[str] = None,
238
- data: Optional[Union[Dict[str, Any], Any]] = None,
239
- client: Optional["PrefectClient"] = None,
240
- ) -> UUID:
241
- """
242
- Helper function to create an artifact.
243
-
244
- Arguments:
245
- type: A string identifying the type of artifact.
246
- key: A user-provided string identifier.
247
- The key must only contain lowercase letters, numbers, and dashes.
248
- description: A user-specified description of the artifact.
249
- data: A JSON payload that allows for a result to be retrieved.
250
- client: The PrefectClient
251
-
252
- Returns:
253
- - The table artifact ID.
254
- """
255
-
256
- artifact = await Artifact(
257
- type=type,
258
- key=key,
259
- description=description,
260
- data=data,
261
- ).create(client)
262
-
263
- return artifact.id
264
-
265
-
266
233
  @sync_compatible
267
234
  async def create_link_artifact(
268
235
  link: str,
@@ -286,12 +253,16 @@ async def create_link_artifact(
286
253
  Returns:
287
254
  The table artifact ID.
288
255
  """
289
- artifact = await LinkArtifact(
256
+ new_artifact = LinkArtifact(
290
257
  key=key,
291
258
  description=description,
292
259
  link=link,
293
260
  link_text=link_text,
294
- ).create(client)
261
+ )
262
+ create_coro = new_artifact.create(client)
263
+ if TYPE_CHECKING:
264
+ assert asyncio.iscoroutine(create_coro)
265
+ artifact = await create_coro
295
266
 
296
267
  return artifact.id
297
268
 
@@ -315,18 +286,22 @@ async def create_markdown_artifact(
315
286
  Returns:
316
287
  The table artifact ID.
317
288
  """
318
- artifact = await MarkdownArtifact(
289
+ new_artifact = MarkdownArtifact(
319
290
  key=key,
320
291
  description=description,
321
292
  markdown=markdown,
322
- ).create()
293
+ )
294
+ create_coro = new_artifact.create()
295
+ if TYPE_CHECKING:
296
+ assert asyncio.iscoroutine(create_coro)
297
+ artifact = await create_coro
323
298
 
324
299
  return artifact.id
325
300
 
326
301
 
327
302
  @sync_compatible
328
303
  async def create_table_artifact(
329
- table: Union[Dict[str, List[Any]], List[Dict[str, Any]], List[List[Any]]],
304
+ table: Union[dict[str, list[Any]], list[dict[str, Any]], list[list[Any]]],
330
305
  key: Optional[str] = None,
331
306
  description: Optional[str] = None,
332
307
  ) -> UUID:
@@ -344,11 +319,15 @@ async def create_table_artifact(
344
319
  The table artifact ID.
345
320
  """
346
321
 
347
- artifact = await TableArtifact(
322
+ new_artifact = TableArtifact(
348
323
  key=key,
349
324
  description=description,
350
325
  table=table,
351
- ).create()
326
+ )
327
+ create_coro = new_artifact.create()
328
+ if TYPE_CHECKING:
329
+ assert asyncio.iscoroutine(create_coro)
330
+ artifact = await create_coro
352
331
 
353
332
  return artifact.id
354
333
 
@@ -373,11 +352,15 @@ async def create_progress_artifact(
373
352
  The progress artifact ID.
374
353
  """
375
354
 
376
- artifact = await ProgressArtifact(
355
+ new_artifact = ProgressArtifact(
377
356
  key=key,
378
357
  description=description,
379
358
  progress=progress,
380
- ).create()
359
+ )
360
+ create_coro = new_artifact.create()
361
+ if TYPE_CHECKING:
362
+ assert asyncio.iscoroutine(create_coro)
363
+ artifact = await create_coro
381
364
 
382
365
  return artifact.id
383
366
 
@@ -387,7 +370,7 @@ async def update_progress_artifact(
387
370
  artifact_id: UUID,
388
371
  progress: float,
389
372
  description: Optional[str] = None,
390
- client: Optional[PrefectClient] = None,
373
+ client: Optional["PrefectClient"] = None,
391
374
  ) -> UUID:
392
375
  """
393
376
  Update a progress artifact.
@@ -444,10 +427,14 @@ async def create_image_artifact(
444
427
  The image artifact ID.
445
428
  """
446
429
 
447
- artifact = await ImageArtifact(
430
+ new_artifact = ImageArtifact(
448
431
  key=key,
449
432
  description=description,
450
433
  image_url=image_url,
451
- ).create()
434
+ )
435
+ create_coro = new_artifact.create()
436
+ if TYPE_CHECKING:
437
+ assert asyncio.iscoroutine(create_coro)
438
+ artifact = await create_coro
452
439
 
453
440
  return artifact.id
prefect/automations.py CHANGED
@@ -1,4 +1,4 @@
1
- from typing import Optional, Type
1
+ from typing import TYPE_CHECKING, Optional, overload
2
2
  from uuid import UUID
3
3
 
4
4
  from pydantic import Field
@@ -112,17 +112,28 @@ class Automation(AutomationCore):
112
112
  auto.name = "new name"
113
113
  auto.update()
114
114
  """
115
+ assert self.id is not None
115
116
  async with get_client() as client:
116
117
  automation = AutomationCore(
117
118
  **self.model_dump(exclude={"id", "owner_resource"})
118
119
  )
119
120
  await client.update_automation(automation_id=self.id, automation=automation)
120
121
 
122
+ @overload
123
+ @classmethod
124
+ async def read(cls, id: UUID, name: Optional[str] = ...) -> Self:
125
+ ...
126
+
127
+ @overload
128
+ @classmethod
129
+ async def read(cls, id: None = None, name: str = ...) -> Optional[Self]:
130
+ ...
131
+
121
132
  @classmethod
122
133
  @sync_compatible
123
134
  async def read(
124
- cls: Type[Self], id: Optional[UUID] = None, name: Optional[str] = None
125
- ) -> Self:
135
+ cls, id: Optional[UUID] = None, name: Optional[str] = None
136
+ ) -> Optional[Self]:
126
137
  """
127
138
  Read an automation by ID or name.
128
139
  automation = Automation.read(name="woodchonk")
@@ -145,13 +156,13 @@ class Automation(AutomationCore):
145
156
  raise
146
157
  if automation is None:
147
158
  raise ValueError(f"Automation with ID {id!r} not found")
148
- return Automation(**automation.model_dump())
159
+ return cls(**automation.model_dump())
149
160
  else:
161
+ if TYPE_CHECKING:
162
+ assert name is not None
150
163
  automation = await client.read_automations_by_name(name=name)
151
164
  if len(automation) > 0:
152
- return (
153
- Automation(**automation[0].model_dump()) if automation else None
154
- )
165
+ return cls(**automation[0].model_dump()) if automation else None
155
166
  else:
156
167
  raise ValueError(f"Automation with name {name!r} not found")
157
168
 
@@ -161,6 +172,9 @@ class Automation(AutomationCore):
161
172
  auto = Automation.read(id = 123)
162
173
  auto.delete()
163
174
  """
175
+ if self.id is None:
176
+ raise ValueError("Can't delete an automation without an id")
177
+
164
178
  async with get_client() as client:
165
179
  try:
166
180
  await client.delete_automation(self.id)
@@ -177,6 +191,9 @@ class Automation(AutomationCore):
177
191
  auto = Automation.read(id = 123)
178
192
  auto.disable()
179
193
  """
194
+ if self.id is None:
195
+ raise ValueError("Can't disable an automation without an id")
196
+
180
197
  async with get_client() as client:
181
198
  try:
182
199
  await client.pause_automation(self.id)
@@ -193,6 +210,9 @@ class Automation(AutomationCore):
193
210
  auto = Automation.read(id = 123)
194
211
  auto.enable()
195
212
  """
213
+ if self.id is None:
214
+ raise ValueError("Can't enable an automation without an id")
215
+
196
216
  async with get_client() as client:
197
217
  try:
198
218
  await client.resume_automation(self.id)
prefect/context.py CHANGED
@@ -9,21 +9,10 @@ For more user-accessible information about the current run, see [`prefect.runtim
9
9
  import os
10
10
  import sys
11
11
  import warnings
12
+ from collections.abc import AsyncGenerator, Generator, Mapping
12
13
  from contextlib import ExitStack, asynccontextmanager, contextmanager
13
14
  from contextvars import ContextVar, Token
14
- from typing import (
15
- TYPE_CHECKING,
16
- Any,
17
- AsyncGenerator,
18
- Dict,
19
- Generator,
20
- Mapping,
21
- Optional,
22
- Set,
23
- Type,
24
- TypeVar,
25
- Union,
26
- )
15
+ from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union
27
16
 
28
17
  from pydantic import BaseModel, ConfigDict, Field, PrivateAttr
29
18
  from typing_extensions import Self
@@ -64,7 +53,7 @@ if TYPE_CHECKING:
64
53
  GLOBAL_SETTINGS_CONTEXT = None # type: ignore
65
54
 
66
55
 
67
- def serialize_context() -> Dict[str, Any]:
56
+ def serialize_context() -> dict[str, Any]:
68
57
  """
69
58
  Serialize the current context for use in a remote execution environment.
70
59
  """
@@ -84,7 +73,7 @@ def serialize_context() -> Dict[str, Any]:
84
73
 
85
74
  @contextmanager
86
75
  def hydrated_context(
87
- serialized_context: Optional[Dict[str, Any]] = None,
76
+ serialized_context: Optional[dict[str, Any]] = None,
88
77
  client: Union[PrefectClient, SyncPrefectClient, None] = None,
89
78
  ):
90
79
  with ExitStack() as stack:
@@ -148,7 +137,7 @@ class ContextModel(BaseModel):
148
137
  self._token = None
149
138
 
150
139
  @classmethod
151
- def get(cls: Type[Self]) -> Optional[Self]:
140
+ def get(cls: type[Self]) -> Optional[Self]:
152
141
  """Get the current context instance"""
153
142
  return cls.__var__.get(None)
154
143
 
@@ -173,7 +162,7 @@ class ContextModel(BaseModel):
173
162
  new._token = None
174
163
  return new
175
164
 
176
- def serialize(self, include_secrets: bool = True) -> Dict[str, Any]:
165
+ def serialize(self, include_secrets: bool = True) -> dict[str, Any]:
177
166
  """
178
167
  Serialize the context model to a dictionary that can be pickled with cloudpickle.
179
168
  """
@@ -314,10 +303,10 @@ class RunContext(ContextModel):
314
303
  start_client_metrics_server()
315
304
 
316
305
  start_time: DateTime = Field(default_factory=lambda: DateTime.now("UTC"))
317
- input_keyset: Optional[Dict[str, Dict[str, str]]] = None
306
+ input_keyset: Optional[dict[str, dict[str, str]]] = None
318
307
  client: Union[PrefectClient, SyncPrefectClient]
319
308
 
320
- def serialize(self: Self, include_secrets: bool = True) -> Dict[str, Any]:
309
+ def serialize(self: Self, include_secrets: bool = True) -> dict[str, Any]:
321
310
  return self.model_dump(
322
311
  include={"start_time", "input_keyset"},
323
312
  exclude_unset=True,
@@ -344,7 +333,7 @@ class EngineContext(RunContext):
344
333
  flow_run: Optional[FlowRun] = None
345
334
  task_runner: TaskRunner[Any]
346
335
  log_prints: bool = False
347
- parameters: Optional[Dict[str, Any]] = None
336
+ parameters: Optional[dict[str, Any]] = None
348
337
 
349
338
  # Flag signaling if the flow run context has been serialized and sent
350
339
  # to remote infrastructure.
@@ -355,10 +344,10 @@ class EngineContext(RunContext):
355
344
  persist_result: bool = Field(default_factory=get_default_persist_setting)
356
345
 
357
346
  # Counter for task calls allowing unique
358
- task_run_dynamic_keys: Dict[str, Union[str, int]] = Field(default_factory=dict)
347
+ task_run_dynamic_keys: dict[str, Union[str, int]] = Field(default_factory=dict)
359
348
 
360
349
  # Counter for flow pauses
361
- observed_flow_pauses: Dict[str, int] = Field(default_factory=dict)
350
+ observed_flow_pauses: dict[str, int] = Field(default_factory=dict)
362
351
 
363
352
  # Tracking for result from task runs in this flow run for dependency tracking
364
353
  # Holds the ID of the object returned by the task run and task run state
@@ -369,7 +358,7 @@ class EngineContext(RunContext):
369
358
 
370
359
  __var__: ContextVar[Self] = ContextVar("flow_run")
371
360
 
372
- def serialize(self: Self, include_secrets: bool = True) -> Dict[str, Any]:
361
+ def serialize(self: Self, include_secrets: bool = True) -> dict[str, Any]:
373
362
  return self.model_dump(
374
363
  include={
375
364
  "flow_run",
@@ -403,7 +392,7 @@ class TaskRunContext(RunContext):
403
392
  task: "Task[Any, Any]"
404
393
  task_run: TaskRun
405
394
  log_prints: bool = False
406
- parameters: Dict[str, Any]
395
+ parameters: dict[str, Any]
407
396
 
408
397
  # Result handling
409
398
  result_store: ResultStore
@@ -411,7 +400,7 @@ class TaskRunContext(RunContext):
411
400
 
412
401
  __var__ = ContextVar("task_run")
413
402
 
414
- def serialize(self: Self, include_secrets: bool = True) -> Dict[str, Any]:
403
+ def serialize(self: Self, include_secrets: bool = True) -> dict[str, Any]:
415
404
  return self.model_dump(
416
405
  include={
417
406
  "task_run",
@@ -437,7 +426,7 @@ class TagsContext(ContextModel):
437
426
  current_tags: A set of current tags in the context
438
427
  """
439
428
 
440
- current_tags: Set[str] = Field(default_factory=set)
429
+ current_tags: set[str] = Field(default_factory=set)
441
430
 
442
431
  @classmethod
443
432
  def get(cls) -> "TagsContext":
@@ -512,7 +501,7 @@ def get_settings_context() -> SettingsContext:
512
501
 
513
502
 
514
503
  @contextmanager
515
- def tags(*new_tags: str) -> Generator[Set[str], None, None]:
504
+ def tags(*new_tags: str) -> Generator[set[str], None, None]:
516
505
  """
517
506
  Context manager to add tags to flow and task run calls.
518
507
 
prefect/flows.py CHANGED
@@ -37,7 +37,6 @@ from typing import (
37
37
  from uuid import UUID
38
38
 
39
39
  import pydantic
40
- from fastapi.encoders import jsonable_encoder
41
40
  from pydantic.v1 import BaseModel as V1BaseModel
42
41
  from pydantic.v1.decorator import ValidatedFunction as V1ValidatedFunction
43
42
  from pydantic.v1.errors import ConfigError # TODO
@@ -613,6 +612,8 @@ class Flow(Generic[P, R]):
613
612
  serialized_parameters[key] = f"<{type(value).__name__}>"
614
613
  continue
615
614
  try:
615
+ from fastapi.encoders import jsonable_encoder
616
+
616
617
  serialized_parameters[key] = jsonable_encoder(value)
617
618
  except (TypeError, ValueError):
618
619
  logger.debug(
prefect/futures.py CHANGED
@@ -1,17 +1,15 @@
1
1
  import abc
2
2
  import asyncio
3
- import collections
4
3
  import concurrent.futures
5
4
  import threading
6
5
  import uuid
7
6
  from collections.abc import Generator, Iterator
8
7
  from functools import partial
9
- from typing import Any, Callable, Generic, List, Optional, Set, Union, cast
8
+ from typing import Any, Callable, Generic, Optional, Union
10
9
 
11
- from typing_extensions import TypeVar
10
+ from typing_extensions import NamedTuple, Self, TypeVar
12
11
 
13
12
  from prefect.client.orchestration import get_client
14
- from prefect.client.schemas.objects import TaskRun
15
13
  from prefect.exceptions import ObjectNotFound
16
14
  from prefect.logging.loggers import get_logger, get_run_logger
17
15
  from prefect.states import Pending, State
@@ -50,7 +48,7 @@ class PrefectFuture(abc.ABC, Generic[R]):
50
48
  return self._final_state
51
49
  client = get_client(sync_client=True)
52
50
  try:
53
- task_run = cast(TaskRun, client.read_task_run(task_run_id=self.task_run_id))
51
+ task_run = client.read_task_run(task_run_id=self.task_run_id)
54
52
  except ObjectNotFound:
55
53
  # We'll be optimistic and assume this task will eventually start
56
54
  # TODO: Consider using task run events to wait for the task to start
@@ -92,7 +90,7 @@ class PrefectFuture(abc.ABC, Generic[R]):
92
90
  """
93
91
 
94
92
  @abc.abstractmethod
95
- def add_done_callback(self, fn):
93
+ def add_done_callback(self, fn: Callable[["PrefectFuture[R]"], None]):
96
94
  """
97
95
  Add a callback to be run when the future completes or is cancelled.
98
96
 
@@ -102,13 +100,17 @@ class PrefectFuture(abc.ABC, Generic[R]):
102
100
  ...
103
101
 
104
102
 
105
- class PrefectWrappedFuture(PrefectFuture, abc.ABC, Generic[R, F]):
103
+ class PrefectWrappedFuture(PrefectFuture[R], abc.ABC, Generic[R, F]):
106
104
  """
107
105
  A Prefect future that wraps another future object.
106
+
107
+ Type Parameters:
108
+ R: The return type of the future
109
+ F: The type of the wrapped future
108
110
  """
109
111
 
110
112
  def __init__(self, task_run_id: uuid.UUID, wrapped_future: F):
111
- self._wrapped_future = wrapped_future
113
+ self._wrapped_future: F = wrapped_future
112
114
  super().__init__(task_run_id)
113
115
 
114
116
  @property
@@ -116,10 +118,11 @@ class PrefectWrappedFuture(PrefectFuture, abc.ABC, Generic[R, F]):
116
118
  """The underlying future object wrapped by this Prefect future"""
117
119
  return self._wrapped_future
118
120
 
119
- def add_done_callback(self, fn: Callable[[PrefectFuture[R]], None]):
121
+ def add_done_callback(self, fn: Callable[[PrefectFuture[R]], None]) -> None:
122
+ """Add a callback to be executed when the future completes."""
120
123
  if not self._final_state:
121
124
 
122
- def call_with_self(future):
125
+ def call_with_self(future: F):
123
126
  """Call the callback with self as the argument, this is necessary to ensure we remove the future from the pending set"""
124
127
  fn(self)
125
128
 
@@ -128,7 +131,7 @@ class PrefectWrappedFuture(PrefectFuture, abc.ABC, Generic[R, F]):
128
131
  fn(self)
129
132
 
130
133
 
131
- class PrefectConcurrentFuture(PrefectWrappedFuture[R, concurrent.futures.Future]):
134
+ class PrefectConcurrentFuture(PrefectWrappedFuture[R, concurrent.futures.Future[R]]):
132
135
  """
133
136
  A Prefect future that wraps a concurrent.futures.Future. This future is used
134
137
  when the task run is submitted to a ThreadPoolExecutor.
@@ -193,7 +196,7 @@ class PrefectDistributedFuture(PrefectFuture[R]):
193
196
  any task run scheduled in Prefect's API.
194
197
  """
195
198
 
196
- done_callbacks: List[Callable[[PrefectFuture[R]], None]] = []
199
+ done_callbacks: list[Callable[[PrefectFuture[R]], None]] = []
197
200
  waiter = None
198
201
 
199
202
  def wait(self, timeout: Optional[float] = None) -> None:
@@ -270,7 +273,7 @@ class PrefectDistributedFuture(PrefectFuture[R]):
270
273
  return
271
274
  TaskRunWaiter.add_done_callback(self._task_run_id, partial(fn, self))
272
275
 
273
- def __eq__(self, other):
276
+ def __eq__(self, other: Any) -> bool:
274
277
  if not isinstance(other, PrefectDistributedFuture):
275
278
  return False
276
279
  return self.task_run_id == other.task_run_id
@@ -279,7 +282,7 @@ class PrefectDistributedFuture(PrefectFuture[R]):
279
282
  return hash(self.task_run_id)
280
283
 
281
284
 
282
- class PrefectFutureList(list, Iterator, Generic[F]):
285
+ class PrefectFutureList(list[PrefectFuture[R]], Iterator[PrefectFuture[R]]):
283
286
  """
284
287
  A list of Prefect futures.
285
288
 
@@ -298,10 +301,10 @@ class PrefectFutureList(list, Iterator, Generic[F]):
298
301
  wait(self, timeout=timeout)
299
302
 
300
303
  def result(
301
- self: "PrefectFutureList[R]",
304
+ self: Self,
302
305
  timeout: Optional[float] = None,
303
306
  raise_on_failure: bool = True,
304
- ) -> List[R]:
307
+ ) -> list[R]:
305
308
  """
306
309
  Get the results of all task runs associated with the futures in the list.
307
310
 
@@ -331,21 +334,22 @@ class PrefectFutureList(list, Iterator, Generic[F]):
331
334
 
332
335
 
333
336
  def as_completed(
334
- futures: List[PrefectFuture[R]], timeout: Optional[float] = None
337
+ futures: list[PrefectFuture[R]], timeout: Optional[float] = None
335
338
  ) -> Generator[PrefectFuture[R], None]:
336
- unique_futures: Set[PrefectFuture[R]] = set(futures)
339
+ unique_futures: set[PrefectFuture[R]] = set(futures)
337
340
  total_futures = len(unique_futures)
341
+ pending = unique_futures
338
342
  try:
339
343
  with timeout_context(timeout):
340
- done = {f for f in unique_futures if f._final_state}
344
+ done = {f for f in unique_futures if f._final_state} # type: ignore[privateUsage]
341
345
  pending = unique_futures - done
342
346
  yield from done
343
347
 
344
348
  finished_event = threading.Event()
345
349
  finished_lock = threading.Lock()
346
- finished_futures = []
350
+ finished_futures: list[PrefectFuture[R]] = []
347
351
 
348
- def add_to_done(future):
352
+ def add_to_done(future: PrefectFuture[R]):
349
353
  with finished_lock:
350
354
  finished_futures.append(future)
351
355
  finished_event.set()
@@ -370,10 +374,19 @@ def as_completed(
370
374
  )
371
375
 
372
376
 
373
- DoneAndNotDoneFutures = collections.namedtuple("DoneAndNotDoneFutures", "done not_done")
377
+ class DoneAndNotDoneFutures(NamedTuple, Generic[R]):
378
+ """A named 2-tuple of sets.
379
+
380
+ multiple inheritance supported in 3.11+, use typing_extensions.NamedTuple
381
+ """
382
+
383
+ done: set[PrefectFuture[R]]
384
+ not_done: set[PrefectFuture[R]]
374
385
 
375
386
 
376
- def wait(futures: List[PrefectFuture[R]], timeout=None) -> DoneAndNotDoneFutures:
387
+ def wait(
388
+ futures: list[PrefectFuture[R]], timeout: Optional[float] = None
389
+ ) -> DoneAndNotDoneFutures[R]:
377
390
  """
378
391
  Wait for the futures in the given sequence to complete.
379
392
 
@@ -431,9 +444,11 @@ def resolve_futures_to_states(
431
444
 
432
445
  Unsupported object types will be returned without modification.
433
446
  """
434
- futures: Set[PrefectFuture[R]] = set()
447
+ futures: set[PrefectFuture[R]] = set()
435
448
 
436
- def _collect_futures(futures, expr, context):
449
+ def _collect_futures(
450
+ futures: set[PrefectFuture[R]], expr: Any, context: Any
451
+ ) -> Union[PrefectFuture[R], Any]:
437
452
  # Expressions inside quotes should not be traversed
438
453
  if isinstance(context.get("annotation"), quote):
439
454
  raise StopVisiting()
@@ -455,14 +470,14 @@ def resolve_futures_to_states(
455
470
  return expr
456
471
 
457
472
  # Get final states for each future
458
- states = []
473
+ states: list[State] = []
459
474
  for future in futures:
460
475
  future.wait()
461
476
  states.append(future.state)
462
477
 
463
478
  states_by_future = dict(zip(futures, states))
464
479
 
465
- def replace_futures_with_states(expr, context):
480
+ def replace_futures_with_states(expr: Any, context: Any) -> Any:
466
481
  # Expressions inside quotes should not be modified
467
482
  if isinstance(context.get("annotation"), quote):
468
483
  raise StopVisiting()
@@ -1,6 +1,7 @@
1
1
  import time
2
+ from logging import Logger
2
3
  from pathlib import Path
3
- from typing import Dict, Optional
4
+ from typing import Optional
4
5
 
5
6
  import anyio
6
7
  import pendulum
@@ -11,7 +12,7 @@ from prefect.logging.loggers import get_logger
11
12
 
12
13
  from .protocol import LockManager
13
14
 
14
- logger = get_logger(__name__)
15
+ logger: Logger = get_logger(__name__)
15
16
 
16
17
 
17
18
  class _LockInfo(TypedDict):
@@ -37,11 +38,11 @@ class FileSystemLockManager(LockManager):
37
38
  lock_files_directory: the directory where lock files are stored
38
39
  """
39
40
 
40
- def __init__(self, lock_files_directory: Path):
41
- self.lock_files_directory = lock_files_directory.expanduser().resolve()
42
- self._locks: Dict[str, _LockInfo] = {}
41
+ def __init__(self, lock_files_directory: Path) -> None:
42
+ self.lock_files_directory: Path = lock_files_directory.expanduser().resolve()
43
+ self._locks: dict[str, _LockInfo] = {}
43
44
 
44
- def _ensure_lock_files_directory_exists(self):
45
+ def _ensure_lock_files_directory_exists(self) -> None:
45
46
  self.lock_files_directory.mkdir(parents=True, exist_ok=True)
46
47
 
47
48
  def _lock_path_for_key(self, key: str) -> Path:
@@ -49,7 +50,7 @@ class FileSystemLockManager(LockManager):
49
50
  return lock_info["path"]
50
51
  return self.lock_files_directory.joinpath(key).with_suffix(".lock")
51
52
 
52
- def _get_lock_info(self, key: str, use_cache=True) -> Optional[_LockInfo]:
53
+ def _get_lock_info(self, key: str, use_cache: bool = True) -> Optional[_LockInfo]:
53
54
  if use_cache:
54
55
  if (lock_info := self._locks.get(key)) is not None:
55
56
  return lock_info
prefect/locking/memory.py CHANGED
@@ -1,6 +1,8 @@
1
1
  import asyncio
2
2
  import threading
3
- from typing import Dict, Optional, TypedDict
3
+ from typing import Any, Optional, TypedDict
4
+
5
+ from typing_extensions import Self
4
6
 
5
7
  from .protocol import LockManager
6
8
 
@@ -30,14 +32,14 @@ class MemoryLockManager(LockManager):
30
32
 
31
33
  _instance = None
32
34
 
33
- def __new__(cls, *args, **kwargs):
35
+ def __new__(cls, *args: Any, **kwargs: Any) -> Self:
34
36
  if cls._instance is None:
35
37
  cls._instance = super().__new__(cls)
36
38
  return cls._instance
37
39
 
38
40
  def __init__(self):
39
41
  self._locks_dict_lock = threading.Lock()
40
- self._locks: Dict[str, _LockInfo] = {}
42
+ self._locks: dict[str, _LockInfo] = {}
41
43
 
42
44
  def _expire_lock(self, key: str):
43
45
  """
@@ -57,7 +57,7 @@ class LockManager(Protocol):
57
57
  """
58
58
  ...
59
59
 
60
- def release_lock(self, key: str, holder: str):
60
+ def release_lock(self, key: str, holder: str) -> None:
61
61
  """
62
62
  Releases the lock on the corresponding transaction record.
63
63
 
prefect/plugins.py CHANGED
@@ -9,15 +9,15 @@ Currently supported entrypoints:
9
9
  """
10
10
 
11
11
  from types import ModuleType
12
- from typing import Any, Dict, Union
12
+ from typing import Any, Union
13
13
 
14
14
  import prefect.settings
15
15
  from prefect.utilities.compat import EntryPoints, entry_points
16
16
 
17
- COLLECTIONS: Union[None, Dict[str, Union[ModuleType, Exception]]] = None
17
+ _collections: Union[None, dict[str, Union[ModuleType, Exception]]] = None
18
18
 
19
19
 
20
- def safe_load_entrypoints(entrypoints: EntryPoints) -> Dict[str, Union[Exception, Any]]:
20
+ def safe_load_entrypoints(entrypoints: EntryPoints) -> dict[str, Union[Exception, Any]]:
21
21
  """
22
22
  Load entry points for a group capturing any exceptions that occur.
23
23
  """
@@ -26,7 +26,7 @@ def safe_load_entrypoints(entrypoints: EntryPoints) -> Dict[str, Union[Exception
26
26
  # also want to validate the type for the group for entrypoints that have
27
27
  # a specific type we expect.
28
28
 
29
- results = {}
29
+ results: dict[str, Union[Exception, Any]] = {}
30
30
 
31
31
  for entrypoint in entrypoints:
32
32
  result = None
@@ -40,18 +40,20 @@ def safe_load_entrypoints(entrypoints: EntryPoints) -> Dict[str, Union[Exception
40
40
  return results
41
41
 
42
42
 
43
- def load_prefect_collections() -> Dict[str, Union[ModuleType, Exception]]:
43
+ def load_prefect_collections() -> dict[str, Union[ModuleType, Exception]]:
44
44
  """
45
45
  Load all Prefect collections that define an entrypoint in the group
46
46
  `prefect.collections`.
47
47
  """
48
- global COLLECTIONS
48
+ global _collections
49
49
 
50
- if COLLECTIONS is not None:
51
- return COLLECTIONS
50
+ if _collections is not None:
51
+ return _collections
52
52
 
53
53
  collection_entrypoints: EntryPoints = entry_points(group="prefect.collections")
54
- collections = safe_load_entrypoints(collection_entrypoints)
54
+ collections: dict[str, Union[Exception, Any]] = safe_load_entrypoints(
55
+ collection_entrypoints
56
+ )
55
57
 
56
58
  # TODO: Consider the utility of this once we've established this pattern.
57
59
  # We cannot use a logger here because logging is not yet initialized.
@@ -68,5 +70,5 @@ def load_prefect_collections() -> Dict[str, Union[ModuleType, Exception]]:
68
70
  if prefect.settings.PREFECT_DEBUG_MODE:
69
71
  print(f"Loaded collection {name!r}.")
70
72
 
71
- COLLECTIONS = collections
73
+ _collections = collections
72
74
  return collections
prefect/results.py CHANGED
@@ -245,7 +245,7 @@ async def _call_explicitly_async_block_method(
245
245
  see https://github.com/PrefectHQ/prefect/issues/15008
246
246
  """
247
247
  if hasattr(block, f"a{method}"): # explicit async method
248
- return await getattr(block.__class__.__name__, f"a{method}")(*args, **kwargs)
248
+ return await getattr(block, f"a{method}")(*args, **kwargs)
249
249
  elif hasattr(getattr(block, method, None), "aio"): # sync_compatible
250
250
  return await getattr(block, method).aio(block, *args, **kwargs)
251
251
  else: # should not happen in prefect, but users can override impls
@@ -1,6 +1,6 @@
1
1
  import time
2
2
  from threading import Event, Lock, Thread
3
- from typing import TYPE_CHECKING, Dict, Optional
3
+ from typing import TYPE_CHECKING, Optional
4
4
 
5
5
  from opentelemetry.context import Context
6
6
  from opentelemetry.sdk.trace import Span, SpanProcessor
@@ -13,7 +13,7 @@ if TYPE_CHECKING:
13
13
  class InFlightSpanProcessor(SpanProcessor):
14
14
  def __init__(self, span_exporter: "SpanExporter"):
15
15
  self.span_exporter = span_exporter
16
- self._in_flight: Dict[int, Span] = {}
16
+ self._in_flight: dict[int, Span] = {}
17
17
  self._lock = Lock()
18
18
  self._stop_event = Event()
19
19
  self._export_thread = Thread(target=self._export_periodically, daemon=True)
@@ -30,10 +30,10 @@ class InFlightSpanProcessor(SpanProcessor):
30
30
  self.span_exporter.export(to_export)
31
31
 
32
32
  def _readable_span(self, span: "Span") -> "ReadableSpan":
33
- readable = span._readable_span()
34
- readable._end_time = time.time_ns()
35
- readable._attributes = {
36
- **(readable._attributes or {}),
33
+ readable = span._readable_span() # pyright: ignore[reportPrivateUsage]
34
+ readable._end_time = time.time_ns() # pyright: ignore[reportPrivateUsage]
35
+ readable._attributes = { # pyright: ignore[reportPrivateUsage]
36
+ **(readable._attributes or {}), # pyright: ignore[reportPrivateUsage]
37
37
  "prefect.in-flight": True,
38
38
  }
39
39
  return readable
@@ -1,32 +1,38 @@
1
- from abc import abstractmethod
2
- from typing import Union
1
+ from collections.abc import Sequence
2
+ from typing import Any, Protocol, TypeVar
3
3
 
4
4
  from opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter
5
5
  from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
6
6
  from opentelemetry.sdk._logs import LogData
7
7
  from opentelemetry.sdk._logs.export import LogExporter
8
8
  from opentelemetry.sdk.trace import ReadableSpan
9
- from opentelemetry.sdk.trace.export import SpanExporter
9
+ from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult
10
10
 
11
11
  from prefect._internal.concurrency.services import BatchedQueueService
12
12
 
13
+ BatchItem = TypeVar("BatchItem", ReadableSpan, LogData)
14
+ T_contra = TypeVar("T_contra", contravariant=True)
13
15
 
14
- class BaseQueueingExporter(BatchedQueueService):
16
+
17
+ class OTLPExporter(Protocol[T_contra]):
18
+ def export(self, __items: Sequence[T_contra]) -> Any:
19
+ ...
20
+
21
+ def shutdown(self) -> Any:
22
+ ...
23
+
24
+
25
+ class BaseQueueingExporter(BatchedQueueService[BatchItem]):
15
26
  _max_batch_size = 512
16
27
  _min_interval = 2.0
17
- _otlp_exporter: Union[SpanExporter, LogExporter]
18
-
19
- def export(self, batch: list[Union[ReadableSpan, LogData]]) -> None:
20
- for item in batch:
21
- self.send(item)
22
28
 
23
- @abstractmethod
24
- def _export_batch(self, items: list[Union[ReadableSpan, LogData]]) -> None:
25
- pass
29
+ def __init__(self, otlp_exporter: OTLPExporter[BatchItem]) -> None:
30
+ super().__init__()
31
+ self._otlp_exporter = otlp_exporter
26
32
 
27
- async def _handle_batch(self, items: list[Union[ReadableSpan, LogData]]) -> None:
33
+ async def _handle_batch(self, items: list[BatchItem]) -> None:
28
34
  try:
29
- self._export_batch(items)
35
+ self._otlp_exporter.export(items)
30
36
  except Exception as e:
31
37
  self._logger.exception(f"Failed to export batch: {e}")
32
38
  raise
@@ -39,29 +45,24 @@ class BaseQueueingExporter(BatchedQueueService):
39
45
  self._otlp_exporter.shutdown()
40
46
 
41
47
 
42
- class QueueingSpanExporter(BaseQueueingExporter, SpanExporter):
48
+ class QueueingSpanExporter(BaseQueueingExporter[ReadableSpan], SpanExporter):
43
49
  _otlp_exporter: OTLPSpanExporter
44
50
 
45
51
  def __init__(self, endpoint: str, headers: tuple[tuple[str, str]]):
46
- super().__init__()
47
- self._otlp_exporter = OTLPSpanExporter(
48
- endpoint=endpoint,
49
- headers=dict(headers),
50
- )
52
+ super().__init__(OTLPSpanExporter(endpoint=endpoint, headers=dict(headers)))
51
53
 
52
- def _export_batch(self, items: list[ReadableSpan]) -> None:
53
- self._otlp_exporter.export(items)
54
+ def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult:
55
+ for item in spans:
56
+ self.send(item)
57
+ return SpanExportResult.SUCCESS
54
58
 
55
59
 
56
- class QueueingLogExporter(BaseQueueingExporter, LogExporter):
60
+ class QueueingLogExporter(BaseQueueingExporter[LogData], LogExporter):
57
61
  _otlp_exporter: OTLPLogExporter
58
62
 
59
- def __init__(self, endpoint: str, headers: tuple[tuple[str, str]]):
60
- super().__init__()
61
- self._otlp_exporter = OTLPLogExporter(
62
- endpoint=endpoint,
63
- headers=dict(headers),
64
- )
63
+ def __init__(self, endpoint: str, headers: tuple[tuple[str, str]]) -> None:
64
+ super().__init__(OTLPLogExporter(endpoint=endpoint, headers=dict(headers)))
65
65
 
66
- def _export_batch(self, items: list[LogData]) -> None:
67
- self._otlp_exporter.export(items)
66
+ def export(self, batch: Sequence[LogData]) -> None:
67
+ for item in batch:
68
+ self.send(item)
@@ -1 +1,3 @@
1
1
  from .process import ProcessWorker
2
+
3
+ __all__ = ["ProcessWorker"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: prefect-client
3
- Version: 3.1.9
3
+ Version: 3.1.10
4
4
  Summary: Workflow orchestration and management.
5
5
  Home-page: https://www.prefect.io
6
6
  Author: Prefect Technologies, Inc.
@@ -1,22 +1,22 @@
1
1
  prefect/.prefectignore,sha256=awSprvKT0vI8a64mEOLrMxhxqcO-b0ERQeYpA2rNKVQ,390
2
2
  prefect/__init__.py,sha256=FmdMSNpGH8Mrkn5X0mNZup8_SHdeB_aqEmS5taeOHAQ,3530
3
- prefect/_version.py,sha256=TTbVIJVdD1KpTcWtqBYl_bfNt7ct2xNjSPTYGZCtKGk,496
3
+ prefect/_version.py,sha256=bUcLcvgSrFk7uLI6vWR4M14nKrDGJAXv4mOuUqQtH0U,497
4
4
  prefect/agent.py,sha256=qyyUMdiv5ndUIk-O8uwamESJGXXDQ_BmhKiLlm31ue0,286
5
- prefect/artifacts.py,sha256=dsxFWmdg2r9zbHM3KgKOR5YbJ29_dXUYF9kipJpbxkE,13009
6
- prefect/automations.py,sha256=T8sUqDriABSuFeuoKUH2OXeCK5YwFfk-mjjM0_Oflyw,5984
5
+ prefect/artifacts.py,sha256=c_hMYTQoKFij8_tahtBeHzjYl7ztXAU90QP_6SuMw9A,12934
6
+ prefect/automations.py,sha256=QHS3Xh6wUKRvzxXt8cfWri6wXjX8EfEDDQN8a7cRw3c,6594
7
7
  prefect/cache_policies.py,sha256=dlhYHMxhb2N5KdDMIAuw4q-PIsI8WH5k0LDDLqsRYMU,9903
8
- prefect/context.py,sha256=HTEqJIvd_VuSS9LYdhZ2qlZsPgftWndgkw6EFGKbWJw,22364
8
+ prefect/context.py,sha256=OAEhyJz7kheIh6UEwPp3oLklYdM_UHibrdqeM3aCLqk,22325
9
9
  prefect/engine.py,sha256=qkT6hQWfxQPmjAEECQx3wluiDiFMHf3h9DRG1ShwK7w,2031
10
10
  prefect/exceptions.py,sha256=sbphPKQ4yOBUa9w0MsSFoDj_uC8Tlv9WHTjzO3cQKq8,11593
11
11
  prefect/filesystems.py,sha256=cLBGbnW2NQqH4N70Y1i1QuCL3R7p-_r_d5CGaEAd4wg,17897
12
12
  prefect/flow_engine.py,sha256=eb2N5lRdsZBWNIsaAs1pqdDhL5Vevq8ETxyn5LM4Mks,53812
13
13
  prefect/flow_runs.py,sha256=-5udBBYdgdCBCjAMYvELbA1vmrjZ6oREXl-BZdZr6hc,16129
14
- prefect/flows.py,sha256=FaArZfFYQgPnKRCC4c3nsEfJlwQTBQrCM7UHhULmrl4,94110
15
- prefect/futures.py,sha256=DlZvdccKtwQKuDUFrZ4zcINeO9C1chLiNOwjE5gTgCk,16356
14
+ prefect/flows.py,sha256=Z1BdpmJotXJoqoDqcUtxiiPsGWvDfSBvk1XEEo6ykw4,94127
15
+ prefect/futures.py,sha256=ZtQiRJddO5-LNabUZiX_2wEJnRf6w7qZ8KRC5VUNOa0,16915
16
16
  prefect/main.py,sha256=lFYvXkW32sMj4aVH97foApD3Ut3rZIwtO91xUQHo_6I,2355
17
- prefect/plugins.py,sha256=HY7Z7OJlltqzsUiPMEL1Y_hQbHw0CeZKayWiK-k8DP4,2435
17
+ prefect/plugins.py,sha256=FPRLR2mWVBMuOnlzeiTD9krlHONZH2rtYLD753JQDNQ,2516
18
18
  prefect/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- prefect/results.py,sha256=TiGitDQmG4wnrnxhV04mKnSe30gczGstLQa6ItrAOyM,50581
19
+ prefect/results.py,sha256=okLkMlQcYUZHIl0XXMqVnWVLdcIYXe4b1wWX1T7Qa_8,50562
20
20
  prefect/serializers.py,sha256=DiKLYdIA5VjCSrLyu0BSWcLLVRujqjvj8XoQ3HOuvoY,8968
21
21
  prefect/states.py,sha256=ZhJHLx8ax7dQNdaBl2eDT6VYGAU-68R1loht68qHGpc,25396
22
22
  prefect/task_engine.py,sha256=1xM64s9OpDREnKPnU9HpwHgtbAE50uwdp2ZucmPUhCg,61226
@@ -133,9 +133,9 @@ prefect/input/__init__.py,sha256=Ue2h-YhYP71nEtsVJaslqMwO6C0ckjhjTYwwEgp-E3g,701
133
133
  prefect/input/actions.py,sha256=IGdWjVcesnRjLmPCzB4ZM7FkRWXDKCku6yhE-7p0vKk,3777
134
134
  prefect/input/run_input.py,sha256=2wG-0L3N0spwh61Z3xI0PM8AAjHEIQZcDN703Er_gLo,18728
135
135
  prefect/locking/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
136
- prefect/locking/filesystem.py,sha256=GiZlLLj51cLH6QQgq7IeU6jUK6vGi0wMnOG0zaO95-c,8025
137
- prefect/locking/memory.py,sha256=Y1fsMSUAk3jUILzRivbxlrE9Xv8OcVbaylVf-aiEGNc,7495
138
- prefect/locking/protocol.py,sha256=o5-48SxvEDAdVwW8RIn7rCN32CmvIsaVHTztESUXuHU,4232
136
+ prefect/locking/filesystem.py,sha256=zhNwdKroi2kLR6Cut6CMT-rWmFwtTtzuGKSwGH_Iw0s,8084
137
+ prefect/locking/memory.py,sha256=mFUgV750ywEL7aVQuxFjg9gxbjVU4esBQn7bGQYzeMY,7548
138
+ prefect/locking/protocol.py,sha256=RsfvlaHTTEJ0YvYWSqFGoZuT2w4FPPxyQlHqjoyNGuE,4240
139
139
  prefect/logging/__init__.py,sha256=zx9f5_dWrR4DbcTOFBpNGOPoCZ1QcPFudr7zxb2XRpA,148
140
140
  prefect/logging/configuration.py,sha256=t7EJrk7Jr4QMxopH3TP6gRN8kMg_LFBsIoiwXCihrso,3353
141
141
  prefect/logging/filters.py,sha256=9keHLN4-cpnsWcii1qU0RITNi9-m7pOhkJ_t0MtCM4k,1117
@@ -200,9 +200,9 @@ prefect/telemetry/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs
200
200
  prefect/telemetry/bootstrap.py,sha256=b64UpBBo0Yo7Z8b_V9NQLAlFrpIuJoTs5opYTuB-R20,1550
201
201
  prefect/telemetry/instrumentation.py,sha256=G8kDiN2N4l7A8on-BHbYnh8uqH71zuGr3t2JntxRv0Q,4183
202
202
  prefect/telemetry/logging.py,sha256=yn5D4D2GGRrAv0y8wlHPN7PZDmQucGjQT_YauK9M9Yo,727
203
- prefect/telemetry/processors.py,sha256=mBWk51uIcdFumus0L_FZ0Qf-0c43jzDUAkoNETH_wJ8,2122
203
+ prefect/telemetry/processors.py,sha256=jw6j6LviOVxw3IBJe7cSjsxFk0zzY43jUmy6C9pcfCE,2272
204
204
  prefect/telemetry/run_telemetry.py,sha256=FfvcUJK6Sqcagp6rJ3vx4twCAkyYJYBhtNUUzjM0D7A,8135
205
- prefect/telemetry/services.py,sha256=eGKcg9pKUsTnrs9ou-vOCn1wXN2f-0iD9b1Upk01R3o,2146
205
+ prefect/telemetry/services.py,sha256=ek5KMSgCjUeIoNl9INPCfKkwlUwyFYp_dUiZd_rD0_8,2270
206
206
  prefect/types/__init__.py,sha256=s-l0r8UiDs7GCEstOPMzbb9PvvF_0F4G8OcVy3_50Yk,4700
207
207
  prefect/types/entrypoint.py,sha256=2FF03-wLPgtnqR_bKJDB2BsXXINPdu8ptY9ZYEZnXg8,328
208
208
  prefect/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -234,15 +234,15 @@ prefect/utilities/visualization.py,sha256=4MyQKLb00A1QZCvSrbPEbyqUNByQ_EkJ6wXKFC
234
234
  prefect/utilities/schema_tools/__init__.py,sha256=At3rMHd2g_Em2P3_dFQlFgqR_EpBwrYtU2N2OJd0pDE,345
235
235
  prefect/utilities/schema_tools/hydration.py,sha256=4yQMynZSloPFp0tlA7g8udWqE2TjZgfm19Y4R4F0s04,9415
236
236
  prefect/utilities/schema_tools/validation.py,sha256=Wix26IVR-ZJ32-6MX2pHhrwm3reB-Q4iB6_phn85OKE,10743
237
- prefect/workers/__init__.py,sha256=8dP8SLZbWYyC_l9DRTQSE3dEbDgns5DZDhxkp_NfsbQ,35
237
+ prefect/workers/__init__.py,sha256=EaM1F0RZ-XIJaGeTKLsXDnfOPHzVWk5bk0_c4BVS44M,64
238
238
  prefect/workers/base.py,sha256=nBv4pc51J1JRoSkgxvBDfQb4wIEN67D7cBVwT-jYHdI,49198
239
239
  prefect/workers/block.py,sha256=qyyUMdiv5ndUIk-O8uwamESJGXXDQ_BmhKiLlm31ue0,286
240
240
  prefect/workers/cloud.py,sha256=qyyUMdiv5ndUIk-O8uwamESJGXXDQ_BmhKiLlm31ue0,286
241
241
  prefect/workers/process.py,sha256=tcJ3fbiraLCfpVGpv8dOHwMSfVzeD_kyguUOvPuIz6I,19796
242
242
  prefect/workers/server.py,sha256=lgh2FfSuaNU7b6HPxSFm8JtKvAvHsZGkiOo4y4tW1Cw,2022
243
243
  prefect/workers/utilities.py,sha256=VfPfAlGtTuDj0-Kb8WlMgAuOfgXCdrGAnKMapPSBrwc,2483
244
- prefect_client-3.1.9.dist-info/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
245
- prefect_client-3.1.9.dist-info/METADATA,sha256=KmvB9sA6WKsVD23CjmL-BLNkORJIbhyKv28iSnvbrxE,7286
246
- prefect_client-3.1.9.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
247
- prefect_client-3.1.9.dist-info/top_level.txt,sha256=MJZYJgFdbRc2woQCeB4vM6T33tr01TmkEhRcns6H_H4,8
248
- prefect_client-3.1.9.dist-info/RECORD,,
244
+ prefect_client-3.1.10.dist-info/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
245
+ prefect_client-3.1.10.dist-info/METADATA,sha256=BbPdwx1OPrG1CxVh7OJNeBzquSMMMfOCBk4e-zilqhs,7287
246
+ prefect_client-3.1.10.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
247
+ prefect_client-3.1.10.dist-info/top_level.txt,sha256=MJZYJgFdbRc2woQCeB4vM6T33tr01TmkEhRcns6H_H4,8
248
+ prefect_client-3.1.10.dist-info/RECORD,,