prefect-client 3.4.5.dev4__py3-none-any.whl → 3.4.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- prefect/_build_info.py +3 -3
- prefect/assets/__init__.py +4 -0
- prefect/assets/core.py +75 -0
- prefect/assets/materialize.py +42 -0
- prefect/context.py +246 -2
- prefect/deployments/runner.py +2 -2
- prefect/events/clients.py +2 -2
- prefect/runner/server.py +2 -2
- prefect/runner/submit.py +2 -2
- prefect/server/api/events.py +1 -1
- prefect/server/api/task_workers.py +1 -1
- prefect/server/api/templates.py +8 -2
- prefect/settings/models/server/services.py +26 -0
- prefect/settings/profiles.py +41 -30
- prefect/task_engine.py +107 -29
- prefect/tasks.py +126 -30
- prefect/types/__init__.py +2 -0
- prefect/types/_datetime.py +2 -2
- prefect/types/names.py +23 -0
- prefect/utilities/callables.py +13 -11
- prefect/utilities/engine.py +15 -3
- {prefect_client-3.4.5.dev4.dist-info → prefect_client-3.4.6.dist-info}/METADATA +2 -2
- {prefect_client-3.4.5.dev4.dist-info → prefect_client-3.4.6.dist-info}/RECORD +25 -22
- {prefect_client-3.4.5.dev4.dist-info → prefect_client-3.4.6.dist-info}/WHEEL +0 -0
- {prefect_client-3.4.5.dev4.dist-info → prefect_client-3.4.6.dist-info}/licenses/LICENSE +0 -0
prefect/tasks.py
CHANGED
@@ -29,10 +29,20 @@ from typing import (
|
|
29
29
|
)
|
30
30
|
from uuid import UUID, uuid4
|
31
31
|
|
32
|
-
from typing_extensions import
|
32
|
+
from typing_extensions import (
|
33
|
+
Literal,
|
34
|
+
ParamSpec,
|
35
|
+
Self,
|
36
|
+
Sequence,
|
37
|
+
TypeAlias,
|
38
|
+
TypedDict,
|
39
|
+
TypeIs,
|
40
|
+
Unpack,
|
41
|
+
)
|
33
42
|
|
34
43
|
import prefect.states
|
35
44
|
from prefect._internal.uuid7 import uuid7
|
45
|
+
from prefect.assets import Asset
|
36
46
|
from prefect.cache_policies import DEFAULT, NO_CACHE, CachePolicy
|
37
47
|
from prefect.client.orchestration import get_client
|
38
48
|
from prefect.client.schemas import TaskRun
|
@@ -90,6 +100,65 @@ OneOrManyFutureOrResult: TypeAlias = Union[
|
|
90
100
|
]
|
91
101
|
|
92
102
|
|
103
|
+
class TaskRunNameCallbackWithParameters(Protocol):
|
104
|
+
@classmethod
|
105
|
+
def is_callback_with_parameters(cls, callable: Callable[..., str]) -> TypeIs[Self]:
|
106
|
+
sig = inspect.signature(callable)
|
107
|
+
return "parameters" in sig.parameters
|
108
|
+
|
109
|
+
def __call__(self, parameters: dict[str, Any]) -> str: ...
|
110
|
+
|
111
|
+
|
112
|
+
StateHookCallable: TypeAlias = Callable[
|
113
|
+
["Task[..., Any]", TaskRun, State], Union[Awaitable[None], None]
|
114
|
+
]
|
115
|
+
RetryConditionCallable: TypeAlias = Callable[
|
116
|
+
["Task[..., Any]", TaskRun, State], Union[Awaitable[bool], bool]
|
117
|
+
]
|
118
|
+
TaskRunNameValueOrCallable: TypeAlias = Union[
|
119
|
+
Callable[[], str], TaskRunNameCallbackWithParameters, str
|
120
|
+
]
|
121
|
+
|
122
|
+
|
123
|
+
class TaskOptions(TypedDict, total=False):
|
124
|
+
"""
|
125
|
+
A TypedDict representing all available task configuration options.
|
126
|
+
|
127
|
+
This can be used with `Unpack` to provide type hints for **kwargs.
|
128
|
+
"""
|
129
|
+
|
130
|
+
name: Optional[str]
|
131
|
+
description: Optional[str]
|
132
|
+
tags: Optional[Iterable[str]]
|
133
|
+
version: Optional[str]
|
134
|
+
cache_policy: Union[CachePolicy, type[NotSet]]
|
135
|
+
cache_key_fn: Union[
|
136
|
+
Callable[["TaskRunContext", dict[str, Any]], Optional[str]], None
|
137
|
+
]
|
138
|
+
cache_expiration: Optional[datetime.timedelta]
|
139
|
+
task_run_name: Optional[TaskRunNameValueOrCallable]
|
140
|
+
retries: Optional[int]
|
141
|
+
retry_delay_seconds: Union[
|
142
|
+
float, int, list[float], Callable[[int], list[float]], None
|
143
|
+
]
|
144
|
+
retry_jitter_factor: Optional[float]
|
145
|
+
persist_result: Optional[bool]
|
146
|
+
result_storage: Optional[ResultStorage]
|
147
|
+
result_serializer: Optional[ResultSerializer]
|
148
|
+
result_storage_key: Optional[str]
|
149
|
+
cache_result_in_memory: bool
|
150
|
+
timeout_seconds: Union[int, float, None]
|
151
|
+
log_prints: Optional[bool]
|
152
|
+
refresh_cache: Optional[bool]
|
153
|
+
on_completion: Optional[list[StateHookCallable]]
|
154
|
+
on_failure: Optional[list[StateHookCallable]]
|
155
|
+
on_rollback: Optional[list[Callable[["Transaction"], None]]]
|
156
|
+
on_commit: Optional[list[Callable[["Transaction"], None]]]
|
157
|
+
retry_condition_fn: Optional[RetryConditionCallable]
|
158
|
+
viz_return_value: Any
|
159
|
+
asset_deps: Optional[list[Union[Asset, str]]]
|
160
|
+
|
161
|
+
|
93
162
|
def task_input_hash(
|
94
163
|
context: "TaskRunContext", arguments: dict[str, Any]
|
95
164
|
) -> Optional[str]:
|
@@ -223,23 +292,6 @@ def _generate_task_key(fn: Callable[..., Any]) -> str:
|
|
223
292
|
return f"{qualname}-{code_hash}"
|
224
293
|
|
225
294
|
|
226
|
-
class TaskRunNameCallbackWithParameters(Protocol):
|
227
|
-
@classmethod
|
228
|
-
def is_callback_with_parameters(cls, callable: Callable[..., str]) -> TypeIs[Self]:
|
229
|
-
sig = inspect.signature(callable)
|
230
|
-
return "parameters" in sig.parameters
|
231
|
-
|
232
|
-
def __call__(self, parameters: dict[str, Any]) -> str: ...
|
233
|
-
|
234
|
-
|
235
|
-
StateHookCallable: TypeAlias = Callable[
|
236
|
-
["Task[..., Any]", TaskRun, State], Union[Awaitable[None], None]
|
237
|
-
]
|
238
|
-
TaskRunNameValueOrCallable: TypeAlias = Union[
|
239
|
-
Callable[[], str], TaskRunNameCallbackWithParameters, str
|
240
|
-
]
|
241
|
-
|
242
|
-
|
243
295
|
class Task(Generic[P, R]):
|
244
296
|
"""
|
245
297
|
A Prefect task definition.
|
@@ -311,6 +363,7 @@ class Task(Generic[P, R]):
|
|
311
363
|
should end as failed. Defaults to `None`, indicating the task should always continue
|
312
364
|
to its retry policy.
|
313
365
|
viz_return_value: An optional value to return when the task dependency tree is visualized.
|
366
|
+
asset_deps: An optional list of upstream assets that this task depends on.
|
314
367
|
"""
|
315
368
|
|
316
369
|
# NOTE: These parameters (types, defaults, and docstrings) should be duplicated
|
@@ -350,10 +403,9 @@ class Task(Generic[P, R]):
|
|
350
403
|
on_failure: Optional[list[StateHookCallable]] = None,
|
351
404
|
on_rollback: Optional[list[Callable[["Transaction"], None]]] = None,
|
352
405
|
on_commit: Optional[list[Callable[["Transaction"], None]]] = None,
|
353
|
-
retry_condition_fn: Optional[
|
354
|
-
Callable[["Task[..., Any]", TaskRun, State], bool]
|
355
|
-
] = None,
|
406
|
+
retry_condition_fn: Optional[RetryConditionCallable] = None,
|
356
407
|
viz_return_value: Optional[Any] = None,
|
408
|
+
asset_deps: Optional[list[Union[str, Asset]]] = None,
|
357
409
|
):
|
358
410
|
# Validate if hook passed is list and contains callables
|
359
411
|
hook_categories = [on_completion, on_failure]
|
@@ -547,6 +599,14 @@ class Task(Generic[P, R]):
|
|
547
599
|
self.retry_condition_fn = retry_condition_fn
|
548
600
|
self.viz_return_value = viz_return_value
|
549
601
|
|
602
|
+
from prefect.assets import Asset
|
603
|
+
|
604
|
+
self.asset_deps: list[Asset] = (
|
605
|
+
[Asset(key=a) if isinstance(a, str) else a for a in asset_deps]
|
606
|
+
if asset_deps
|
607
|
+
else []
|
608
|
+
)
|
609
|
+
|
550
610
|
@property
|
551
611
|
def ismethod(self) -> bool:
|
552
612
|
return hasattr(self.fn, "__prefect_self__")
|
@@ -613,10 +673,9 @@ class Task(Generic[P, R]):
|
|
613
673
|
refresh_cache: Union[bool, type[NotSet]] = NotSet,
|
614
674
|
on_completion: Optional[list[StateHookCallable]] = None,
|
615
675
|
on_failure: Optional[list[StateHookCallable]] = None,
|
616
|
-
retry_condition_fn: Optional[
|
617
|
-
Callable[["Task[..., Any]", TaskRun, State], bool]
|
618
|
-
] = None,
|
676
|
+
retry_condition_fn: Optional[RetryConditionCallable] = None,
|
619
677
|
viz_return_value: Optional[Any] = None,
|
678
|
+
asset_deps: Optional[list[Union[str, Asset]]] = None,
|
620
679
|
) -> "Task[P, R]":
|
621
680
|
"""
|
622
681
|
Create a new task from the current object, updating provided options.
|
@@ -750,6 +809,7 @@ class Task(Generic[P, R]):
|
|
750
809
|
on_failure=on_failure or self.on_failure_hooks,
|
751
810
|
retry_condition_fn=retry_condition_fn or self.retry_condition_fn,
|
752
811
|
viz_return_value=viz_return_value or self.viz_return_value,
|
812
|
+
asset_deps=asset_deps or self.asset_deps,
|
753
813
|
)
|
754
814
|
|
755
815
|
def on_completion(self, fn: StateHookCallable) -> StateHookCallable:
|
@@ -887,7 +947,9 @@ class Task(Generic[P, R]):
|
|
887
947
|
deferred: bool = False,
|
888
948
|
) -> TaskRun:
|
889
949
|
from prefect.utilities._engine import dynamic_key_for_task_run
|
890
|
-
from prefect.utilities.engine import
|
950
|
+
from prefect.utilities.engine import (
|
951
|
+
collect_task_run_inputs_sync,
|
952
|
+
)
|
891
953
|
|
892
954
|
if flow_run_context is None:
|
893
955
|
flow_run_context = FlowRunContext.get()
|
@@ -927,7 +989,7 @@ class Task(Generic[P, R]):
|
|
927
989
|
|
928
990
|
store = await ResultStore(
|
929
991
|
result_storage=await get_or_create_default_task_scheduling_storage()
|
930
|
-
).update_for_task(
|
992
|
+
).update_for_task(self)
|
931
993
|
context = serialize_context()
|
932
994
|
data: dict[str, Any] = {"context": context}
|
933
995
|
if parameters:
|
@@ -963,6 +1025,7 @@ class Task(Generic[P, R]):
|
|
963
1025
|
else None
|
964
1026
|
)
|
965
1027
|
task_run_id = id or uuid7()
|
1028
|
+
|
966
1029
|
state = prefect.states.Pending(
|
967
1030
|
state_details=StateDetails(
|
968
1031
|
task_run_id=task_run_id,
|
@@ -1664,8 +1727,9 @@ def task(
|
|
1664
1727
|
refresh_cache: Optional[bool] = None,
|
1665
1728
|
on_completion: Optional[list[StateHookCallable]] = None,
|
1666
1729
|
on_failure: Optional[list[StateHookCallable]] = None,
|
1667
|
-
retry_condition_fn:
|
1730
|
+
retry_condition_fn: Optional[RetryConditionCallable] = None,
|
1668
1731
|
viz_return_value: Any = None,
|
1732
|
+
asset_deps: Optional[list[Union[str, Asset]]] = None,
|
1669
1733
|
) -> Callable[[Callable[P, R]], Task[P, R]]: ...
|
1670
1734
|
|
1671
1735
|
|
@@ -1699,8 +1763,9 @@ def task(
|
|
1699
1763
|
refresh_cache: Optional[bool] = None,
|
1700
1764
|
on_completion: Optional[list[StateHookCallable]] = None,
|
1701
1765
|
on_failure: Optional[list[StateHookCallable]] = None,
|
1702
|
-
retry_condition_fn: Optional[
|
1766
|
+
retry_condition_fn: Optional[RetryConditionCallable] = None,
|
1703
1767
|
viz_return_value: Any = None,
|
1768
|
+
asset_deps: Optional[list[Union[str, Asset]]] = None,
|
1704
1769
|
) -> Callable[[Callable[P, R]], Task[P, R]]: ...
|
1705
1770
|
|
1706
1771
|
|
@@ -1735,8 +1800,9 @@ def task(
|
|
1735
1800
|
refresh_cache: Optional[bool] = None,
|
1736
1801
|
on_completion: Optional[list[StateHookCallable]] = None,
|
1737
1802
|
on_failure: Optional[list[StateHookCallable]] = None,
|
1738
|
-
retry_condition_fn: Optional[
|
1803
|
+
retry_condition_fn: Optional[RetryConditionCallable] = None,
|
1739
1804
|
viz_return_value: Any = None,
|
1805
|
+
asset_deps: Optional[list[Union[str, Asset]]] = None,
|
1740
1806
|
) -> Callable[[Callable[P, R]], Task[P, R]]: ...
|
1741
1807
|
|
1742
1808
|
|
@@ -1768,8 +1834,9 @@ def task(
|
|
1768
1834
|
refresh_cache: Optional[bool] = None,
|
1769
1835
|
on_completion: Optional[list[StateHookCallable]] = None,
|
1770
1836
|
on_failure: Optional[list[StateHookCallable]] = None,
|
1771
|
-
retry_condition_fn: Optional[
|
1837
|
+
retry_condition_fn: Optional[RetryConditionCallable] = None,
|
1772
1838
|
viz_return_value: Any = None,
|
1839
|
+
asset_deps: Optional[list[Union[str, Asset]]] = None,
|
1773
1840
|
):
|
1774
1841
|
"""
|
1775
1842
|
Decorator to designate a function as a task in a Prefect workflow.
|
@@ -1830,6 +1897,7 @@ def task(
|
|
1830
1897
|
should end as failed. Defaults to `None`, indicating the task should always continue
|
1831
1898
|
to its retry policy.
|
1832
1899
|
viz_return_value: An optional value to return when the task dependency tree is visualized.
|
1900
|
+
asset_deps: An optional list of upstream assets that this task depends on.
|
1833
1901
|
|
1834
1902
|
Returns:
|
1835
1903
|
A callable `Task` object which, when called, will submit the task for execution.
|
@@ -1906,6 +1974,7 @@ def task(
|
|
1906
1974
|
on_failure=on_failure,
|
1907
1975
|
retry_condition_fn=retry_condition_fn,
|
1908
1976
|
viz_return_value=viz_return_value,
|
1977
|
+
asset_deps=asset_deps,
|
1909
1978
|
)
|
1910
1979
|
else:
|
1911
1980
|
return cast(
|
@@ -1935,5 +2004,32 @@ def task(
|
|
1935
2004
|
on_failure=on_failure,
|
1936
2005
|
retry_condition_fn=retry_condition_fn,
|
1937
2006
|
viz_return_value=viz_return_value,
|
2007
|
+
asset_deps=asset_deps,
|
1938
2008
|
),
|
1939
2009
|
)
|
2010
|
+
|
2011
|
+
|
2012
|
+
class MaterializingTask(Task[P, R]):
|
2013
|
+
"""
|
2014
|
+
A task that materializes Assets.
|
2015
|
+
|
2016
|
+
Args:
|
2017
|
+
assets: List of Assets that this task materializes (can be str or Asset)
|
2018
|
+
materialized_by: An optional tool that materialized the asset e.g. "dbt" or "spark"
|
2019
|
+
**task_kwargs: All other Task arguments
|
2020
|
+
"""
|
2021
|
+
|
2022
|
+
def __init__(
|
2023
|
+
self,
|
2024
|
+
fn: Callable[P, R],
|
2025
|
+
*,
|
2026
|
+
assets: Sequence[Union[str, Asset]],
|
2027
|
+
materialized_by: str | None = None,
|
2028
|
+
**task_kwargs: Unpack[TaskOptions],
|
2029
|
+
):
|
2030
|
+
super().__init__(fn=fn, **task_kwargs)
|
2031
|
+
|
2032
|
+
self.assets: list[Asset] = [
|
2033
|
+
Asset(key=a) if isinstance(a, str) else a for a in assets
|
2034
|
+
]
|
2035
|
+
self.materialized_by = materialized_by
|
prefect/types/__init__.py
CHANGED
@@ -14,6 +14,7 @@ from .names import (
|
|
14
14
|
BANNED_CHARACTERS,
|
15
15
|
WITHOUT_BANNED_CHARACTERS,
|
16
16
|
MAX_VARIABLE_NAME_LENGTH,
|
17
|
+
URILike,
|
17
18
|
)
|
18
19
|
from pydantic import (
|
19
20
|
BeforeValidator,
|
@@ -219,4 +220,5 @@ __all__ = [
|
|
219
220
|
"StatusCode",
|
220
221
|
"StrictVariableValue",
|
221
222
|
"TaskRetryDelaySeconds",
|
223
|
+
"URILike",
|
222
224
|
]
|
prefect/types/_datetime.py
CHANGED
@@ -223,10 +223,10 @@ def travel_to(dt: Any):
|
|
223
223
|
|
224
224
|
def in_local_tz(dt: datetime.datetime) -> datetime.datetime:
|
225
225
|
if sys.version_info >= (3, 13):
|
226
|
-
from whenever import
|
226
|
+
from whenever import PlainDateTime, ZonedDateTime
|
227
227
|
|
228
228
|
if dt.tzinfo is None:
|
229
|
-
wdt =
|
229
|
+
wdt = PlainDateTime.from_py_datetime(dt)
|
230
230
|
else:
|
231
231
|
if not isinstance(dt.tzinfo, ZoneInfo):
|
232
232
|
if key := getattr(dt.tzinfo, "key", None):
|
prefect/types/names.py
CHANGED
@@ -137,3 +137,26 @@ VariableName = Annotated[
|
|
137
137
|
examples=["my_variable"],
|
138
138
|
),
|
139
139
|
]
|
140
|
+
|
141
|
+
|
142
|
+
# URI validation
|
143
|
+
URI_REGEX = re.compile(r"^[a-z0-9]+://")
|
144
|
+
|
145
|
+
|
146
|
+
def validate_uri(value: str) -> str:
|
147
|
+
"""Validate that a string is a valid URI with lowercase protocol."""
|
148
|
+
if not URI_REGEX.match(value):
|
149
|
+
raise ValueError(
|
150
|
+
"Key must be a valid URI, e.g. storage://bucket/folder/asset.csv"
|
151
|
+
)
|
152
|
+
return value
|
153
|
+
|
154
|
+
|
155
|
+
URILike = Annotated[
|
156
|
+
str,
|
157
|
+
AfterValidator(validate_uri),
|
158
|
+
Field(
|
159
|
+
description="A URI-like string with a lowercase protocol",
|
160
|
+
examples=["s3://bucket/folder/data.csv", "postgres://dbtable"],
|
161
|
+
),
|
162
|
+
]
|
prefect/utilities/callables.py
CHANGED
@@ -286,8 +286,10 @@ def process_v1_params(
|
|
286
286
|
docstrings: dict[str, str],
|
287
287
|
aliases: dict[str, str],
|
288
288
|
) -> tuple[str, Any, Any]:
|
289
|
+
import pydantic.v1 as pydantic_v1
|
290
|
+
|
289
291
|
# Pydantic model creation will fail if names collide with the BaseModel type
|
290
|
-
if hasattr(
|
292
|
+
if hasattr(pydantic_v1.BaseModel, param.name):
|
291
293
|
name = param.name + "__"
|
292
294
|
aliases[name] = param.name
|
293
295
|
else:
|
@@ -296,10 +298,9 @@ def process_v1_params(
|
|
296
298
|
type_ = Any if param.annotation is inspect.Parameter.empty else param.annotation
|
297
299
|
|
298
300
|
with warnings.catch_warnings():
|
299
|
-
warnings
|
300
|
-
|
301
|
-
|
302
|
-
field: Any = pydantic.Field( # type: ignore # this uses the v1 signature, not v2
|
301
|
+
# Note: pydantic.v1 doesn't have the warnings module, so we can't suppress them
|
302
|
+
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
303
|
+
field: Any = pydantic_v1.Field(
|
303
304
|
default=... if param.default is param.empty else param.default,
|
304
305
|
title=param.name,
|
305
306
|
description=docstrings.get(param.name, None),
|
@@ -312,18 +313,19 @@ def process_v1_params(
|
|
312
313
|
def create_v1_schema(
|
313
314
|
name_: str, model_cfg: type[Any], model_fields: Optional[dict[str, Any]] = None
|
314
315
|
) -> dict[str, Any]:
|
316
|
+
import pydantic.v1 as pydantic_v1
|
317
|
+
|
315
318
|
with warnings.catch_warnings():
|
316
|
-
warnings
|
317
|
-
|
318
|
-
)
|
319
|
+
# Note: pydantic.v1 doesn't have the warnings module, so we can't suppress them
|
320
|
+
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
319
321
|
|
320
322
|
model_fields = model_fields or {}
|
321
|
-
model: type[
|
323
|
+
model: type[pydantic_v1.BaseModel] = pydantic_v1.create_model(
|
322
324
|
name_,
|
323
|
-
__config__=model_cfg,
|
325
|
+
__config__=model_cfg,
|
324
326
|
**model_fields,
|
325
327
|
)
|
326
|
-
return model.schema(by_alias=True)
|
328
|
+
return model.schema(by_alias=True)
|
327
329
|
|
328
330
|
|
329
331
|
def parameter_schema(fn: Callable[..., Any]) -> ParameterSchema:
|
prefect/utilities/engine.py
CHANGED
@@ -80,7 +80,11 @@ async def collect_task_run_inputs(expr: Any, max_depth: int = -1) -> set[TaskRun
|
|
80
80
|
inputs.add(TaskRunResult(id=obj.task_run_id))
|
81
81
|
elif isinstance(obj, State):
|
82
82
|
if obj.state_details.task_run_id:
|
83
|
-
inputs.add(
|
83
|
+
inputs.add(
|
84
|
+
TaskRunResult(
|
85
|
+
id=obj.state_details.task_run_id,
|
86
|
+
)
|
87
|
+
)
|
84
88
|
# Expressions inside quotes should not be traversed
|
85
89
|
elif isinstance(obj, quote):
|
86
90
|
raise StopVisiting
|
@@ -118,10 +122,18 @@ def collect_task_run_inputs_sync(
|
|
118
122
|
|
119
123
|
def add_futures_and_states_to_inputs(obj: Any) -> None:
|
120
124
|
if isinstance(obj, future_cls) and hasattr(obj, "task_run_id"):
|
121
|
-
inputs.add(
|
125
|
+
inputs.add(
|
126
|
+
TaskRunResult(
|
127
|
+
id=obj.task_run_id,
|
128
|
+
)
|
129
|
+
)
|
122
130
|
elif isinstance(obj, State):
|
123
131
|
if obj.state_details.task_run_id:
|
124
|
-
inputs.add(
|
132
|
+
inputs.add(
|
133
|
+
TaskRunResult(
|
134
|
+
id=obj.state_details.task_run_id,
|
135
|
+
)
|
136
|
+
)
|
125
137
|
# Expressions inside quotes should not be traversed
|
126
138
|
elif isinstance(obj, quote):
|
127
139
|
raise StopVisiting
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: prefect-client
|
3
|
-
Version: 3.4.
|
3
|
+
Version: 3.4.6
|
4
4
|
Summary: Workflow orchestration and management.
|
5
5
|
Project-URL: Changelog, https://github.com/PrefectHQ/prefect/releases
|
6
6
|
Project-URL: Documentation, https://docs.prefect.io
|
@@ -44,7 +44,7 @@ Requires-Dist: packaging<25.1,>=21.3
|
|
44
44
|
Requires-Dist: pathspec>=0.8.0
|
45
45
|
Requires-Dist: pendulum<4,>=3.0.0; python_version < '3.13'
|
46
46
|
Requires-Dist: prometheus-client>=0.20.0
|
47
|
-
Requires-Dist: pydantic!=2.10.0,<3.0.0,>=2.9
|
47
|
+
Requires-Dist: pydantic!=2.10.0,!=2.11.0,!=2.11.1,!=2.11.2,!=2.11.3,!=2.11.4,<3.0.0,>=2.9
|
48
48
|
Requires-Dist: pydantic-core<3.0.0,>=2.12.0
|
49
49
|
Requires-Dist: pydantic-extra-types<3.0.0,>=2.8.2
|
50
50
|
Requires-Dist: pydantic-settings!=2.9.0,<3.0.0,>2.2.1
|
@@ -1,7 +1,7 @@
|
|
1
1
|
prefect/.prefectignore,sha256=awSprvKT0vI8a64mEOLrMxhxqcO-b0ERQeYpA2rNKVQ,390
|
2
2
|
prefect/__init__.py,sha256=iCdcC5ZmeewikCdnPEP6YBAjPNV5dvfxpYCTpw30Hkw,3685
|
3
3
|
prefect/__main__.py,sha256=WFjw3kaYJY6pOTA7WDOgqjsz8zUEUZHCcj3P5wyVa-g,66
|
4
|
-
prefect/_build_info.py,sha256=
|
4
|
+
prefect/_build_info.py,sha256=Onw22rPtd_3lrnO8gZBgQj2RZMrJF7WFwSbga7c6V7Q,180
|
5
5
|
prefect/_result_records.py,sha256=S6QmsODkehGVSzbMm6ig022PYbI6gNKz671p_8kBYx4,7789
|
6
6
|
prefect/_versioning.py,sha256=YqR5cxXrY4P6LM1Pmhd8iMo7v_G2KJpGNdsf4EvDFQ0,14132
|
7
7
|
prefect/_waiters.py,sha256=Ia2ITaXdHzevtyWIgJoOg95lrEXQqNEOquHvw3T33UQ,9026
|
@@ -9,7 +9,7 @@ prefect/agent.py,sha256=dPvG1jDGD5HSH7aM2utwtk6RaJ9qg13XjkA0lAIgQmY,287
|
|
9
9
|
prefect/artifacts.py,sha256=dMBUOAWnUamzjb5HSqwB5-GR2Qb-Gxee26XG5NDCUuw,22720
|
10
10
|
prefect/automations.py,sha256=ZzPxn2tINdlXTQo805V4rIlbXuNWxd7cdb3gTJxZIeY,12567
|
11
11
|
prefect/cache_policies.py,sha256=jH1aDW6vItTcsEytuTCrNYyjbq87IQPwdOgF0yxiUts,12749
|
12
|
-
prefect/context.py,sha256=
|
12
|
+
prefect/context.py,sha256=9IbfzBrhd6nqVicgcqeAqihRxKUYYZDg-psTByCYcZo,32589
|
13
13
|
prefect/engine.py,sha256=uB5JN4l045i5JTlRQNT1x7MwlSiGQ5Bop2Q6jHHOgxY,3699
|
14
14
|
prefect/exceptions.py,sha256=wZLQQMRB_DyiYkeEdIC5OKwbba5A94Dlnics-lrWI7A,11581
|
15
15
|
prefect/filesystems.py,sha256=v5YqGB4uXf9Ew2VuB9VCSkawvYMMVvEtZf7w1VmAmr8,18036
|
@@ -24,11 +24,11 @@ prefect/results.py,sha256=Amm3TQu8U_oakSn__tCogIJ5DsTj0w_kLzuENWsxK6A,36824
|
|
24
24
|
prefect/schedules.py,sha256=dhq4OhImRvcmtxF7UH1m8RbwYdHT5RQsp_FrxVXfODE,7289
|
25
25
|
prefect/serializers.py,sha256=lU9A1rGEfAfhr8nTl3rf-K7ED78QNShXOrmRBhgNk3Y,9566
|
26
26
|
prefect/states.py,sha256=rh7l1bnIYpTXdlXt5nnpz66y9KLjBWAJrN9Eo5RwgQs,26023
|
27
|
-
prefect/task_engine.py,sha256=
|
27
|
+
prefect/task_engine.py,sha256=j7i_UiLvijV4Vut1Bw5-72kSlOqAPxqeS7-3cMVEBPA,65509
|
28
28
|
prefect/task_runners.py,sha256=ptgE5wuXg_IVHM0j7d6l7ELAVg3SXSy4vggnoHRF8dA,17040
|
29
29
|
prefect/task_runs.py,sha256=7LIzfo3fondCyEUpU05sYFN5IfpZigBDXrhG5yc-8t0,9039
|
30
30
|
prefect/task_worker.py,sha256=RifZ3bOl6ppoYPiOAd4TQp2_GEw9eDQoW483rq1q52Q,20805
|
31
|
-
prefect/tasks.py,sha256=
|
31
|
+
prefect/tasks.py,sha256=d4bJUiyNAtXqUotU7cHdk2IFV0OZQDdJ9jkkno8HdIs,78220
|
32
32
|
prefect/transactions.py,sha256=uIoPNudzJzH6NrMJhrgr5lyh6JxOJQqT1GvrXt69yNw,26068
|
33
33
|
prefect/variables.py,sha256=dCK3vX7TbkqXZhnNT_v7rcGh3ISRqoR6pJVLpoll3Js,8342
|
34
34
|
prefect/_experimental/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -71,6 +71,9 @@ prefect/_internal/schemas/serializers.py,sha256=G_RGHfObjisUiRvd29p-zc6W4bwt5rE1
|
|
71
71
|
prefect/_internal/schemas/validators.py,sha256=h5LL6WuXf4rMmLHsYFflmJBlwqi5c7y0tYibMJzJANM,16933
|
72
72
|
prefect/_vendor/croniter/__init__.py,sha256=NUFzdbyPcTQhIOFtzmFM0nbClAvBbKh2mlnTBa6NfHU,523
|
73
73
|
prefect/_vendor/croniter/croniter.py,sha256=eJ2HzStNAYV-vNiLOgDXl4sYWWHOsSA0dgwbkQoguhY,53009
|
74
|
+
prefect/assets/__init__.py,sha256=-BAzycfydjD0eKRdpTiGXKxU66-yZX7CUh3Hot__PY4,203
|
75
|
+
prefect/assets/core.py,sha256=9iGsGqZ74UdCwZcLqUogPgVscBROIVeczv-TpB9fnYA,2179
|
76
|
+
prefect/assets/materialize.py,sha256=GcHn1HEbCpExka0IOOz2b_2ZsJFROIo5y7DCP5GjpI8,1143
|
74
77
|
prefect/blocks/__init__.py,sha256=D0hB72qMfgqnBB2EMZRxUxlX9yLfkab5zDChOwJZmkY,220
|
75
78
|
prefect/blocks/abstract.py,sha256=mpOAWopSR_RrzdxeurBTXVSKisP8ne-k8LYos-tp7go,17021
|
76
79
|
prefect/blocks/core.py,sha256=iP-g6guW9HFkt-sFpgH8WCyWhwnH5zIoUJuI2ykImG0,62894
|
@@ -140,7 +143,7 @@ prefect/deployments/__init__.py,sha256=_wb7NxDKhq11z9MjYsPckmT3o6MRhGLRgCV9TmvYt
|
|
140
143
|
prefect/deployments/base.py,sha256=YY7g8MN6qzjNEjEA8wQXPxCrd47WnACIUeSRtI4nrEk,11849
|
141
144
|
prefect/deployments/deployments.py,sha256=K3Rgnpjxo_T8I8LMwlq24OKqZiZBTE8-YnPg-YGUStM,171
|
142
145
|
prefect/deployments/flow_runs.py,sha256=NYe-Bphsy6ENLqSSfywQuX5cRZt-uVgzqGmOsf3Sqw4,7643
|
143
|
-
prefect/deployments/runner.py,sha256=
|
146
|
+
prefect/deployments/runner.py,sha256=nRXloAo5j56rbTmr-MU8oYOVoXodvEauLAH_07vtcHM,56734
|
144
147
|
prefect/deployments/schedules.py,sha256=2eL1-w8qXtwKVkgfUK7cuamwpKK3X6tN1QYTDa_gWxU,2190
|
145
148
|
prefect/deployments/steps/__init__.py,sha256=Dlz9VqMRyG1Gal8dj8vfGpPr0LyQhZdvcciozkK8WoY,206
|
146
149
|
prefect/deployments/steps/core.py,sha256=ulSgBFSx1lhBt1fP-UxebrernkumBDlympR6IPffV1g,6900
|
@@ -150,7 +153,7 @@ prefect/docker/__init__.py,sha256=z6wdc6UFfiBG2jb9Jk64uCWVM04JKVWeVyDWwuuon8M,52
|
|
150
153
|
prefect/docker/docker_image.py,sha256=bR_pEq5-FDxlwTj8CP_7nwZ_MiGK6KxIi8v7DRjy1Kg,3138
|
151
154
|
prefect/events/__init__.py,sha256=GtKl2bE--pJduTxelH2xy7SadlLJmmis8WR1EYixhuA,2094
|
152
155
|
prefect/events/actions.py,sha256=A7jS8bo4zWGnrt3QfSoQs0uYC1xfKXio3IfU0XtTb5s,9129
|
153
|
-
prefect/events/clients.py,sha256=
|
156
|
+
prefect/events/clients.py,sha256=r_C3ZevVYUzIW53CpmFbEtR2DwhYeYB4budtB3GaYl0,27625
|
154
157
|
prefect/events/filters.py,sha256=tnAbA4Z0Npem8Jbin-qqe38K_4a-4YdpU-Oc4u8Y95Q,8697
|
155
158
|
prefect/events/related.py,sha256=CTeexYUmmA93V4gsR33GIFmw-SS-X_ouOpRg-oeq-BU,6672
|
156
159
|
prefect/events/utilities.py,sha256=ww34bTMENCNwcp6RhhgzG0KgXOvKGe0MKmBdSJ8NpZY,3043
|
@@ -188,9 +191,9 @@ prefect/logging/logging.yml,sha256=G5hFJ57Vawz40_w8tDdhqq00dp103OvVDVmWrSQeQcQ,3
|
|
188
191
|
prefect/runner/__init__.py,sha256=pQBd9wVrUVUDUFJlgiweKSnbahoBZwqnd2O2jkhrULY,158
|
189
192
|
prefect/runner/_observers.py,sha256=PpyXQL5bjp86AnDFEzcFPS5ayL6ExqcYgyuBMMQCO9Q,2183
|
190
193
|
prefect/runner/runner.py,sha256=q_3l2awvZATTTgVW3MYiElWHRWw5_ZIliUN9Ltt9d9M,59591
|
191
|
-
prefect/runner/server.py,sha256=
|
194
|
+
prefect/runner/server.py,sha256=5vMIJcgunjiDVzJEig09yOP8EbhcW6s-9zNUt101b44,11994
|
192
195
|
prefect/runner/storage.py,sha256=n-65YoEf7KNVInnmMPeP5TVFJOa2zOS8w9en9MHi6uo,31328
|
193
|
-
prefect/runner/submit.py,sha256=
|
196
|
+
prefect/runner/submit.py,sha256=b5n1M12DFQsxo6FazZnDbblRcIE7H3xrpecDMb4CjJY,9512
|
194
197
|
prefect/runner/utils.py,sha256=19DbhyiV6nvSpTXmnWlt7qPNt1jrz1jscznYrRVGurw,3413
|
195
198
|
prefect/runtime/__init__.py,sha256=JswiTlYRup2zXOYu8AqJ7czKtgcw9Kxo0tTbS6aWCqY,407
|
196
199
|
prefect/runtime/deployment.py,sha256=0A_cUVpYiFk3ciJw2ixy95dk9xBJcjisyF69pakSCcQ,5091
|
@@ -211,7 +214,7 @@ prefect/server/api/concurrency_limits_v2.py,sha256=PGjG7W2Z65OojNTP0ezFu2z69plXo
|
|
211
214
|
prefect/server/api/csrf_token.py,sha256=BwysSjQAhre7O0OY_LF3ZcIiO53FdMQroNT11Q6OcOM,1344
|
212
215
|
prefect/server/api/dependencies.py,sha256=VujfcIGn41TGJxUunFHVabY5hE-6nY6uSHyhNFj8PdI,6634
|
213
216
|
prefect/server/api/deployments.py,sha256=ppYA3b2csnw32-SbOXz5Dm_IsnmPKczNiSbqCzusFKI,39332
|
214
|
-
prefect/server/api/events.py,sha256=
|
217
|
+
prefect/server/api/events.py,sha256=mUTv5ZNxiRsEOpzq8fpfCkLpPasjt-ROUAowA5eFbDE,9900
|
215
218
|
prefect/server/api/flow_run_states.py,sha256=lIdxVE9CqLgtDCuH9bTaKkzHNL81FPrr11liPzvONrw,1661
|
216
219
|
prefect/server/api/flow_runs.py,sha256=Lmb165fLbN4DioxjxgDYaAJ5Qxj771iRYaqn-hYq9KM,33744
|
217
220
|
prefect/server/api/flows.py,sha256=Bz0ISh-9oY0W1X3mqA631_8678pQ6tuRGMpSgWAfxOc,7018
|
@@ -223,8 +226,8 @@ prefect/server/api/saved_searches.py,sha256=UjoqLLe245QVIs6q5Vk4vdODCOoYzciEEjhi
|
|
223
226
|
prefect/server/api/server.py,sha256=xSi2km9KhhHPHSKEFHVntii0hRz2OINtB5zCUNajt6A,33356
|
224
227
|
prefect/server/api/task_run_states.py,sha256=e63OPpxPudv_CIB5oKr8Z8rfQ-Osjm9Zq0iHe8obnMo,1647
|
225
228
|
prefect/server/api/task_runs.py,sha256=86lXKGUJJSElhkVcxX-kbjctrNe98nUe3U0McDCfTMw,13904
|
226
|
-
prefect/server/api/task_workers.py,sha256=
|
227
|
-
prefect/server/api/templates.py,sha256=
|
229
|
+
prefect/server/api/task_workers.py,sha256=bFHWifk7IwWF3iPu_3HwKu0vLRrxHg42SZU7vYWOw9g,1061
|
230
|
+
prefect/server/api/templates.py,sha256=EW5aJOuvSXBeShd5VIygI1f9W0uTUpGb32ADrL9LG3k,1208
|
228
231
|
prefect/server/api/validation.py,sha256=HxSNyH8yb_tI-kOfjXESRjJp6WQK6hYWBJsaBxUvY34,14490
|
229
232
|
prefect/server/api/variables.py,sha256=SJaKuqInfQIEdMlJOemptBDN43KLFhlf_u9QwupDu7A,6185
|
230
233
|
prefect/server/api/work_queues.py,sha256=368YmggZbDYpD6-p4MXFvDniImEp1Tr4zejvmIA2lXM,7609
|
@@ -241,7 +244,7 @@ prefect/settings/base.py,sha256=VtBSwBLowLvtBVDq3ZY5oKAwosMqsDMt2gcXLAiFf5k,9682
|
|
241
244
|
prefect/settings/constants.py,sha256=5NjVLG1Km9J9I-a6wrq-qmi_dTkPdwEk3IrY9bSxWvw,281
|
242
245
|
prefect/settings/context.py,sha256=yKxnaDJHX8e2jmAVtw1RF9o7X4V3AOcz61sVeQyPX2c,2195
|
243
246
|
prefect/settings/legacy.py,sha256=KG00GwaURl1zbwfCKAjwNRdJjB2UdTyo80gYF7U60jk,5693
|
244
|
-
prefect/settings/profiles.py,sha256=
|
247
|
+
prefect/settings/profiles.py,sha256=Mk-fcfDUuJx5zIpp87Ar8d9jLFTgCOM83vEJWgmECBc,12795
|
245
248
|
prefect/settings/profiles.toml,sha256=kTvqDNMzjH3fsm5OEI-NKY4dMmipor5EvQXRB6rPEjY,522
|
246
249
|
prefect/settings/sources.py,sha256=x-yJT9aENh32wGVxe9WZg6KLLCZOZOMV0h5dDHuR6FA,13545
|
247
250
|
prefect/settings/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -268,7 +271,7 @@ prefect/settings/models/server/ephemeral.py,sha256=rh8Py5Nxh-gq9KgfB7CDnIgT_nuOu
|
|
268
271
|
prefect/settings/models/server/events.py,sha256=9rdlbLz9SIg_easm1UcFTfX1seS935Xtv5d9y3r39Eo,5578
|
269
272
|
prefect/settings/models/server/flow_run_graph.py,sha256=PuAZqqdu6fzvrbUgXZzyntUH_Ii_bP7qezgcgvW7ULk,1146
|
270
273
|
prefect/settings/models/server/root.py,sha256=Dk_Zx4eGUy1h2cAetDKphnd6TWhDrK6DHOLJxdP7e1Y,5215
|
271
|
-
prefect/settings/models/server/services.py,sha256=
|
274
|
+
prefect/settings/models/server/services.py,sha256=Mb71MG5I1hPlCaJ54vNmHgU7Rxde2x8QeDQl9a8cGU4,18998
|
272
275
|
prefect/settings/models/server/tasks.py,sha256=_CaOUfh3WDXvUhmHXmR-MkTRaQqocZck4efmX74iOg8,2976
|
273
276
|
prefect/settings/models/server/ui.py,sha256=hShsi4rPBtdJA2WnT1Er0tWqu-e5wUum8NkNgucShkk,1867
|
274
277
|
prefect/telemetry/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
@@ -278,10 +281,10 @@ prefect/telemetry/logging.py,sha256=ktIVTXbdZ46v6fUhoHNidFrpvpNJR-Pj-hQ4V9b40W4,
|
|
278
281
|
prefect/telemetry/processors.py,sha256=jw6j6LviOVxw3IBJe7cSjsxFk0zzY43jUmy6C9pcfCE,2272
|
279
282
|
prefect/telemetry/run_telemetry.py,sha256=_FbjiPqPemu4xvZuI2YBPwXeRJ2BcKRJ6qgO4UMzKKE,8571
|
280
283
|
prefect/telemetry/services.py,sha256=DxgNNDTeWNtHBtioX8cjua4IrCbTiJJdYecx-gugg-w,2358
|
281
|
-
prefect/types/__init__.py,sha256=
|
282
|
-
prefect/types/_datetime.py,sha256=
|
284
|
+
prefect/types/__init__.py,sha256=iJzZLnK1qQuZUExF4_4xRLr0TMgb3uKfR5HQ1cjQ_0w,6066
|
285
|
+
prefect/types/_datetime.py,sha256=_N3eAMhYlwSEubMQlfeTGxLJHn2jRFPrNPxkod21B_s,7566
|
283
286
|
prefect/types/entrypoint.py,sha256=2FF03-wLPgtnqR_bKJDB2BsXXINPdu8ptY9ZYEZnXg8,328
|
284
|
-
prefect/types/names.py,sha256=
|
287
|
+
prefect/types/names.py,sha256=dGXNrP9nibQTm4hOBOpaQebKm3Avf3OGM5MH4M5BUKc,4013
|
285
288
|
prefect/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
286
289
|
prefect/utilities/_ast.py,sha256=sgEPUWElih-3cp4PoAy1IOyPtu8E27lL0Dldf3ijnYY,4905
|
287
290
|
prefect/utilities/_deprecated.py,sha256=b3pqRSoFANdVJAc8TJkygBcP-VjZtLJUxVIWC7kwspI,1303
|
@@ -289,13 +292,13 @@ prefect/utilities/_engine.py,sha256=9GW4X1lyAbmPwCuXXIubVJ7Z0DMT3dykkEUtp9tm5hI,
|
|
289
292
|
prefect/utilities/_git.py,sha256=bPYWQdr9xvH0BqxR1ll1RkaSb3x0vhwylhYD5EilkKU,863
|
290
293
|
prefect/utilities/annotations.py,sha256=0Elqgq6LR7pQqezNqT5wb6U_0e2pDO_zx6VseVL6kL8,4396
|
291
294
|
prefect/utilities/asyncutils.py,sha256=xcfeNym2j3WH4gKXznON2hI1PpUTcwr_BGc16IQS3C4,19789
|
292
|
-
prefect/utilities/callables.py,sha256=
|
295
|
+
prefect/utilities/callables.py,sha256=HcXA3_Stb8CBtp074SuFKuMy-ge2KW89X5towbzGjaY,25925
|
293
296
|
prefect/utilities/collections.py,sha256=c3nPLPWqIZQQdNuHs_nrbQJwuhQSX4ivUl-h9LtzXto,23243
|
294
297
|
prefect/utilities/compat.py,sha256=nnPA3lf2f4Y-l645tYFFNmj5NDPaYvjqa9pbGKZ3WKE,582
|
295
298
|
prefect/utilities/context.py,sha256=23SDMgdt07SjmB1qShiykHfGgiv55NBzdbMXM3fE9CI,1447
|
296
299
|
prefect/utilities/dispatch.py,sha256=u6GSGSO3_6vVoIqHVc849lsKkC-I1wUl6TX134GwRBo,6310
|
297
300
|
prefect/utilities/dockerutils.py,sha256=6DLVyzE195IzeQSWERiK1t3bDMnYBLe0zXIpMQ4r0c0,21659
|
298
|
-
prefect/utilities/engine.py,sha256=
|
301
|
+
prefect/utilities/engine.py,sha256=Ltu-Elpb6AjxPumjyqfl3yb2r61UMxO-l6zHXAZ5erM,29190
|
299
302
|
prefect/utilities/filesystem.py,sha256=Pwesv71PGFhf3lPa1iFyMqZZprBjy9nEKCVxTkf_hXw,5710
|
300
303
|
prefect/utilities/generics.py,sha256=o77e8a5iwmrisOf42wLp2WI9YvSw2xDW4vFdpdEwr3I,543
|
301
304
|
prefect/utilities/hashing.py,sha256=7jRy26s46IJAFRmVnCnoK9ek9N4p_UfXxQQvu2tW6dM,2589
|
@@ -322,7 +325,7 @@ prefect/workers/cloud.py,sha256=dPvG1jDGD5HSH7aM2utwtk6RaJ9qg13XjkA0lAIgQmY,287
|
|
322
325
|
prefect/workers/process.py,sha256=Yi5D0U5AQ51wHT86GdwtImXSefe0gJf3LGq4r4z9zwM,11090
|
323
326
|
prefect/workers/server.py,sha256=2pmVeJZiVbEK02SO6BEZaBIvHMsn6G8LzjW8BXyiTtk,1952
|
324
327
|
prefect/workers/utilities.py,sha256=VfPfAlGtTuDj0-Kb8WlMgAuOfgXCdrGAnKMapPSBrwc,2483
|
325
|
-
prefect_client-3.4.
|
326
|
-
prefect_client-3.4.
|
327
|
-
prefect_client-3.4.
|
328
|
-
prefect_client-3.4.
|
328
|
+
prefect_client-3.4.6.dist-info/METADATA,sha256=oRVZlQzoBXYQxELP1bqqSMwzSFcFcYXtlmv469afKjY,7512
|
329
|
+
prefect_client-3.4.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
330
|
+
prefect_client-3.4.6.dist-info/licenses/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
|
331
|
+
prefect_client-3.4.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|