prefect-client 2.20.2__py3-none-any.whl → 3.0.0__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/__init__.py +74 -110
- prefect/_internal/compatibility/deprecated.py +6 -115
- prefect/_internal/compatibility/experimental.py +4 -79
- prefect/_internal/compatibility/migration.py +166 -0
- prefect/_internal/concurrency/__init__.py +2 -2
- prefect/_internal/concurrency/api.py +1 -35
- prefect/_internal/concurrency/calls.py +0 -6
- prefect/_internal/concurrency/cancellation.py +0 -3
- prefect/_internal/concurrency/event_loop.py +0 -20
- prefect/_internal/concurrency/inspection.py +3 -3
- prefect/_internal/concurrency/primitives.py +1 -0
- prefect/_internal/concurrency/services.py +23 -0
- prefect/_internal/concurrency/threads.py +35 -0
- prefect/_internal/concurrency/waiters.py +0 -28
- prefect/_internal/integrations.py +7 -0
- prefect/_internal/pydantic/__init__.py +0 -45
- prefect/_internal/pydantic/annotations/pendulum.py +2 -2
- prefect/_internal/pydantic/v1_schema.py +21 -22
- prefect/_internal/pydantic/v2_schema.py +0 -2
- prefect/_internal/pydantic/v2_validated_func.py +18 -23
- prefect/_internal/pytz.py +1 -1
- prefect/_internal/retries.py +61 -0
- prefect/_internal/schemas/bases.py +45 -177
- prefect/_internal/schemas/fields.py +1 -43
- prefect/_internal/schemas/validators.py +47 -233
- prefect/agent.py +3 -695
- prefect/artifacts.py +173 -14
- prefect/automations.py +39 -4
- prefect/blocks/abstract.py +1 -1
- prefect/blocks/core.py +423 -164
- prefect/blocks/fields.py +2 -57
- prefect/blocks/notifications.py +43 -28
- prefect/blocks/redis.py +168 -0
- prefect/blocks/system.py +67 -20
- prefect/blocks/webhook.py +2 -9
- prefect/cache_policies.py +239 -0
- prefect/client/__init__.py +4 -0
- prefect/client/base.py +33 -27
- prefect/client/cloud.py +65 -20
- prefect/client/collections.py +1 -1
- prefect/client/orchestration.py +667 -440
- prefect/client/schemas/actions.py +115 -100
- prefect/client/schemas/filters.py +46 -52
- prefect/client/schemas/objects.py +228 -178
- prefect/client/schemas/responses.py +18 -36
- prefect/client/schemas/schedules.py +55 -36
- prefect/client/schemas/sorting.py +2 -0
- prefect/client/subscriptions.py +8 -7
- prefect/client/types/flexible_schedule_list.py +11 -0
- prefect/client/utilities.py +9 -6
- prefect/concurrency/asyncio.py +60 -11
- prefect/concurrency/context.py +24 -0
- prefect/concurrency/events.py +2 -2
- prefect/concurrency/services.py +46 -16
- prefect/concurrency/sync.py +51 -7
- prefect/concurrency/v1/asyncio.py +143 -0
- prefect/concurrency/v1/context.py +27 -0
- prefect/concurrency/v1/events.py +61 -0
- prefect/concurrency/v1/services.py +116 -0
- prefect/concurrency/v1/sync.py +92 -0
- prefect/context.py +246 -149
- prefect/deployments/__init__.py +33 -18
- prefect/deployments/base.py +10 -15
- prefect/deployments/deployments.py +2 -1048
- prefect/deployments/flow_runs.py +178 -0
- prefect/deployments/runner.py +72 -173
- prefect/deployments/schedules.py +31 -25
- prefect/deployments/steps/__init__.py +0 -1
- prefect/deployments/steps/core.py +7 -0
- prefect/deployments/steps/pull.py +15 -21
- prefect/deployments/steps/utility.py +2 -1
- prefect/docker/__init__.py +20 -0
- prefect/docker/docker_image.py +82 -0
- prefect/engine.py +15 -2466
- prefect/events/actions.py +17 -23
- prefect/events/cli/automations.py +20 -7
- prefect/events/clients.py +142 -80
- prefect/events/filters.py +14 -18
- prefect/events/related.py +74 -75
- prefect/events/schemas/__init__.py +0 -5
- prefect/events/schemas/automations.py +55 -46
- prefect/events/schemas/deployment_triggers.py +7 -197
- prefect/events/schemas/events.py +46 -65
- prefect/events/schemas/labelling.py +10 -14
- prefect/events/utilities.py +4 -5
- prefect/events/worker.py +23 -8
- prefect/exceptions.py +15 -0
- prefect/filesystems.py +30 -529
- prefect/flow_engine.py +827 -0
- prefect/flow_runs.py +379 -7
- prefect/flows.py +470 -360
- prefect/futures.py +382 -331
- prefect/infrastructure/__init__.py +5 -26
- prefect/infrastructure/base.py +3 -320
- prefect/infrastructure/provisioners/__init__.py +5 -3
- prefect/infrastructure/provisioners/cloud_run.py +13 -8
- prefect/infrastructure/provisioners/container_instance.py +14 -9
- prefect/infrastructure/provisioners/ecs.py +10 -8
- prefect/infrastructure/provisioners/modal.py +8 -5
- prefect/input/__init__.py +4 -0
- prefect/input/actions.py +2 -4
- prefect/input/run_input.py +9 -9
- prefect/logging/formatters.py +2 -4
- prefect/logging/handlers.py +9 -14
- prefect/logging/loggers.py +5 -5
- prefect/main.py +72 -0
- prefect/plugins.py +2 -64
- prefect/profiles.toml +16 -2
- prefect/records/__init__.py +1 -0
- prefect/records/base.py +223 -0
- prefect/records/filesystem.py +207 -0
- prefect/records/memory.py +178 -0
- prefect/records/result_store.py +64 -0
- prefect/results.py +577 -504
- prefect/runner/runner.py +124 -51
- prefect/runner/server.py +32 -34
- prefect/runner/storage.py +3 -12
- prefect/runner/submit.py +2 -10
- prefect/runner/utils.py +2 -2
- prefect/runtime/__init__.py +1 -0
- prefect/runtime/deployment.py +1 -0
- prefect/runtime/flow_run.py +40 -5
- prefect/runtime/task_run.py +1 -0
- prefect/serializers.py +28 -39
- prefect/server/api/collections_data/views/aggregate-worker-metadata.json +5 -14
- prefect/settings.py +209 -332
- prefect/states.py +160 -63
- prefect/task_engine.py +1478 -57
- prefect/task_runners.py +383 -287
- prefect/task_runs.py +240 -0
- prefect/task_worker.py +463 -0
- prefect/tasks.py +684 -374
- prefect/transactions.py +410 -0
- prefect/types/__init__.py +72 -86
- prefect/types/entrypoint.py +13 -0
- prefect/utilities/annotations.py +4 -3
- prefect/utilities/asyncutils.py +227 -148
- prefect/utilities/callables.py +138 -48
- prefect/utilities/collections.py +134 -86
- prefect/utilities/dispatch.py +27 -14
- prefect/utilities/dockerutils.py +11 -4
- prefect/utilities/engine.py +186 -32
- prefect/utilities/filesystem.py +4 -5
- prefect/utilities/importtools.py +26 -27
- prefect/utilities/pydantic.py +128 -38
- prefect/utilities/schema_tools/hydration.py +18 -1
- prefect/utilities/schema_tools/validation.py +30 -0
- prefect/utilities/services.py +35 -9
- prefect/utilities/templating.py +12 -2
- prefect/utilities/timeout.py +20 -5
- prefect/utilities/urls.py +195 -0
- prefect/utilities/visualization.py +1 -0
- prefect/variables.py +78 -59
- prefect/workers/__init__.py +0 -1
- prefect/workers/base.py +237 -244
- prefect/workers/block.py +5 -226
- prefect/workers/cloud.py +6 -0
- prefect/workers/process.py +265 -12
- prefect/workers/server.py +29 -11
- {prefect_client-2.20.2.dist-info → prefect_client-3.0.0.dist-info}/METADATA +30 -26
- prefect_client-3.0.0.dist-info/RECORD +201 -0
- {prefect_client-2.20.2.dist-info → prefect_client-3.0.0.dist-info}/WHEEL +1 -1
- prefect/_internal/pydantic/_base_model.py +0 -51
- prefect/_internal/pydantic/_compat.py +0 -82
- prefect/_internal/pydantic/_flags.py +0 -20
- prefect/_internal/pydantic/_types.py +0 -8
- prefect/_internal/pydantic/utilities/config_dict.py +0 -72
- prefect/_internal/pydantic/utilities/field_validator.py +0 -150
- prefect/_internal/pydantic/utilities/model_construct.py +0 -56
- prefect/_internal/pydantic/utilities/model_copy.py +0 -55
- prefect/_internal/pydantic/utilities/model_dump.py +0 -136
- prefect/_internal/pydantic/utilities/model_dump_json.py +0 -112
- prefect/_internal/pydantic/utilities/model_fields.py +0 -50
- prefect/_internal/pydantic/utilities/model_fields_set.py +0 -29
- prefect/_internal/pydantic/utilities/model_json_schema.py +0 -82
- prefect/_internal/pydantic/utilities/model_rebuild.py +0 -80
- prefect/_internal/pydantic/utilities/model_validate.py +0 -75
- prefect/_internal/pydantic/utilities/model_validate_json.py +0 -68
- prefect/_internal/pydantic/utilities/model_validator.py +0 -87
- prefect/_internal/pydantic/utilities/type_adapter.py +0 -71
- prefect/_vendor/fastapi/__init__.py +0 -25
- prefect/_vendor/fastapi/applications.py +0 -946
- prefect/_vendor/fastapi/background.py +0 -3
- prefect/_vendor/fastapi/concurrency.py +0 -44
- prefect/_vendor/fastapi/datastructures.py +0 -58
- prefect/_vendor/fastapi/dependencies/__init__.py +0 -0
- prefect/_vendor/fastapi/dependencies/models.py +0 -64
- prefect/_vendor/fastapi/dependencies/utils.py +0 -877
- prefect/_vendor/fastapi/encoders.py +0 -177
- prefect/_vendor/fastapi/exception_handlers.py +0 -40
- prefect/_vendor/fastapi/exceptions.py +0 -46
- prefect/_vendor/fastapi/logger.py +0 -3
- prefect/_vendor/fastapi/middleware/__init__.py +0 -1
- prefect/_vendor/fastapi/middleware/asyncexitstack.py +0 -25
- prefect/_vendor/fastapi/middleware/cors.py +0 -3
- prefect/_vendor/fastapi/middleware/gzip.py +0 -3
- prefect/_vendor/fastapi/middleware/httpsredirect.py +0 -3
- prefect/_vendor/fastapi/middleware/trustedhost.py +0 -3
- prefect/_vendor/fastapi/middleware/wsgi.py +0 -3
- prefect/_vendor/fastapi/openapi/__init__.py +0 -0
- prefect/_vendor/fastapi/openapi/constants.py +0 -2
- prefect/_vendor/fastapi/openapi/docs.py +0 -203
- prefect/_vendor/fastapi/openapi/models.py +0 -480
- prefect/_vendor/fastapi/openapi/utils.py +0 -485
- prefect/_vendor/fastapi/param_functions.py +0 -340
- prefect/_vendor/fastapi/params.py +0 -453
- prefect/_vendor/fastapi/py.typed +0 -0
- prefect/_vendor/fastapi/requests.py +0 -4
- prefect/_vendor/fastapi/responses.py +0 -40
- prefect/_vendor/fastapi/routing.py +0 -1331
- prefect/_vendor/fastapi/security/__init__.py +0 -15
- prefect/_vendor/fastapi/security/api_key.py +0 -98
- prefect/_vendor/fastapi/security/base.py +0 -6
- prefect/_vendor/fastapi/security/http.py +0 -172
- prefect/_vendor/fastapi/security/oauth2.py +0 -227
- prefect/_vendor/fastapi/security/open_id_connect_url.py +0 -34
- prefect/_vendor/fastapi/security/utils.py +0 -10
- prefect/_vendor/fastapi/staticfiles.py +0 -1
- prefect/_vendor/fastapi/templating.py +0 -3
- prefect/_vendor/fastapi/testclient.py +0 -1
- prefect/_vendor/fastapi/types.py +0 -3
- prefect/_vendor/fastapi/utils.py +0 -235
- prefect/_vendor/fastapi/websockets.py +0 -7
- prefect/_vendor/starlette/__init__.py +0 -1
- prefect/_vendor/starlette/_compat.py +0 -28
- prefect/_vendor/starlette/_exception_handler.py +0 -80
- prefect/_vendor/starlette/_utils.py +0 -88
- prefect/_vendor/starlette/applications.py +0 -261
- prefect/_vendor/starlette/authentication.py +0 -159
- prefect/_vendor/starlette/background.py +0 -43
- prefect/_vendor/starlette/concurrency.py +0 -59
- prefect/_vendor/starlette/config.py +0 -151
- prefect/_vendor/starlette/convertors.py +0 -87
- prefect/_vendor/starlette/datastructures.py +0 -707
- prefect/_vendor/starlette/endpoints.py +0 -130
- prefect/_vendor/starlette/exceptions.py +0 -60
- prefect/_vendor/starlette/formparsers.py +0 -276
- prefect/_vendor/starlette/middleware/__init__.py +0 -17
- prefect/_vendor/starlette/middleware/authentication.py +0 -52
- prefect/_vendor/starlette/middleware/base.py +0 -220
- prefect/_vendor/starlette/middleware/cors.py +0 -176
- prefect/_vendor/starlette/middleware/errors.py +0 -265
- prefect/_vendor/starlette/middleware/exceptions.py +0 -74
- prefect/_vendor/starlette/middleware/gzip.py +0 -113
- prefect/_vendor/starlette/middleware/httpsredirect.py +0 -19
- prefect/_vendor/starlette/middleware/sessions.py +0 -82
- prefect/_vendor/starlette/middleware/trustedhost.py +0 -64
- prefect/_vendor/starlette/middleware/wsgi.py +0 -147
- prefect/_vendor/starlette/py.typed +0 -0
- prefect/_vendor/starlette/requests.py +0 -328
- prefect/_vendor/starlette/responses.py +0 -347
- prefect/_vendor/starlette/routing.py +0 -933
- prefect/_vendor/starlette/schemas.py +0 -154
- prefect/_vendor/starlette/staticfiles.py +0 -248
- prefect/_vendor/starlette/status.py +0 -199
- prefect/_vendor/starlette/templating.py +0 -231
- prefect/_vendor/starlette/testclient.py +0 -804
- prefect/_vendor/starlette/types.py +0 -30
- prefect/_vendor/starlette/websockets.py +0 -193
- prefect/blocks/kubernetes.py +0 -119
- prefect/deprecated/__init__.py +0 -0
- prefect/deprecated/data_documents.py +0 -350
- prefect/deprecated/packaging/__init__.py +0 -12
- prefect/deprecated/packaging/base.py +0 -96
- prefect/deprecated/packaging/docker.py +0 -146
- prefect/deprecated/packaging/file.py +0 -92
- prefect/deprecated/packaging/orion.py +0 -80
- prefect/deprecated/packaging/serializers.py +0 -171
- prefect/events/instrument.py +0 -135
- prefect/infrastructure/container.py +0 -824
- prefect/infrastructure/kubernetes.py +0 -920
- prefect/infrastructure/process.py +0 -289
- prefect/manifests.py +0 -20
- prefect/new_flow_engine.py +0 -449
- prefect/new_task_engine.py +0 -423
- prefect/pydantic/__init__.py +0 -76
- prefect/pydantic/main.py +0 -39
- prefect/software/__init__.py +0 -2
- prefect/software/base.py +0 -50
- prefect/software/conda.py +0 -199
- prefect/software/pip.py +0 -122
- prefect/software/python.py +0 -52
- prefect/task_server.py +0 -322
- prefect_client-2.20.2.dist-info/RECORD +0 -294
- /prefect/{_internal/pydantic/utilities → client/types}/__init__.py +0 -0
- /prefect/{_vendor → concurrency/v1}/__init__.py +0 -0
- {prefect_client-2.20.2.dist-info → prefect_client-3.0.0.dist-info}/LICENSE +0 -0
- {prefect_client-2.20.2.dist-info → prefect_client-3.0.0.dist-info}/top_level.txt +0 -0
@@ -3,29 +3,18 @@ Utilities for creating and working with Prefect REST API schemas.
|
|
3
3
|
"""
|
4
4
|
|
5
5
|
import datetime
|
6
|
-
import json
|
7
6
|
import os
|
8
|
-
from
|
9
|
-
from typing import Any, Dict, Generator, Optional, Set, TypeVar
|
7
|
+
from typing import Any, ClassVar, Optional, Set, TypeVar
|
10
8
|
from uuid import UUID, uuid4
|
11
9
|
|
12
|
-
import orjson
|
13
10
|
import pendulum
|
14
|
-
from
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
from pydantic.v1.json import custom_pydantic_encoder
|
22
|
-
else:
|
23
|
-
import pydantic
|
24
|
-
from pydantic import BaseModel, Field, SecretField
|
25
|
-
from pydantic.json import custom_pydantic_encoder
|
26
|
-
|
27
|
-
from prefect._internal.schemas.fields import DateTimeTZ
|
28
|
-
from prefect._internal.schemas.serializers import orjson_dumps_extra_compatible
|
11
|
+
from pydantic import (
|
12
|
+
BaseModel,
|
13
|
+
ConfigDict,
|
14
|
+
Field,
|
15
|
+
)
|
16
|
+
from pydantic_extra_types.pendulum_dt import DateTime
|
17
|
+
from typing_extensions import Self
|
29
18
|
|
30
19
|
T = TypeVar("T")
|
31
20
|
|
@@ -42,39 +31,17 @@ class PrefectBaseModel(BaseModel):
|
|
42
31
|
subtle unintentional testing errors.
|
43
32
|
"""
|
44
33
|
|
45
|
-
|
46
|
-
# extra attributes are forbidden in order to raise meaningful errors for
|
47
|
-
# bad API payloads
|
48
|
-
# We cannot load this setting through the normal pattern due to circular
|
49
|
-
# imports; instead just check if its a truthy setting directly
|
50
|
-
if os.getenv("PREFECT_TEST_MODE", "0").lower() in ["1", "true"]:
|
51
|
-
extra = "forbid"
|
52
|
-
else:
|
53
|
-
extra = "ignore"
|
54
|
-
|
55
|
-
json_encoders = {
|
56
|
-
# Uses secret fields and strange logic to avoid a circular import error
|
57
|
-
# for Secret dict in prefect.blocks.fields
|
58
|
-
SecretField: lambda v: v.dict() if getattr(v, "dict", None) else str(v)
|
59
|
-
}
|
60
|
-
|
61
|
-
pydantic_version = getattr(pydantic, "__version__", None)
|
62
|
-
if pydantic_version is not None and Version(pydantic_version) >= Version(
|
63
|
-
"1.9.2"
|
64
|
-
):
|
65
|
-
copy_on_model_validation = "none"
|
66
|
-
else:
|
67
|
-
copy_on_model_validation = False
|
34
|
+
_reset_fields: ClassVar[Set[str]] = set()
|
68
35
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
36
|
+
model_config = ConfigDict(
|
37
|
+
ser_json_timedelta="float",
|
38
|
+
defer_build=True,
|
39
|
+
extra=(
|
40
|
+
"ignore"
|
41
|
+
if os.getenv("PREFECT_TEST_MODE", "0").lower() not in ["true", "1"]
|
42
|
+
else "forbid"
|
43
|
+
),
|
44
|
+
)
|
78
45
|
|
79
46
|
def __eq__(self, other: Any) -> bool:
|
80
47
|
"""Equaltiy operator that ignores the resettable fields of the PrefectBaseModel.
|
@@ -82,124 +49,47 @@ class PrefectBaseModel(BaseModel):
|
|
82
49
|
NOTE: this equality operator will only be applied if the PrefectBaseModel is
|
83
50
|
the left-hand operand. This is a limitation of Python.
|
84
51
|
"""
|
85
|
-
copy_dict = self.
|
52
|
+
copy_dict = self.model_dump(exclude=self._reset_fields)
|
86
53
|
if isinstance(other, PrefectBaseModel):
|
87
|
-
return copy_dict == other.
|
54
|
+
return copy_dict == other.model_dump(exclude=other._reset_fields)
|
88
55
|
if isinstance(other, BaseModel):
|
89
|
-
return copy_dict == other.
|
56
|
+
return copy_dict == other.model_dump()
|
90
57
|
else:
|
91
58
|
return copy_dict == other
|
92
59
|
|
93
|
-
def json(self, *args, include_secrets: bool = False, **kwargs) -> str:
|
94
|
-
"""
|
95
|
-
Returns a representation of the model as JSON.
|
96
|
-
|
97
|
-
If `include_secrets=True`, then `SecretStr` and `SecretBytes` objects are
|
98
|
-
fully revealed. Otherwise they are obfuscated.
|
99
|
-
|
100
|
-
"""
|
101
|
-
if include_secrets:
|
102
|
-
if "encoder" in kwargs:
|
103
|
-
raise ValueError(
|
104
|
-
"Alternative encoder provided; can not set encoder for"
|
105
|
-
" SecretFields."
|
106
|
-
)
|
107
|
-
kwargs["encoder"] = partial(
|
108
|
-
custom_pydantic_encoder,
|
109
|
-
{SecretField: lambda v: v.get_secret_value() if v else None},
|
110
|
-
)
|
111
|
-
return super().json(*args, **kwargs)
|
112
|
-
|
113
|
-
def dict(
|
114
|
-
self, *args, shallow: bool = False, json_compatible: bool = False, **kwargs
|
115
|
-
) -> dict:
|
116
|
-
"""Returns a representation of the model as a Python dictionary.
|
117
|
-
|
118
|
-
For more information on this distinction please see
|
119
|
-
https://pydantic-docs.helpmanual.io/usage/exporting_models/#dictmodel-and-iteration
|
120
|
-
|
121
|
-
|
122
|
-
Args:
|
123
|
-
shallow (bool, optional): If True (default), nested Pydantic fields
|
124
|
-
are also coerced to dicts. If false, they are left as Pydantic
|
125
|
-
models.
|
126
|
-
json_compatible (bool, optional): if True, objects are converted
|
127
|
-
into json-compatible representations, similar to calling
|
128
|
-
`json.loads(self.json())`. Not compatible with shallow=True.
|
129
|
-
|
130
|
-
Returns:
|
131
|
-
dict
|
132
|
-
"""
|
133
|
-
|
134
|
-
if json_compatible and shallow:
|
135
|
-
raise ValueError(
|
136
|
-
"`json_compatible` can only be applied to the entire object."
|
137
|
-
)
|
138
|
-
|
139
|
-
# return a json-compatible representation of the object
|
140
|
-
elif json_compatible:
|
141
|
-
return json.loads(self.json(*args, **kwargs))
|
142
|
-
|
143
|
-
# if shallow wasn't requested, return the standard pydantic behavior
|
144
|
-
elif not shallow:
|
145
|
-
return super().dict(*args, **kwargs)
|
146
|
-
|
147
|
-
# if no options were requested, return simple dict transformation
|
148
|
-
# to apply shallow conversion
|
149
|
-
elif not args and not kwargs:
|
150
|
-
return dict(self)
|
151
|
-
|
152
|
-
# if options like include/exclude were provided, perform
|
153
|
-
# a full dict conversion then overwrite with any shallow
|
154
|
-
# differences
|
155
|
-
else:
|
156
|
-
deep_dict = super().dict(*args, **kwargs)
|
157
|
-
shallow_dict = dict(self)
|
158
|
-
for k, v in list(deep_dict.items()):
|
159
|
-
if isinstance(v, dict) and isinstance(shallow_dict[k], BaseModel):
|
160
|
-
deep_dict[k] = shallow_dict[k]
|
161
|
-
return deep_dict
|
162
|
-
|
163
|
-
def copy(
|
164
|
-
self: T, *, update: Dict = None, reset_fields: bool = False, **kwargs: Any
|
165
|
-
) -> T:
|
166
|
-
"""
|
167
|
-
Duplicate a model.
|
168
|
-
|
169
|
-
Args:
|
170
|
-
update: values to change/add to the model copy
|
171
|
-
reset_fields: if True, reset the fields specified in `self._reset_fields`
|
172
|
-
to their default value on the new model
|
173
|
-
kwargs: kwargs to pass to `pydantic.BaseModel.copy`
|
174
|
-
|
175
|
-
Returns:
|
176
|
-
A new copy of the model
|
177
|
-
"""
|
178
|
-
if reset_fields:
|
179
|
-
update = update or dict()
|
180
|
-
for field in self._reset_fields():
|
181
|
-
update.setdefault(field, self.__fields__[field].get_default())
|
182
|
-
return super().copy(update=update, **kwargs)
|
183
|
-
|
184
60
|
def __rich_repr__(self):
|
185
61
|
# Display all of the fields in the model if they differ from the default value
|
186
|
-
for name, field in self.
|
62
|
+
for name, field in self.model_fields.items():
|
187
63
|
value = getattr(self, name)
|
188
64
|
|
189
65
|
# Simplify the display of some common fields
|
190
|
-
if field.
|
66
|
+
if field.annotation == UUID and value:
|
191
67
|
value = str(value)
|
192
68
|
elif (
|
193
|
-
isinstance(field.
|
69
|
+
isinstance(field.annotation, datetime.datetime)
|
194
70
|
and name == "timestamp"
|
195
71
|
and value
|
196
72
|
):
|
197
73
|
value = pendulum.instance(value).isoformat()
|
198
|
-
elif isinstance(field.
|
74
|
+
elif isinstance(field.annotation, datetime.datetime) and value:
|
199
75
|
value = pendulum.instance(value).diff_for_humans()
|
200
76
|
|
201
77
|
yield name, value, field.get_default()
|
202
78
|
|
79
|
+
def reset_fields(self: Self) -> Self:
|
80
|
+
"""
|
81
|
+
Reset the fields of the model that are in the `_reset_fields` set.
|
82
|
+
|
83
|
+
Returns:
|
84
|
+
PrefectBaseModel: A new instance of the model with the reset fields.
|
85
|
+
"""
|
86
|
+
return self.model_copy(
|
87
|
+
update={
|
88
|
+
field: self.model_fields[field].get_default(call_default_factory=True)
|
89
|
+
for field in self._reset_fields
|
90
|
+
}
|
91
|
+
)
|
92
|
+
|
203
93
|
|
204
94
|
class IDBaseModel(PrefectBaseModel):
|
205
95
|
"""
|
@@ -208,11 +98,9 @@ class IDBaseModel(PrefectBaseModel):
|
|
208
98
|
The ID is reset on copy() and not included in equality comparisons.
|
209
99
|
"""
|
210
100
|
|
101
|
+
_reset_fields: ClassVar[Set[str]] = {"id"}
|
211
102
|
id: UUID = Field(default_factory=uuid4)
|
212
103
|
|
213
|
-
def _reset_fields(self) -> Set[str]:
|
214
|
-
return super()._reset_fields().union({"id"})
|
215
|
-
|
216
104
|
|
217
105
|
class ObjectBaseModel(IDBaseModel):
|
218
106
|
"""
|
@@ -223,32 +111,12 @@ class ObjectBaseModel(IDBaseModel):
|
|
223
111
|
equality comparisons.
|
224
112
|
"""
|
225
113
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
created: Optional[DateTimeTZ] = Field(default=None, repr=False)
|
230
|
-
updated: Optional[DateTimeTZ] = Field(default=None, repr=False)
|
114
|
+
_reset_fields: ClassVar[Set[str]] = {"id", "created", "updated"}
|
115
|
+
model_config = ConfigDict(from_attributes=True)
|
231
116
|
|
232
|
-
|
233
|
-
|
117
|
+
created: Optional[DateTime] = Field(default=None, repr=False)
|
118
|
+
updated: Optional[DateTime] = Field(default=None, repr=False)
|
234
119
|
|
235
120
|
|
236
121
|
class ActionBaseModel(PrefectBaseModel):
|
237
|
-
|
238
|
-
extra = "forbid"
|
239
|
-
|
240
|
-
def __iter__(self):
|
241
|
-
# By default, `pydantic.BaseModel.__iter__` yields from `self.__dict__` directly
|
242
|
-
# instead of going through `_iter`. We want tor retain our custom logic in
|
243
|
-
# `_iter` during `dict(model)` calls which is what Pydantic uses for
|
244
|
-
# `parse_obj(model)`
|
245
|
-
yield from self._iter(to_dict=True)
|
246
|
-
|
247
|
-
def _iter(self, *args, **kwargs) -> Generator[tuple, None, None]:
|
248
|
-
# Drop fields that are marked as `ignored` from json and dictionary outputs
|
249
|
-
exclude = kwargs.pop("exclude", None) or set()
|
250
|
-
for name, field in self.__fields__.items():
|
251
|
-
if field.field_info.extra.get("ignored"):
|
252
|
-
exclude.add(name)
|
253
|
-
|
254
|
-
return super()._iter(*args, **kwargs, exclude=exclude)
|
122
|
+
model_config: ConfigDict = ConfigDict(extra="forbid")
|
@@ -1,49 +1,7 @@
|
|
1
|
-
import datetime
|
2
1
|
from typing import Optional
|
3
2
|
from uuid import UUID
|
4
3
|
|
5
|
-
import
|
6
|
-
from typing_extensions import TypeAlias
|
7
|
-
|
8
|
-
from prefect._internal.pydantic import HAS_PYDANTIC_V2
|
9
|
-
|
10
|
-
if HAS_PYDANTIC_V2:
|
11
|
-
from pydantic.v1 import BaseModel, Field
|
12
|
-
else:
|
13
|
-
from pydantic import BaseModel, Field
|
14
|
-
|
15
|
-
|
16
|
-
# Rather than subclassing pendulum.DateTime to add our pydantic-specific validation,
|
17
|
-
# which will lead to a lot of funky typing issues, we'll just monkeypatch the pydantic
|
18
|
-
# validators onto the class. Retaining this type alias means that we can still use it
|
19
|
-
# as we have been in class definitions, also guaranteeing that we'll be applying these
|
20
|
-
# validators by importing this module.
|
21
|
-
|
22
|
-
DateTimeTZ: TypeAlias = pendulum.DateTime
|
23
|
-
|
24
|
-
|
25
|
-
def _datetime_patched_classmethod(function):
|
26
|
-
if hasattr(DateTimeTZ, function.__name__):
|
27
|
-
return function
|
28
|
-
setattr(DateTimeTZ, function.__name__, classmethod(function))
|
29
|
-
return function
|
30
|
-
|
31
|
-
|
32
|
-
@_datetime_patched_classmethod
|
33
|
-
def __get_validators__(cls):
|
34
|
-
yield getattr(cls, "validate")
|
35
|
-
|
36
|
-
|
37
|
-
@_datetime_patched_classmethod
|
38
|
-
def validate(cls, v) -> pendulum.DateTime:
|
39
|
-
if isinstance(v, str):
|
40
|
-
parsed = pendulum.parse(v)
|
41
|
-
assert isinstance(parsed, pendulum.DateTime)
|
42
|
-
return parsed
|
43
|
-
elif isinstance(v, datetime.datetime):
|
44
|
-
return pendulum.instance(v)
|
45
|
-
else:
|
46
|
-
raise ValueError("Unrecognized datetime.")
|
4
|
+
from pydantic import BaseModel, Field
|
47
5
|
|
48
6
|
|
49
7
|
class CreatedBy(BaseModel):
|