prefect-client 3.2.1__py3-none-any.whl → 3.2.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,15 +3,14 @@ Utilities for creating and working with Prefect REST API schemas.
3
3
  """
4
4
 
5
5
  import datetime
6
- from typing import Any, ClassVar, Optional, TypeVar, cast
6
+ from typing import Any, ClassVar, Optional, TypeVar
7
7
  from uuid import UUID, uuid4
8
8
 
9
- import pendulum
10
9
  from pydantic import BaseModel, ConfigDict, Field
11
10
  from rich.repr import RichReprResult
12
11
  from typing_extensions import Self
13
12
 
14
- from prefect.types import DateTime
13
+ from prefect.types._datetime import DateTime, create_datetime_instance
15
14
  from prefect.utilities.generics import validate_list
16
15
 
17
16
  T = TypeVar("T")
@@ -73,11 +72,9 @@ class PrefectBaseModel(BaseModel):
73
72
  and name == "timestamp"
74
73
  and value
75
74
  ):
76
- value = cast(pendulum.DateTime, pendulum.instance(value)).isoformat()
75
+ value = create_datetime_instance(value).isoformat()
77
76
  elif isinstance(field.annotation, datetime.datetime) and value:
78
- value = cast(
79
- pendulum.DateTime, pendulum.instance(value)
80
- ).diff_for_humans()
77
+ value = create_datetime_instance(value).diff_for_humans()
81
78
 
82
79
  yield name, value, field.get_default()
83
80
 
@@ -19,9 +19,8 @@ from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union, overload
19
19
  from uuid import UUID
20
20
 
21
21
  import jsonschema
22
- import pendulum
23
- import pendulum.tz
24
22
 
23
+ from prefect.types._datetime import DateTime, create_datetime_instance, get_timezones
25
24
  from prefect.utilities.collections import isiterable
26
25
  from prefect.utilities.filesystem import relative_path_to_current_platform
27
26
  from prefect.utilities.importtools import from_qualified_name
@@ -253,8 +252,8 @@ def reconcile_paused_deployment(values: MM) -> MM:
253
252
  return values
254
253
 
255
254
 
256
- def default_anchor_date(v: pendulum.DateTime) -> pendulum.DateTime:
257
- return pendulum.instance(v)
255
+ def default_anchor_date(v: DateTime) -> DateTime:
256
+ return create_datetime_instance(v)
258
257
 
259
258
 
260
259
  @overload
@@ -271,7 +270,7 @@ def default_timezone(
271
270
  v: Optional[str], values: Optional[Mapping[str, Any]] = None
272
271
  ) -> Optional[str]:
273
272
  values = values or {}
274
- timezones = pendulum.tz.timezones()
273
+ timezones = get_timezones()
275
274
 
276
275
  if v is not None:
277
276
  if v and v not in timezones:
@@ -283,7 +282,7 @@ def default_timezone(
283
282
 
284
283
  # anchor schedules
285
284
  elif "anchor_date" in values:
286
- anchor_date: pendulum.DateTime = values["anchor_date"]
285
+ anchor_date: DateTime = values["anchor_date"]
287
286
  tz = "UTC" if anchor_date.tz is None else anchor_date.tz.name
288
287
  # sometimes anchor dates have "timezones" that are UTC offsets
289
288
  # like "-04:00". This happens when parsing ISO8601 strings.
@@ -9,6 +9,7 @@ from typing import (
9
9
  Optional,
10
10
  TypeVar,
11
11
  Union,
12
+ cast,
12
13
  )
13
14
  from uuid import UUID
14
15
 
@@ -146,6 +147,8 @@ class ResultRecord(BaseModel, Generic[R]):
146
147
  @classmethod
147
148
  def coerce_old_format(cls, value: dict[str, Any] | Any) -> dict[str, Any]:
148
149
  if isinstance(value, dict):
150
+ if TYPE_CHECKING: # TODO: # isintance doesn't accept generic parameters
151
+ value = cast(dict[str, Any], value)
149
152
  if "data" in value:
150
153
  value["result"] = value.pop("data")
151
154
  if "metadata" not in value:
@@ -232,4 +235,6 @@ class ResultRecord(BaseModel, Generic[R]):
232
235
  def __eq__(self, other: Any | "ResultRecord[Any]") -> bool:
233
236
  if not isinstance(other, ResultRecord):
234
237
  return False
235
- return self.metadata == other.metadata and self.result == other.result
238
+ return self.model_dump(include={"metadata", "result"}) == other.model_dump(
239
+ include={"metadata", "result"}
240
+ )
prefect/_version.py CHANGED
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2025-02-10T15:20:53-0600",
11
+ "date": "2025-02-13T10:53:49-0500",
12
12
  "dirty": true,
13
13
  "error": null,
14
- "full-revisionid": "f8b15dfbe4dc668f9048f5199efdd90dc8626859",
15
- "version": "3.2.1"
14
+ "full-revisionid": "d982c69a8bd4fb92cb250bc91dea25d361601260",
15
+ "version": "3.2.2"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -11,7 +11,7 @@ from uuid import UUID
11
11
  import certifi
12
12
  import httpcore
13
13
  import httpx
14
- import pendulum
14
+
15
15
  import pydantic
16
16
  from asgi_lifespan import LifespanManager
17
17
  from packaging import version
@@ -130,6 +130,7 @@ from prefect.settings import (
130
130
  PREFECT_SERVER_ALLOW_EPHEMERAL_MODE,
131
131
  PREFECT_TESTING_UNIT_TEST_MODE,
132
132
  )
133
+ from prefect.types._datetime import now
133
134
 
134
135
  if TYPE_CHECKING:
135
136
  from prefect.tasks import Task as TaskObject
@@ -148,7 +149,7 @@ T = TypeVar("T")
148
149
 
149
150
 
150
151
  @overload
151
- def get_client(
152
+ def get_client( # type: ignore # TODO
152
153
  *,
153
154
  httpx_settings: Optional[dict[str, Any]] = ...,
154
155
  sync_client: Literal[False] = False,
@@ -607,7 +608,7 @@ class PrefectClient(
607
608
  List[FlowRun]: a list of FlowRun objects read from the queue
608
609
  """
609
610
  if scheduled_before is None:
610
- scheduled_before = pendulum.now("UTC")
611
+ scheduled_before = now("UTC")
611
612
 
612
613
  try:
613
614
  response = await self._client.post(
@@ -30,7 +30,7 @@ def is_valid_timezone(v: str) -> bool:
30
30
  Validate that the provided timezone is a valid IANA timezone.
31
31
 
32
32
  Unfortunately this list is slightly different from the list of valid
33
- timezones in pendulum that we use for cron and interval timezone validation.
33
+ timezones we use for cron and interval timezone validation.
34
34
  """
35
35
  from prefect._internal.pytz import HAS_PYTZ
36
36
 
@@ -309,7 +309,7 @@ class RRuleSchedule(PrefectBaseModel):
309
309
  Validate that the provided timezone is a valid IANA timezone.
310
310
 
311
311
  Unfortunately this list is slightly different from the list of valid
312
- timezones in pendulum that we use for cron and interval timezone validation.
312
+ timezones we use for cron and interval timezone validation.
313
313
  """
314
314
  if v is None:
315
315
  return "UTC"
@@ -3,7 +3,8 @@ from contextlib import asynccontextmanager
3
3
  from typing import Optional, Union
4
4
 
5
5
  import anyio
6
- import pendulum
6
+
7
+ from prefect.types._datetime import now
7
8
 
8
9
  from ._asyncio import (
9
10
  AcquireConcurrencySlotTimeoutError as AcquireConcurrencySlotTimeoutError,
@@ -69,13 +70,13 @@ async def concurrency(
69
70
  max_retries=max_retries,
70
71
  strict=strict,
71
72
  )
72
- acquisition_time = pendulum.now("UTC")
73
+ acquisition_time = now("UTC")
73
74
  emitted_events = emit_concurrency_acquisition_events(limits, occupy)
74
75
 
75
76
  try:
76
77
  yield
77
78
  finally:
78
- occupancy_period = pendulum.now("UTC") - acquisition_time
79
+ occupancy_period = now("UTC") - acquisition_time
79
80
  try:
80
81
  await arelease_concurrency_slots(
81
82
  names, occupy, occupancy_period.total_seconds()
@@ -2,10 +2,10 @@ from collections.abc import Generator
2
2
  from contextlib import contextmanager
3
3
  from typing import Optional, TypeVar, Union
4
4
 
5
- import pendulum
6
5
  from typing_extensions import Literal
7
6
 
8
7
  from prefect.client.schemas.responses import MinimalConcurrencyLimitResponse
8
+ from prefect.types._datetime import now
9
9
  from prefect.utilities.asyncutils import run_coro_as_sync
10
10
 
11
11
  from ._asyncio import (
@@ -98,13 +98,13 @@ def concurrency(
98
98
  strict=strict,
99
99
  max_retries=max_retries,
100
100
  )
101
- acquisition_time = pendulum.now("UTC")
101
+ acquisition_time = now("UTC")
102
102
  emitted_events = emit_concurrency_acquisition_events(limits, occupy)
103
103
 
104
104
  try:
105
105
  yield
106
106
  finally:
107
- occupancy_period = pendulum.now("UTC") - acquisition_time
107
+ occupancy_period = now("UTC") - acquisition_time
108
108
  _release_concurrency_slots(names, occupy, occupancy_period.total_seconds())
109
109
  emit_concurrency_release_events(limits, occupy, emitted_events)
110
110
 
@@ -4,7 +4,6 @@ from typing import TYPE_CHECKING, Optional, Union
4
4
  from uuid import UUID
5
5
 
6
6
  import anyio
7
- import pendulum
8
7
 
9
8
  from prefect.concurrency.v1._asyncio import (
10
9
  acquire_concurrency_slots,
@@ -15,6 +14,7 @@ from prefect.concurrency.v1._events import (
15
14
  emit_concurrency_release_events,
16
15
  )
17
16
  from prefect.concurrency.v1.context import ConcurrencyContext
17
+ from prefect.types._datetime import now
18
18
 
19
19
  from ._asyncio import (
20
20
  AcquireConcurrencySlotTimeoutError as AcquireConcurrencySlotTimeoutError,
@@ -67,13 +67,13 @@ async def concurrency(
67
67
  if TYPE_CHECKING:
68
68
  assert not isinstance(acquire_slots, list)
69
69
  limits = await acquire_slots
70
- acquisition_time = pendulum.now("UTC")
70
+ acquisition_time = now("UTC")
71
71
  emitted_events = emit_concurrency_acquisition_events(limits, task_run_id)
72
72
 
73
73
  try:
74
74
  yield
75
75
  finally:
76
- occupancy_period = pendulum.now("UTC") - acquisition_time
76
+ occupancy_period = now("UTC") - acquisition_time
77
77
  try:
78
78
  release_slots = release_concurrency_slots(
79
79
  names_normalized, task_run_id, occupancy_period.total_seconds()
@@ -4,7 +4,7 @@ from contextlib import contextmanager
4
4
  from typing import Optional, TypeVar, Union
5
5
  from uuid import UUID
6
6
 
7
- import pendulum
7
+ from prefect.types._datetime import now
8
8
 
9
9
  from ._asyncio import acquire_concurrency_slots, release_concurrency_slots
10
10
  from ._events import (
@@ -59,13 +59,13 @@ def concurrency(
59
59
  )
60
60
  assert not asyncio.iscoroutine(result)
61
61
  limits = result
62
- acquisition_time = pendulum.now("UTC")
62
+ acquisition_time = now("UTC")
63
63
  emitted_events = emit_concurrency_acquisition_events(limits, task_run_id)
64
64
 
65
65
  try:
66
66
  yield
67
67
  finally:
68
- occupancy_period = pendulum.now("UTC") - acquisition_time
68
+ occupancy_period = now("UTC") - acquisition_time
69
69
  release_concurrency_slots(
70
70
  names, task_run_id, occupancy_period.total_seconds(), **force
71
71
  )
@@ -3,7 +3,6 @@ from typing import TYPE_CHECKING, Any, Iterable, Optional, Union
3
3
  from uuid import UUID
4
4
 
5
5
  import anyio
6
- import pendulum
7
6
 
8
7
  import prefect
9
8
  from prefect._result_records import ResultRecordMetadata
@@ -16,6 +15,7 @@ from prefect.tasks import Task
16
15
  from prefect.telemetry.run_telemetry import (
17
16
  LABELS_TRACEPARENT_KEY,
18
17
  )
18
+ from prefect.types._datetime import now
19
19
  from prefect.utilities.asyncutils import sync_compatible
20
20
  from prefect.utilities.slugify import slugify
21
21
 
@@ -96,7 +96,7 @@ async def run_deployment(
96
96
  raise ValueError("`timeout` cannot be negative")
97
97
 
98
98
  if scheduled_time is None:
99
- scheduled_time = pendulum.now("UTC")
99
+ scheduled_time = now("UTC")
100
100
 
101
101
  parameters = parameters or {}
102
102
 
@@ -1,11 +1,10 @@
1
1
  from pathlib import Path
2
2
  from typing import Any, Optional
3
3
 
4
- from pendulum import now as pendulum_now
5
-
6
4
  from prefect.settings import (
7
5
  PREFECT_DEFAULT_DOCKER_BUILD_NAMESPACE,
8
6
  )
7
+ from prefect.types._datetime import now
9
8
  from prefect.utilities.dockerutils import (
10
9
  PushError,
11
10
  build_image,
@@ -54,7 +53,7 @@ class DockerImage:
54
53
  # join the namespace and repository to create the full image name
55
54
  # ignore namespace if it is None
56
55
  self.name: str = "/".join(filter(None, [namespace, repository]))
57
- self.tag: str = tag or image_tag or slugify(pendulum_now("utc").isoformat())
56
+ self.tag: str = tag or image_tag or slugify(now("UTC").isoformat())
58
57
  self.dockerfile: str = dockerfile
59
58
  self.build_kwargs: dict[str, Any] = build_kwargs
60
59
 
prefect/engine.py CHANGED
@@ -64,7 +64,7 @@ if __name__ == "__main__":
64
64
 
65
65
  except Abort:
66
66
  engine_logger.info(
67
- "Engine execution of flow run '{flow_run_id}' aborted by orchestrator."
67
+ f"Engine execution of flow run '{flow_run_id}' aborted by orchestrator."
68
68
  )
69
69
  exit(0)
70
70
  except Pause:
prefect/events/clients.py CHANGED
@@ -2,6 +2,7 @@ import abc
2
2
  import asyncio
3
3
  import os
4
4
  import ssl
5
+ from datetime import timedelta
5
6
  from types import TracebackType
6
7
  from typing import (
7
8
  TYPE_CHECKING,
@@ -21,7 +22,6 @@ from urllib.request import proxy_bypass
21
22
  from uuid import UUID
22
23
 
23
24
  import orjson
24
- import pendulum
25
25
  from cachetools import TTLCache
26
26
  from prometheus_client import Counter
27
27
  from python_socks.async_.asyncio import Proxy
@@ -44,6 +44,7 @@ from prefect.settings import (
44
44
  PREFECT_DEBUG_MODE,
45
45
  PREFECT_SERVER_ALLOW_EPHEMERAL_MODE,
46
46
  )
47
+ from prefect.types._datetime import add_years, now
47
48
 
48
49
  if TYPE_CHECKING:
49
50
  from prefect.events.filters import EventFilter
@@ -653,8 +654,8 @@ class PrefectEventSubscriber:
653
654
  from prefect.events.filters import EventOccurredFilter
654
655
 
655
656
  self._filter.occurred = EventOccurredFilter(
656
- since=pendulum.now("UTC").subtract(minutes=1),
657
- until=pendulum.now("UTC").add(years=1),
657
+ since=now("UTC") - timedelta(minutes=1),
658
+ until=add_years(now("UTC"), 1),
658
659
  )
659
660
 
660
661
  logger.debug(" filtering events since %s...", self._filter.occurred.since)
prefect/events/related.py CHANGED
@@ -14,9 +14,7 @@ from typing import (
14
14
  )
15
15
  from uuid import UUID
16
16
 
17
- import pendulum
18
-
19
- from prefect.types import DateTime
17
+ from prefect.types._datetime import DateTime, now
20
18
 
21
19
  from .schemas.events import RelatedResource
22
20
 
@@ -79,7 +77,7 @@ async def related_resources_from_run_context(
79
77
 
80
78
  related_objects: List[ResourceCacheEntry] = []
81
79
 
82
- async def dummy_read():
80
+ async def dummy_read() -> ResourceCacheEntry:
83
81
  return {}
84
82
 
85
83
  if flow_run_context:
@@ -207,7 +205,7 @@ async def _get_and_cache_related_object(
207
205
  "object": obj_,
208
206
  }
209
207
 
210
- cache[cache_key] = (entry, pendulum.now("UTC"))
208
+ cache[cache_key] = (entry, now("UTC"))
211
209
 
212
210
  # In the case of a worker or agent this cache could be long-lived. To keep
213
211
  # from running out of memory only keep `MAX_CACHE_SIZE` entries in the
prefect/flows.py CHANGED
@@ -2360,11 +2360,17 @@ async def load_flow_from_flow_run(
2360
2360
  import_path = relative_path_to_current_platform(deployment.entrypoint)
2361
2361
  run_logger.debug(f"Importing flow code from '{import_path}'")
2362
2362
 
2363
- flow = await run_sync_in_worker_thread(
2364
- load_flow_from_entrypoint,
2365
- str(import_path),
2366
- use_placeholder_flow=use_placeholder_flow,
2367
- )
2363
+ try:
2364
+ flow = await run_sync_in_worker_thread(
2365
+ load_flow_from_entrypoint,
2366
+ str(import_path),
2367
+ use_placeholder_flow=use_placeholder_flow,
2368
+ )
2369
+ except MissingFlowError:
2370
+ flow = await run_sync_in_worker_thread(
2371
+ load_function_and_convert_to_flow,
2372
+ str(import_path),
2373
+ )
2368
2374
 
2369
2375
  return flow
2370
2376
 
@@ -1,15 +1,15 @@
1
1
  import time
2
+ from datetime import timedelta
2
3
  from logging import Logger
3
4
  from pathlib import Path
4
5
  from typing import Optional
5
6
 
6
7
  import anyio
7
- import pendulum
8
8
  import pydantic_core
9
9
  from typing_extensions import TypedDict
10
10
 
11
11
  from prefect.logging.loggers import get_logger
12
- from prefect.types._datetime import DateTime, PendulumDuration
12
+ from prefect.types._datetime import DateTime, now, parse_datetime
13
13
 
14
14
  from .protocol import LockManager
15
15
 
@@ -27,7 +27,7 @@ class _LockInfo(TypedDict):
27
27
  """
28
28
 
29
29
  holder: str
30
- expiration: Optional[pendulum.DateTime]
30
+ expiration: Optional[DateTime]
31
31
  path: Path
32
32
 
33
33
 
@@ -64,7 +64,7 @@ class FileSystemLockManager(LockManager):
64
64
  lock_info["path"] = lock_path
65
65
  expiration = lock_info.get("expiration")
66
66
  lock_info["expiration"] = (
67
- pendulum.parse(expiration) if expiration is not None else None
67
+ parse_datetime(expiration) if expiration is not None else None
68
68
  )
69
69
  self._locks[key] = lock_info
70
70
  return lock_info
@@ -86,7 +86,7 @@ class FileSystemLockManager(LockManager):
86
86
  lock_info["path"] = lock_path
87
87
  expiration = lock_info.get("expiration")
88
88
  lock_info["expiration"] = (
89
- pendulum.parse(expiration) if expiration is not None else None
89
+ parse_datetime(expiration) if expiration is not None else None
90
90
  )
91
91
  self._locks[key] = lock_info
92
92
  return lock_info
@@ -117,7 +117,7 @@ class FileSystemLockManager(LockManager):
117
117
  )
118
118
  return self.acquire_lock(key, holder, acquire_timeout, hold_timeout)
119
119
  expiration = (
120
- DateTime.now("utc") + PendulumDuration(seconds=hold_timeout)
120
+ now("UTC") + timedelta(seconds=hold_timeout)
121
121
  if hold_timeout is not None
122
122
  else None
123
123
  )
@@ -166,7 +166,7 @@ class FileSystemLockManager(LockManager):
166
166
  )
167
167
  return self.acquire_lock(key, holder, acquire_timeout, hold_timeout)
168
168
  expiration = (
169
- DateTime.now("utc") + PendulumDuration(seconds=hold_timeout)
169
+ now("UTC") + timedelta(seconds=hold_timeout)
170
170
  if hold_timeout is not None
171
171
  else None
172
172
  )
@@ -208,7 +208,7 @@ class FileSystemLockManager(LockManager):
208
208
  if (expiration := lock_info.get("expiration")) is None:
209
209
  return True
210
210
 
211
- expired = expiration < DateTime.now("utc")
211
+ expired = expiration < now("UTC")
212
212
  if expired:
213
213
  Path(lock_info["path"]).unlink()
214
214
  self._locks.pop(key, None)
@@ -8,9 +8,8 @@ import traceback
8
8
  import uuid
9
9
  import warnings
10
10
  from contextlib import asynccontextmanager
11
- from typing import TYPE_CHECKING, Any, Dict, List, TextIO, Type
11
+ from typing import TYPE_CHECKING, Any, Dict, TextIO, Type
12
12
 
13
- import pendulum
14
13
  from rich.console import Console
15
14
  from rich.highlighter import Highlighter, NullHighlighter
16
15
  from rich.theme import Theme
@@ -35,6 +34,7 @@ from prefect.settings import (
35
34
  PREFECT_LOGGING_TO_API_MAX_LOG_SIZE,
36
35
  PREFECT_LOGGING_TO_API_WHEN_MISSING_FLOW,
37
36
  )
37
+ from prefect.types._datetime import from_timestamp
38
38
 
39
39
  if sys.version_info >= (3, 12):
40
40
  StreamHandler = logging.StreamHandler[TextIO]
@@ -47,7 +47,7 @@ else:
47
47
 
48
48
  class APILogWorker(BatchedQueueService[Dict[str, Any]]):
49
49
  @property
50
- def _max_batch_size(self):
50
+ def _max_batch_size(self) -> int:
51
51
  return max(
52
52
  PREFECT_LOGGING_TO_API_BATCH_SIZE.value()
53
53
  - PREFECT_LOGGING_TO_API_MAX_LOG_SIZE.value(),
@@ -55,10 +55,10 @@ class APILogWorker(BatchedQueueService[Dict[str, Any]]):
55
55
  )
56
56
 
57
57
  @property
58
- def _min_interval(self):
58
+ def _min_interval(self) -> float | None:
59
59
  return PREFECT_LOGGING_TO_API_BATCH_INTERVAL.value()
60
60
 
61
- async def _handle_batch(self, items: List):
61
+ async def _handle_batch(self, items: list[dict[str, Any]]):
62
62
  try:
63
63
  await self._client.create_logs(items)
64
64
  except Exception as e:
@@ -229,9 +229,7 @@ class APILogHandler(logging.Handler):
229
229
  worker_id=worker_id,
230
230
  name=record.name,
231
231
  level=record.levelno,
232
- timestamp=pendulum.from_timestamp(
233
- getattr(record, "created", None) or time.time()
234
- ),
232
+ timestamp=from_timestamp(getattr(record, "created", None) or time.time()),
235
233
  message=self.format(record),
236
234
  ).model_dump(mode="json")
237
235
 
@@ -272,9 +270,7 @@ class WorkerAPILogHandler(APILogHandler):
272
270
  worker_id=worker_id,
273
271
  name=record.name,
274
272
  level=record.levelno,
275
- timestamp=pendulum.from_timestamp(
276
- getattr(record, "created", None) or time.time()
277
- ),
273
+ timestamp=from_timestamp(getattr(record, "created", None) or time.time()),
278
274
  message=self.format(record),
279
275
  ).model_dump(mode="json")
280
276
 
@@ -23,14 +23,14 @@ Available attributes:
23
23
  from __future__ import annotations
24
24
 
25
25
  import os
26
+ from datetime import datetime
26
27
  from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional
27
28
 
28
- import pendulum
29
-
30
29
  from prefect._internal.concurrency.api import create_call, from_sync
31
30
  from prefect.client.orchestration import get_client
32
31
  from prefect.context import FlowRunContext, TaskRunContext
33
32
  from prefect.settings import PREFECT_API_URL, PREFECT_UI_URL
33
+ from prefect.types._datetime import DateTime, Timezone, now, parse_datetime
34
34
 
35
35
  if TYPE_CHECKING:
36
36
  from prefect.client.schemas.objects import Flow, FlowRun, TaskRun
@@ -53,28 +53,21 @@ __all__ = [
53
53
  ]
54
54
 
55
55
 
56
- def _pendulum_parse(dt: str) -> pendulum.DateTime:
57
- """
58
- Use pendulum to cast different format date strings to pendulum.DateTime --
59
- tzinfo is ignored (UTC forced)
60
- """
61
- return pendulum.parse(dt, tz=None, strict=False).set(tz="UTC")
56
+ def _parse_datetime_UTC(dt: str) -> DateTime:
57
+ pendulum_dt = parse_datetime(dt, tz=Timezone("UTC"), strict=False)
58
+ assert isinstance(pendulum_dt, datetime)
59
+ return DateTime.instance(pendulum_dt)
62
60
 
63
61
 
64
62
  type_cast: dict[
65
- type[bool]
66
- | type[int]
67
- | type[float]
68
- | type[str]
69
- | type[None]
70
- | type[pendulum.DateTime],
63
+ type[bool] | type[int] | type[float] | type[str] | type[None] | type[DateTime],
71
64
  Callable[[Any], Any],
72
65
  ] = {
73
66
  bool: lambda x: x.lower() == "true",
74
67
  int: int,
75
68
  float: float,
76
69
  str: str,
77
- pendulum.DateTime: _pendulum_parse,
70
+ DateTime: _parse_datetime_UTC,
78
71
  # for optional defined attributes, when real value is NoneType, use str
79
72
  type(None): str,
80
73
  }
@@ -221,11 +214,11 @@ def get_flow_version() -> Optional[str]:
221
214
  return flow_run_ctx.flow.version
222
215
 
223
216
 
224
- def get_scheduled_start_time() -> pendulum.DateTime:
217
+ def get_scheduled_start_time() -> DateTime:
225
218
  flow_run_ctx = FlowRunContext.get()
226
219
  run_id = get_id()
227
220
  if flow_run_ctx is None and run_id is None:
228
- return pendulum.now("utc")
221
+ return now("UTC")
229
222
  elif flow_run_ctx is None:
230
223
  flow_run = from_sync.call_soon_in_loop_thread(
231
224
  create_call(_get_flow_run, run_id)
prefect/states.py CHANGED
@@ -28,7 +28,7 @@ from prefect.exceptions import (
28
28
  UnfinishedRun,
29
29
  )
30
30
  from prefect.logging.loggers import get_logger, get_run_logger
31
- from prefect.types._datetime import DateTime, PendulumDuration
31
+ from prefect.types._datetime import DateTime, Duration, now
32
32
  from prefect.utilities.annotations import BaseAnnotation
33
33
  from prefect.utilities.asyncutils import in_async_main_thread, sync_compatible
34
34
  from prefect.utilities.collections import ensure_iterable
@@ -660,7 +660,7 @@ def Scheduled(
660
660
  """
661
661
  state_details = StateDetails.model_validate(kwargs.pop("state_details", {}))
662
662
  if scheduled_time is None:
663
- scheduled_time = DateTime.now("UTC")
663
+ scheduled_time = now()
664
664
  elif state_details.scheduled_time:
665
665
  raise ValueError("An extra scheduled_time was provided in state_details")
666
666
  state_details.scheduled_time = scheduled_time
@@ -761,7 +761,7 @@ def Paused(
761
761
  state_details.pause_timeout = (
762
762
  DateTime.instance(pause_expiration_time)
763
763
  if pause_expiration_time
764
- else DateTime.now("UTC") + PendulumDuration(seconds=timeout_seconds or 0)
764
+ else now() + Duration(seconds=timeout_seconds or 0)
765
765
  )
766
766
 
767
767
  state_details.pause_reschedule = reschedule
prefect/task_engine.py CHANGED
@@ -79,7 +79,7 @@ from prefect.states import (
79
79
  )
80
80
  from prefect.telemetry.run_telemetry import RunTelemetry
81
81
  from prefect.transactions import IsolationLevel, Transaction, transaction
82
- from prefect.types._datetime import DateTime, PendulumDuration
82
+ from prefect.types._datetime import DateTime, Duration
83
83
  from prefect.utilities._engine import get_hook_name
84
84
  from prefect.utilities.annotations import NotSet
85
85
  from prefect.utilities.asyncutils import run_coro_as_sync
@@ -437,7 +437,7 @@ class SyncTaskRunEngine(BaseTaskRunEngine[P, R]):
437
437
  if last_state.timestamp == new_state.timestamp:
438
438
  # Ensure that the state timestamp is unique, or at least not equal to the last state.
439
439
  # This might occur especially on Windows where the timestamp resolution is limited.
440
- new_state.timestamp += PendulumDuration(microseconds=1)
440
+ new_state.timestamp += Duration(microseconds=1)
441
441
 
442
442
  # Ensure that the state_details are populated with the current run IDs
443
443
  new_state.state_details.task_run_id = self.task_run.id
@@ -970,7 +970,7 @@ class AsyncTaskRunEngine(BaseTaskRunEngine[P, R]):
970
970
  if last_state.timestamp == new_state.timestamp:
971
971
  # Ensure that the state timestamp is unique, or at least not equal to the last state.
972
972
  # This might occur especially on Windows where the timestamp resolution is limited.
973
- new_state.timestamp += PendulumDuration(microseconds=1)
973
+ new_state.timestamp += Duration(microseconds=1)
974
974
 
975
975
  # Ensure that the state_details are populated with the current run IDs
976
976
  new_state.state_details.task_run_id = self.task_run.id
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import datetime
3
4
  from typing import Any
4
5
 
5
6
  import pendulum
@@ -9,12 +10,21 @@ from pendulum.datetime import DateTime as PendulumDateTime
9
10
  from pendulum.duration import Duration as PendulumDuration
10
11
  from pendulum.time import Time as PendulumTime
11
12
  from pendulum.tz.timezone import FixedTimezone, Timezone
12
- from pydantic_extra_types.pendulum_dt import Date as PydanticDate
13
- from pydantic_extra_types.pendulum_dt import DateTime as PydanticDateTime
13
+ from pydantic_extra_types.pendulum_dt import (
14
+ Date as PydanticDate,
15
+ )
16
+ from pydantic_extra_types.pendulum_dt import (
17
+ DateTime as PydanticDateTime,
18
+ )
19
+ from pydantic_extra_types.pendulum_dt import (
20
+ Duration as PydanticDuration,
21
+ )
14
22
  from typing_extensions import TypeAlias
15
23
 
16
24
  DateTime: TypeAlias = PydanticDateTime
17
25
  Date: TypeAlias = PydanticDate
26
+ Duration: TypeAlias = PydanticDuration
27
+ UTC: pendulum.tz.Timezone = pendulum.tz.UTC
18
28
 
19
29
 
20
30
  def parse_datetime(
@@ -37,10 +47,79 @@ def local_timezone() -> Timezone | FixedTimezone:
37
47
  return pendulum.tz.local_timezone()
38
48
 
39
49
 
50
+ def get_timezones() -> tuple[str, ...]:
51
+ return pendulum.tz.timezones()
52
+
53
+
54
+ def create_datetime_instance(v: datetime.datetime) -> DateTime:
55
+ return DateTime.instance(v)
56
+
57
+
40
58
  def from_format(
41
59
  value: str,
42
60
  fmt: str,
43
- tz: str | Timezone = pendulum.tz.UTC,
61
+ tz: str | Timezone = UTC,
44
62
  locale: str | None = None,
45
63
  ) -> DateTime:
46
64
  return DateTime.instance(pendulum.from_format(value, fmt, tz, locale))
65
+
66
+
67
+ def from_timestamp(ts: float, tz: str | pendulum.tz.Timezone = UTC) -> DateTime:
68
+ return DateTime.instance(pendulum.from_timestamp(ts, tz))
69
+
70
+
71
+ def human_friendly_diff(dt: DateTime | datetime.datetime) -> str:
72
+ if isinstance(dt, DateTime):
73
+ return dt.diff_for_humans()
74
+ else:
75
+ return DateTime.instance(dt).diff_for_humans()
76
+
77
+
78
+ def now(tz: str | Timezone = UTC) -> DateTime:
79
+ return DateTime.now(tz)
80
+
81
+
82
+ def add_years(dt: DateTime, years: int) -> DateTime:
83
+ return dt.add(years=years)
84
+
85
+
86
+ def end_of_period(dt: DateTime, period: str) -> DateTime:
87
+ """
88
+ Returns the end of the specified unit of time.
89
+
90
+ Args:
91
+ dt: The datetime to get the end of.
92
+ period: The period to get the end of.
93
+ Valid values: 'second', 'minute', 'hour', 'day',
94
+ 'week', 'month', 'quarter', 'year'
95
+
96
+ Returns:
97
+ DateTime: A new DateTime representing the end of the specified unit.
98
+
99
+ Raises:
100
+ ValueError: If an invalid unit is specified.
101
+ """
102
+ return dt.end_of(period)
103
+
104
+
105
+ def start_of_period(dt: DateTime, period: str) -> DateTime:
106
+ """
107
+ Returns the start of the specified unit of time.
108
+
109
+ Args:
110
+ dt: The datetime to get the start of.
111
+ period: The period to get the start of.
112
+ Valid values: 'second', 'minute', 'hour', 'day',
113
+ 'week', 'month', 'quarter', 'year'
114
+
115
+ Returns:
116
+ DateTime: A new DateTime representing the start of the specified unit.
117
+
118
+ Raises:
119
+ ValueError: If an invalid unit is specified.
120
+ """
121
+ return dt.start_of(period)
122
+
123
+
124
+ def earliest_possible_datetime() -> DateTime:
125
+ return DateTime.instance(datetime.datetime.min)
@@ -11,11 +11,11 @@ from types import TracebackType
11
11
  from typing import TYPE_CHECKING, Any, Optional, TextIO, Union, cast
12
12
  from urllib.parse import urlsplit
13
13
 
14
- import pendulum
15
14
  from packaging.version import Version
16
15
  from typing_extensions import Self
17
16
 
18
17
  import prefect
18
+ from prefect.types._datetime import now
19
19
  from prefect.utilities.importtools import lazy_import
20
20
  from prefect.utilities.slugify import slugify
21
21
 
@@ -428,7 +428,7 @@ def push_image(
428
428
  """
429
429
 
430
430
  if not tag:
431
- tag = slugify(pendulum.now("utc").isoformat())
431
+ tag = slugify(now("UTC").isoformat())
432
432
 
433
433
  _, registry, _, _, _ = urlsplit(registry_url)
434
434
  repository = f"{registry}/{name}"
prefect/workers/base.py CHANGED
@@ -22,7 +22,6 @@ from uuid import UUID, uuid4
22
22
  import anyio
23
23
  import anyio.abc
24
24
  import httpx
25
- import pendulum
26
25
  from importlib_metadata import distributions
27
26
  from pydantic import BaseModel, Field, PrivateAttr, field_validator
28
27
  from pydantic.json_schema import GenerateJsonSchema
@@ -66,6 +65,7 @@ from prefect.states import (
66
65
  exception_to_failed_state,
67
66
  )
68
67
  from prefect.types import KeyValueLabels
68
+ from prefect.types._datetime import DateTime
69
69
  from prefect.utilities.dispatch import get_registry_for_type, register_base_type
70
70
  from prefect.utilities.engine import propose_state
71
71
  from prefect.utilities.services import critical_service_loop
@@ -458,7 +458,7 @@ class BaseWorker(abc.ABC, Generic[C, V, R]):
458
458
  self._exit_stack: AsyncExitStack = AsyncExitStack()
459
459
  self._runs_task_group: Optional[anyio.abc.TaskGroup] = None
460
460
  self._client: Optional[PrefectClient] = None
461
- self._last_polled_time: pendulum.DateTime = pendulum.now("utc")
461
+ self._last_polled_time: DateTime = DateTime.now("utc")
462
462
  self._limit = limit
463
463
  self._limiter: Optional[anyio.CapacityLimiter] = None
464
464
  self._submitting_flow_run_ids = set()
@@ -691,7 +691,7 @@ class BaseWorker(abc.ABC, Generic[C, V, R]):
691
691
  threshold_seconds = query_interval_seconds * 30
692
692
 
693
693
  seconds_since_last_poll = (
694
- pendulum.now("utc") - self._last_polled_time
694
+ DateTime.now("utc") - self._last_polled_time
695
695
  ).in_seconds()
696
696
 
697
697
  is_still_polling = seconds_since_last_poll <= threshold_seconds
@@ -707,7 +707,7 @@ class BaseWorker(abc.ABC, Generic[C, V, R]):
707
707
  async def get_and_submit_flow_runs(self) -> list["FlowRun"]:
708
708
  runs_response = await self._get_scheduled_flow_runs()
709
709
 
710
- self._last_polled_time = pendulum.now("utc")
710
+ self._last_polled_time = DateTime.now("utc")
711
711
 
712
712
  return await self._submit_scheduled_flow_runs(flow_run_response=runs_response)
713
713
 
@@ -856,7 +856,7 @@ class BaseWorker(abc.ABC, Generic[C, V, R]):
856
856
  """
857
857
  Retrieve scheduled flow runs from the work pool's queues.
858
858
  """
859
- scheduled_before = pendulum.now("utc").add(seconds=int(self._prefetch_seconds))
859
+ scheduled_before = DateTime.now("utc").add(seconds=int(self._prefetch_seconds))
860
860
  self._logger.debug(
861
861
  f"Querying for flow runs scheduled before {scheduled_before}"
862
862
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: prefect-client
3
- Version: 3.2.1
3
+ Version: 3.2.2
4
4
  Summary: Workflow orchestration and management.
5
5
  Home-page: https://www.prefect.io
6
6
  Author: Prefect Technologies, Inc.
@@ -1,19 +1,19 @@
1
1
  prefect/.prefectignore,sha256=awSprvKT0vI8a64mEOLrMxhxqcO-b0ERQeYpA2rNKVQ,390
2
2
  prefect/__init__.py,sha256=FmdMSNpGH8Mrkn5X0mNZup8_SHdeB_aqEmS5taeOHAQ,3530
3
3
  prefect/__main__.py,sha256=WFjw3kaYJY6pOTA7WDOgqjsz8zUEUZHCcj3P5wyVa-g,66
4
- prefect/_result_records.py,sha256=d6VWsJuXEM645kFm3y9J3j1lKGmFY2OihyBp-WEQmQA,7584
5
- prefect/_version.py,sha256=t1hNzonzGvks3WeozTF7c1ud2j6kgIXJ21ijVHd6gv8,496
4
+ prefect/_result_records.py,sha256=S6QmsODkehGVSzbMm6ig022PYbI6gNKz671p_8kBYx4,7789
5
+ prefect/_version.py,sha256=fkGKjBZxa9euBDaB1-Et12BbPmFVnGW9hKhhKf3SSQs,496
6
6
  prefect/agent.py,sha256=dPvG1jDGD5HSH7aM2utwtk6RaJ9qg13XjkA0lAIgQmY,287
7
7
  prefect/artifacts.py,sha256=dMBUOAWnUamzjb5HSqwB5-GR2Qb-Gxee26XG5NDCUuw,22720
8
8
  prefect/automations.py,sha256=ZzPxn2tINdlXTQo805V4rIlbXuNWxd7cdb3gTJxZIeY,12567
9
9
  prefect/cache_policies.py,sha256=cF_6eqg34x7XgaCIw6S8Vr-Eq0wIr4Y6t3FOuXaPBrY,11912
10
10
  prefect/context.py,sha256=iJe4pkFqX6lz8ax1Mde_YqVmBVWmzeBe0ca2_nT6KPQ,23673
11
- prefect/engine.py,sha256=g-Hf2FfhMOncLiGhT-rCN142Yx6JmcL-r3zYak_MCX8,2609
11
+ prefect/engine.py,sha256=4ZGTKFZA_t7K0XUSJqbJ6Ec20SFVFHasBTM--47fTyA,2610
12
12
  prefect/exceptions.py,sha256=-nih8qqdxRm6CX-4yrqwePVh8Mcpvla_V6N_KbdJsIU,11593
13
13
  prefect/filesystems.py,sha256=v5YqGB4uXf9Ew2VuB9VCSkawvYMMVvEtZf7w1VmAmr8,18036
14
14
  prefect/flow_engine.py,sha256=mW95w_fBpEPejYFXuMyjfnhm7J1jMSv_VtAYGD0VlCo,60226
15
15
  prefect/flow_runs.py,sha256=MzjfRFgQwOqUSC3Iuu6E0hWkWdn089Urk6BY3qjEwEE,16113
16
- prefect/flows.py,sha256=AnMGp25Xb1weSC9iBGinH8k2ro8MaqsQbxLWGoqY9b4,108215
16
+ prefect/flows.py,sha256=cp9TF3pSg73jhkL3SkzaUGbdU9hbsieKz95Wgfk-VA4,108408
17
17
  prefect/futures.py,sha256=NYWGeC8uRGe1WWB1MxkUshdvAdYibhc32HdFjffdiW0,17217
18
18
  prefect/main.py,sha256=9NFSloSmrOgzXg_Pwh_m31deeZj4jorfpx1pUZqWNi8,2359
19
19
  prefect/plugins.py,sha256=FPRLR2mWVBMuOnlzeiTD9krlHONZH2rtYLD753JQDNQ,2516
@@ -21,8 +21,8 @@ prefect/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
21
  prefect/results.py,sha256=gAcYivq5CN8oL5CWu8cJe2560i0M8I5GL-8RcBTJ6VI,36385
22
22
  prefect/schedules.py,sha256=9ufG4jhIA_R7vS9uXqnnZEgB7Ts922KMhNacWcveVgA,7291
23
23
  prefect/serializers.py,sha256=QI0oEal_BO4HQaWSjr6ReSwT55Hn4sbSOXxGgQI1-y0,9249
24
- prefect/states.py,sha256=pfhwuCLF6rb7JXdAj7s_NdZInyPGGbkxjvgqmNqj6ic,26959
25
- prefect/task_engine.py,sha256=12LfvrqEkUePDFrmg2WluEzyxigPDpYRSUxGGWV_65Q,60707
24
+ prefect/states.py,sha256=tTZrN-IZKvmFcN8FR_4L-X-ZrmXi6z-cPXl6KdOy-XI,26920
25
+ prefect/task_engine.py,sha256=BF7dZPgIMgq2XeNe6GHHyqPTrCfJN2ZDfETOvedvbw8,60683
26
26
  prefect/task_runners.py,sha256=Ce_ngocfq_X-NA5zhPj13IdVmzZ5h6gXlmfxYWs2AXA,15828
27
27
  prefect/task_runs.py,sha256=7LIzfo3fondCyEUpU05sYFN5IfpZigBDXrhG5yc-8t0,9039
28
28
  prefect/task_worker.py,sha256=FkAp6PhRwBcAW2YigJORiN7A-PAwzWa1nM-osZD4Syw,17793
@@ -61,10 +61,10 @@ prefect/_internal/pydantic/v2_validated_func.py,sha256=Ld8OtPFF7Ci-gHHmKhSMizBxz
61
61
  prefect/_internal/pydantic/annotations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
62
  prefect/_internal/pydantic/annotations/pendulum.py,sha256=KTh6w32-S9MXHywwNod9aA7v-VN7a3AWiSZh4vDRkx0,2683
63
63
  prefect/_internal/schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
- prefect/_internal/schemas/bases.py,sha256=kKyEkEbeHfTwXz6YXFPbTaHiRyl1qLoZuRtnKLneMOA,4346
64
+ prefect/_internal/schemas/bases.py,sha256=UpGMovMZe8z2VxqeqIjFLwWYPNLa7rdeeGamRwZH2qw,4286
65
65
  prefect/_internal/schemas/fields.py,sha256=m4LrFNz8rA9uBhMk9VyQT6FIXmV_EVAW92hdXeSvHbY,837
66
66
  prefect/_internal/schemas/serializers.py,sha256=G_RGHfObjisUiRvd29p-zc6W4bwt5rE1OdR6TXNrRhQ,825
67
- prefect/_internal/schemas/validators.py,sha256=1Pa3U2gCqhoJShJuzjGuC09uM8BUvnmAGtNDI7zzi_0,19488
67
+ prefect/_internal/schemas/validators.py,sha256=i-MdHhmP1S8UQG4dZuHIwbqiM_O95g_Ghn0BcehDaaU,19511
68
68
  prefect/blocks/__init__.py,sha256=D0hB72qMfgqnBB2EMZRxUxlX9yLfkab5zDChOwJZmkY,220
69
69
  prefect/blocks/abstract.py,sha256=mpOAWopSR_RrzdxeurBTXVSKisP8ne-k8LYos-tp7go,17021
70
70
  prefect/blocks/core.py,sha256=CgxU59KUWiHLWUdTxOSDOfHkfFAyjLXc7eibmFc_xCo,62186
@@ -80,7 +80,7 @@ prefect/client/collections.py,sha256=t9XkVU_onQMZ871L21F1oZnAiPSQeeVfd_MuDEBS3iM
80
80
  prefect/client/constants.py,sha256=Z_GG8KF70vbbXxpJuqW5pLnwzujTVeHbcYYRikNmGH0,29
81
81
  prefect/client/subscriptions.py,sha256=TZ7Omv8yeQQIkE6EmWYM78e8p7UdvdTDzcQe91dCU4U,3838
82
82
  prefect/client/utilities.py,sha256=UEJD6nwYg2mD8-GSmru-E2ofXaBlmSFZ2-8T_5rIK6c,3472
83
- prefect/client/orchestration/__init__.py,sha256=4oqdQW_IvA5f6s-es9bQRXMd-ln3212un6klIqnkoEI,59343
83
+ prefect/client/orchestration/__init__.py,sha256=-v9MvHGYEdDXAKVeiwujiZmTn37M_Q8gN3V03auls0Q,59382
84
84
  prefect/client/orchestration/base.py,sha256=HM6ryHBZSzuHoCFQM9u5qR5k1dN9Bbr_ah6z1UPNbZQ,1542
85
85
  prefect/client/orchestration/routes.py,sha256=JFG1OWUBfrxPKW8Q7XWItlhOrSZ67IOySSoFZ6mxzm0,4364
86
86
  prefect/client/orchestration/_artifacts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -112,28 +112,28 @@ prefect/client/schemas/actions.py,sha256=yzP6oC0_h6LV78s47ltX1bqxu6bju0Eav5VgB-V
112
112
  prefect/client/schemas/filters.py,sha256=zaiDkalrIpKjd38V4aP1GHlqD24KTPCZiKtPyX69ZWE,36607
113
113
  prefect/client/schemas/objects.py,sha256=ZHLu4ycTYee7Y1LqM2MZgYszQClnpMuMTXIrYewu4zQ,57034
114
114
  prefect/client/schemas/responses.py,sha256=iTXTiUhdRL7PxNyJXMZ4ngT7C8SepT_z7g_pnUnVlzo,15629
115
- prefect/client/schemas/schedules.py,sha256=KSKk7Nmtr_x-yMrfnsSFTYvI14YFepI5b_vabkLqdaQ,14755
115
+ prefect/client/schemas/schedules.py,sha256=4a1lGun448em33zrc0ZUOAew3jB8yqJ7Cxoni3HKR3I,14721
116
116
  prefect/client/schemas/sorting.py,sha256=L-2Mx-igZPtsUoRUguTcG3nIEstMEMPD97NwPM2Ox5s,2579
117
117
  prefect/client/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
118
118
  prefect/client/types/flexible_schedule_list.py,sha256=eNom7QiRxMnyTD1q30bR7kQh3-2sLhxIKe5ST9o6GI4,425
119
119
  prefect/concurrency/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
120
120
  prefect/concurrency/_asyncio.py,sha256=XfiKES0DOEfjHdjQ43NNWH6kdTt6a2Oj_PzxQ8sZ8IY,3004
121
121
  prefect/concurrency/_events.py,sha256=KWHDldCWE3b5AH9eZ7kfmajvp36lRFCjCXIEx77jtKk,1825
122
- prefect/concurrency/asyncio.py,sha256=T4Ut_rIoxzigHY740wbzH1UIqT5kQv2ZvqMfv0bNctc,4680
122
+ prefect/concurrency/asyncio.py,sha256=UJ8tXNFU32_CD4B6coxSEImSWdmjA4mwlyr_6gDPTh0,4687
123
123
  prefect/concurrency/context.py,sha256=8ZXs3G7NOF5Q2NqydK-K3zfjmYNnmfer-25hH6r6MgA,1009
124
124
  prefect/concurrency/services.py,sha256=9db7VgASPLpDB8apEcmr4te75eyaXnycry8N4OhNAB8,2415
125
- prefect/concurrency/sync.py,sha256=f4JQGR5_yVsZHdg_CGGbvpynmpxmTc1gqwc_xynyGJ8,4928
125
+ prefect/concurrency/sync.py,sha256=-r5_OF0PprYoJHiRe0VHFUefUMk1OzRSr18ZxA-GcnM,4934
126
126
  prefect/concurrency/v1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
127
127
  prefect/concurrency/v1/_asyncio.py,sha256=UTFjkOPevvbazzpf-O6sSixwM0gs_GzK5zwH4EG4FJ8,2152
128
128
  prefect/concurrency/v1/_events.py,sha256=eoNmtlt__EqhgImWyxfq_MxwTRqNznJU9-3sKwThc98,1863
129
- prefect/concurrency/v1/asyncio.py,sha256=GcdrqEye97qCjqWnEx2DIu38Zls5Mf2w0ofVpwtDriM,3168
129
+ prefect/concurrency/v1/asyncio.py,sha256=Jbir8gwf7OOBmDh6VblzUV-TUBsTkDL78EvnLPHLAKc,3174
130
130
  prefect/concurrency/v1/context.py,sha256=BhK63TYp9BQYRCgTI1onUPXmgBoYaP7o27U695lH7qk,1107
131
131
  prefect/concurrency/v1/services.py,sha256=ppVCllzb2qeKc-xntobFu45dEh3J-ZTtLDPuHr1djxo,2958
132
- prefect/concurrency/v1/sync.py,sha256=C5uPmW2pWdt3bu1KVQkYf_IscjSzY_VhgR9AZJkkIa8,2106
132
+ prefect/concurrency/v1/sync.py,sha256=N_CHNkbV_eNQvDsJoJaehQo8H68MFlX6B1ObDZuYlTM,2112
133
133
  prefect/deployments/__init__.py,sha256=_wb7NxDKhq11z9MjYsPckmT3o6MRhGLRgCV9TmvYtew,1002
134
134
  prefect/deployments/base.py,sha256=KEc07W35yyzGJcV6GIZry8bKcNfvQk6JjJ99KKB6XpQ,11729
135
135
  prefect/deployments/deployments.py,sha256=K3Rgnpjxo_T8I8LMwlq24OKqZiZBTE8-YnPg-YGUStM,171
136
- prefect/deployments/flow_runs.py,sha256=aQcUKTnzCMUheMZ052xjQhGd-BhtXTnxpOdUAEM37r4,7212
136
+ prefect/deployments/flow_runs.py,sha256=VunxRsw4DyqVJHNjooDAPGJaGvSGucLX83SaxHO8ugU,7227
137
137
  prefect/deployments/runner.py,sha256=lgLvp759BhDJtuF8LeNZFqJZT8dxJxF6SH9Jq_NYFl0,53835
138
138
  prefect/deployments/schedules.py,sha256=2eL1-w8qXtwKVkgfUK7cuamwpKK3X6tN1QYTDa_gWxU,2190
139
139
  prefect/deployments/steps/__init__.py,sha256=Dlz9VqMRyG1Gal8dj8vfGpPr0LyQhZdvcciozkK8WoY,206
@@ -141,12 +141,12 @@ prefect/deployments/steps/core.py,sha256=ulSgBFSx1lhBt1fP-UxebrernkumBDlympR6IPf
141
141
  prefect/deployments/steps/pull.py,sha256=MDN8nHklgU6MXNMsMRDLDVbIqod87ccPJdt-21dshvU,9767
142
142
  prefect/deployments/steps/utility.py,sha256=Ap_p44Rwz9Lxd6pt8hDW8phF3gwI3YjbsSpWHALDyoM,8157
143
143
  prefect/docker/__init__.py,sha256=z6wdc6UFfiBG2jb9Jk64uCWVM04JKVWeVyDWwuuon8M,527
144
- prefect/docker/docker_image.py,sha256=0PZjUCTe_20Zsrg-LtADV4HmPnAYzq7QdXRl22WK40M,3103
144
+ prefect/docker/docker_image.py,sha256=cdvUEokGJXZDugfCekfmrhhpzrxTEW-FvWa2kDs5tVM,3092
145
145
  prefect/events/__init__.py,sha256=GtKl2bE--pJduTxelH2xy7SadlLJmmis8WR1EYixhuA,2094
146
146
  prefect/events/actions.py,sha256=A7jS8bo4zWGnrt3QfSoQs0uYC1xfKXio3IfU0XtTb5s,9129
147
- prefect/events/clients.py,sha256=_BSO4sZEcbJ9j2NhAAT9rtgyspg00g53PIuy2zhdM10,26827
147
+ prefect/events/clients.py,sha256=91_bT-JIkXcBmakuSYpfAftFNoy-iFVUNrftbcGOUPY,26879
148
148
  prefect/events/filters.py,sha256=h9L6pukS9tD7Y8rGC3dt04KJINu0oJoti-flGLQTQQQ,8086
149
- prefect/events/related.py,sha256=A-1SVYwHtsxaDurRepnTsYbTWRBJSbtL5O_KffLaTwU,6534
149
+ prefect/events/related.py,sha256=Uh6-MoVENvP9dYYhjstb7eHesQUoDp-2PTMSP0nhPDI,6545
150
150
  prefect/events/utilities.py,sha256=4Bz-xiTOzi_EeDyIL9BzI7eMbRbBIIyayNvfO_BFyTw,2632
151
151
  prefect/events/worker.py,sha256=HjbibR0_J1W1nnNMZDFTXAbB0cl_cFGaFI87DvNGcnI,4557
152
152
  prefect/events/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -168,14 +168,14 @@ prefect/input/__init__.py,sha256=Ue2h-YhYP71nEtsVJaslqMwO6C0ckjhjTYwwEgp-E3g,701
168
168
  prefect/input/actions.py,sha256=BDx26b6ZYCTr0kbWBp73Or7UXnLIv1lnm0jow6Simxw,3871
169
169
  prefect/input/run_input.py,sha256=GoM4LR3oqAFLf2sPCR1yITY9tNSZT8kAd4gaC-v-a-c,22703
170
170
  prefect/locking/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
171
- prefect/locking/filesystem.py,sha256=RExiv3GDK-wYQfWbNVYKtf-aaPI3-I6CL5z2QICaMGk,8145
171
+ prefect/locking/filesystem.py,sha256=O67Miiz466fQUu3UmHer9dkWpVL1f8GEX8Lv2lDj0Y8,8113
172
172
  prefect/locking/memory.py,sha256=mFUgV750ywEL7aVQuxFjg9gxbjVU4esBQn7bGQYzeMY,7548
173
173
  prefect/locking/protocol.py,sha256=RsfvlaHTTEJ0YvYWSqFGoZuT2w4FPPxyQlHqjoyNGuE,4240
174
174
  prefect/logging/__init__.py,sha256=zx9f5_dWrR4DbcTOFBpNGOPoCZ1QcPFudr7zxb2XRpA,148
175
175
  prefect/logging/configuration.py,sha256=QIvmktuAZPteVnh8nd9jUb7vwGGkcUbBLyiti6XmbYM,3242
176
176
  prefect/logging/filters.py,sha256=NnRYubh9dMmWcCAjuW32cIVQ37rLxdn8ci26wTtQMyU,1136
177
177
  prefect/logging/formatters.py,sha256=BkPykVyOFKdnhDj_1vhhOoWiHiiBeRnWXPcaRIWK3aI,4125
178
- prefect/logging/handlers.py,sha256=XFqpZbAX6M5imW_87uZgf2NXMFB4ZfMvq5A-WQRRwNM,12250
178
+ prefect/logging/handlers.py,sha256=pIeS6gvuVnuh3lZ-kIC4ijRMSbVPkHo-rYeLMj5P8NA,12240
179
179
  prefect/logging/highlighters.py,sha256=BCf_LNhFInIfGPqwuu8YVrGa4wVxNc4YXo2pYgftpg4,1811
180
180
  prefect/logging/loggers.py,sha256=xkmHXsiuoPZZXcrrEgMA-ZQu0E-gW3tNVd4BIxWjnpM,12704
181
181
  prefect/logging/logging.yml,sha256=tT7gTyC4NmngFSqFkCdHaw7R0GPNPDDsTCGZQByiJAQ,3169
@@ -187,7 +187,7 @@ prefect/runner/submit.py,sha256=3Ey6H4XrhYhCII4AobpvzZf21vAunWlMu40zAjMC0gc,8353
187
187
  prefect/runner/utils.py,sha256=MLtoouDD6bh-JAIz0W3fMofKXEt0VfGsg6d8jf45OA0,3280
188
188
  prefect/runtime/__init__.py,sha256=JswiTlYRup2zXOYu8AqJ7czKtgcw9Kxo0tTbS6aWCqY,407
189
189
  prefect/runtime/deployment.py,sha256=0A_cUVpYiFk3ciJw2ixy95dk9xBJcjisyF69pakSCcQ,5091
190
- prefect/runtime/flow_run.py,sha256=YTUYOgJ1ADyarYySsuL4GL2s0Iq-fy3956sf4Z3QIU4,10564
190
+ prefect/runtime/flow_run.py,sha256=hBa6h99G9K5iHdDUvHoJ2Yg9h5cZVEe_OEEJ2VuJHwk,10557
191
191
  prefect/runtime/task_run.py,sha256=zYBSs7QrAu7c2IjKomRzPXKyIXrjqclMTMrco-dwyOw,4212
192
192
  prefect/server/api/collections_data/views/aggregate-worker-metadata.json,sha256=gqrwGyylzBEzlFSPOJcMuUwdoK_zojpU0SZaBDgK5FE,79748
193
193
  prefect/server/api/static/prefect-logo-mark-gradient.png,sha256=ylRjJkI_JHCw8VbQasNnXQHwZW-sH-IQiUGSD3aWP1E,73430
@@ -234,7 +234,7 @@ prefect/telemetry/processors.py,sha256=jw6j6LviOVxw3IBJe7cSjsxFk0zzY43jUmy6C9pcf
234
234
  prefect/telemetry/run_telemetry.py,sha256=NcMVqOc_wQVGPlGpE8cfrz-lyCbkG1EOKpcbjsqMnGA,8264
235
235
  prefect/telemetry/services.py,sha256=DxgNNDTeWNtHBtioX8cjua4IrCbTiJJdYecx-gugg-w,2358
236
236
  prefect/types/__init__.py,sha256=yBjKxiQmSC7jXoo0UNmM3KZil1NBFS-BWGPfwSEaoJo,4621
237
- prefect/types/_datetime.py,sha256=S34IQdm5sIzZ1B3YKkCnCYlQSSadcenswKU3xjWH0JA,1298
237
+ prefect/types/_datetime.py,sha256=eOsg5gkm4bATLWvK4lmLqHByxQdER6gfTFyafzj-DLk,3343
238
238
  prefect/types/entrypoint.py,sha256=2FF03-wLPgtnqR_bKJDB2BsXXINPdu8ptY9ZYEZnXg8,328
239
239
  prefect/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
240
240
  prefect/utilities/_deprecated.py,sha256=b3pqRSoFANdVJAc8TJkygBcP-VjZtLJUxVIWC7kwspI,1303
@@ -247,7 +247,7 @@ prefect/utilities/collections.py,sha256=yMZyRD9j6m3Fd3wm4-HR2r3o7B02AC_MDQZUWsX3
247
247
  prefect/utilities/compat.py,sha256=nnPA3lf2f4Y-l645tYFFNmj5NDPaYvjqa9pbGKZ3WKE,582
248
248
  prefect/utilities/context.py,sha256=23SDMgdt07SjmB1qShiykHfGgiv55NBzdbMXM3fE9CI,1447
249
249
  prefect/utilities/dispatch.py,sha256=u6GSGSO3_6vVoIqHVc849lsKkC-I1wUl6TX134GwRBo,6310
250
- prefect/utilities/dockerutils.py,sha256=R9LN3qsg-ZEw_KH9C3y5wItYPC-MiP7AiwWMUiLvDt4,20863
250
+ prefect/utilities/dockerutils.py,sha256=pQ5rJTDX6xXBzr_wFcCmcPo88YPjRp54YHf39iOnkPY,20878
251
251
  prefect/utilities/engine.py,sha256=wbQpwuAnLrk6yfgOWkip00tljweRn-OODE2NaQBtLAY,28971
252
252
  prefect/utilities/filesystem.py,sha256=Pwesv71PGFhf3lPa1iFyMqZZprBjy9nEKCVxTkf_hXw,5710
253
253
  prefect/utilities/generics.py,sha256=o77e8a5iwmrisOf42wLp2WI9YvSw2xDW4vFdpdEwr3I,543
@@ -269,14 +269,14 @@ prefect/utilities/schema_tools/__init__.py,sha256=At3rMHd2g_Em2P3_dFQlFgqR_EpBwr
269
269
  prefect/utilities/schema_tools/hydration.py,sha256=NkRhWkNfxxFmVGhNDfmxdK_xeKaEhs3a42q83Sg9cT4,9436
270
270
  prefect/utilities/schema_tools/validation.py,sha256=Wix26IVR-ZJ32-6MX2pHhrwm3reB-Q4iB6_phn85OKE,10743
271
271
  prefect/workers/__init__.py,sha256=EaM1F0RZ-XIJaGeTKLsXDnfOPHzVWk5bk0_c4BVS44M,64
272
- prefect/workers/base.py,sha256=izJmvDo_wtnI0vh2ihZbjYenRhpPuEWRuH3jKeph_Y8,49922
272
+ prefect/workers/base.py,sha256=_kJlVnuia2jCGklRGUxur2SSi9uFFqkMouiWlJIJrsI,49942
273
273
  prefect/workers/block.py,sha256=dPvG1jDGD5HSH7aM2utwtk6RaJ9qg13XjkA0lAIgQmY,287
274
274
  prefect/workers/cloud.py,sha256=dPvG1jDGD5HSH7aM2utwtk6RaJ9qg13XjkA0lAIgQmY,287
275
275
  prefect/workers/process.py,sha256=6VWon_LK7fQNLlQTjTBFeU4KFUa4faqP4EUuTvrbtbg,20176
276
276
  prefect/workers/server.py,sha256=SEuyScZ5nGm2OotdtbHjpvqJlTRVWCh29ND7FeL_fZA,1974
277
277
  prefect/workers/utilities.py,sha256=VfPfAlGtTuDj0-Kb8WlMgAuOfgXCdrGAnKMapPSBrwc,2483
278
- prefect_client-3.2.1.dist-info/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
279
- prefect_client-3.2.1.dist-info/METADATA,sha256=y0SU-d6cL0dgjIh2tGQ-t4YndTcIdiE0vxh0keXB5aI,7286
280
- prefect_client-3.2.1.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
281
- prefect_client-3.2.1.dist-info/top_level.txt,sha256=MJZYJgFdbRc2woQCeB4vM6T33tr01TmkEhRcns6H_H4,8
282
- prefect_client-3.2.1.dist-info/RECORD,,
278
+ prefect_client-3.2.2.dist-info/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
279
+ prefect_client-3.2.2.dist-info/METADATA,sha256=RM2qBP1NrJKtLqvQlzLinyY95gETGMdAIIQGg1Zk5CU,7286
280
+ prefect_client-3.2.2.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
281
+ prefect_client-3.2.2.dist-info/top_level.txt,sha256=MJZYJgFdbRc2woQCeB4vM6T33tr01TmkEhRcns6H_H4,8
282
+ prefect_client-3.2.2.dist-info/RECORD,,