prefect-client 2.19.4__py3-none-any.whl → 3.0.0rc2__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.
Files changed (242) hide show
  1. prefect/__init__.py +8 -56
  2. prefect/_internal/compatibility/deprecated.py +6 -115
  3. prefect/_internal/compatibility/experimental.py +4 -79
  4. prefect/_internal/concurrency/api.py +0 -34
  5. prefect/_internal/concurrency/calls.py +0 -6
  6. prefect/_internal/concurrency/cancellation.py +0 -3
  7. prefect/_internal/concurrency/event_loop.py +0 -20
  8. prefect/_internal/concurrency/inspection.py +3 -3
  9. prefect/_internal/concurrency/threads.py +35 -0
  10. prefect/_internal/concurrency/waiters.py +0 -28
  11. prefect/_internal/pydantic/__init__.py +0 -45
  12. prefect/_internal/pydantic/v1_schema.py +21 -22
  13. prefect/_internal/pydantic/v2_schema.py +0 -2
  14. prefect/_internal/pydantic/v2_validated_func.py +18 -23
  15. prefect/_internal/schemas/bases.py +44 -177
  16. prefect/_internal/schemas/fields.py +1 -43
  17. prefect/_internal/schemas/validators.py +60 -158
  18. prefect/artifacts.py +161 -14
  19. prefect/automations.py +39 -4
  20. prefect/blocks/abstract.py +1 -1
  21. prefect/blocks/core.py +268 -148
  22. prefect/blocks/fields.py +2 -57
  23. prefect/blocks/kubernetes.py +8 -12
  24. prefect/blocks/notifications.py +40 -20
  25. prefect/blocks/redis.py +168 -0
  26. prefect/blocks/system.py +22 -11
  27. prefect/blocks/webhook.py +2 -9
  28. prefect/client/base.py +4 -4
  29. prefect/client/cloud.py +8 -13
  30. prefect/client/orchestration.py +362 -340
  31. prefect/client/schemas/actions.py +92 -86
  32. prefect/client/schemas/filters.py +20 -40
  33. prefect/client/schemas/objects.py +158 -152
  34. prefect/client/schemas/responses.py +16 -24
  35. prefect/client/schemas/schedules.py +47 -35
  36. prefect/client/subscriptions.py +2 -2
  37. prefect/client/utilities.py +5 -2
  38. prefect/concurrency/asyncio.py +4 -2
  39. prefect/concurrency/events.py +1 -1
  40. prefect/concurrency/services.py +7 -4
  41. prefect/context.py +195 -27
  42. prefect/deployments/__init__.py +5 -6
  43. prefect/deployments/base.py +7 -5
  44. prefect/deployments/flow_runs.py +185 -0
  45. prefect/deployments/runner.py +50 -45
  46. prefect/deployments/schedules.py +28 -23
  47. prefect/deployments/steps/__init__.py +0 -1
  48. prefect/deployments/steps/core.py +1 -0
  49. prefect/deployments/steps/pull.py +7 -21
  50. prefect/engine.py +12 -2422
  51. prefect/events/actions.py +17 -23
  52. prefect/events/cli/automations.py +19 -6
  53. prefect/events/clients.py +14 -37
  54. prefect/events/filters.py +14 -18
  55. prefect/events/related.py +2 -2
  56. prefect/events/schemas/__init__.py +0 -5
  57. prefect/events/schemas/automations.py +55 -46
  58. prefect/events/schemas/deployment_triggers.py +7 -197
  59. prefect/events/schemas/events.py +36 -65
  60. prefect/events/schemas/labelling.py +10 -14
  61. prefect/events/utilities.py +2 -3
  62. prefect/events/worker.py +2 -3
  63. prefect/filesystems.py +6 -517
  64. prefect/{new_flow_engine.py → flow_engine.py} +315 -74
  65. prefect/flow_runs.py +379 -7
  66. prefect/flows.py +248 -165
  67. prefect/futures.py +187 -345
  68. prefect/infrastructure/__init__.py +0 -27
  69. prefect/infrastructure/provisioners/__init__.py +5 -3
  70. prefect/infrastructure/provisioners/cloud_run.py +11 -6
  71. prefect/infrastructure/provisioners/container_instance.py +11 -7
  72. prefect/infrastructure/provisioners/ecs.py +6 -4
  73. prefect/infrastructure/provisioners/modal.py +8 -5
  74. prefect/input/actions.py +2 -4
  75. prefect/input/run_input.py +9 -9
  76. prefect/logging/formatters.py +0 -2
  77. prefect/logging/handlers.py +3 -11
  78. prefect/logging/loggers.py +2 -2
  79. prefect/manifests.py +2 -1
  80. prefect/records/__init__.py +1 -0
  81. prefect/records/cache_policies.py +179 -0
  82. prefect/records/result_store.py +42 -0
  83. prefect/records/store.py +9 -0
  84. prefect/results.py +43 -39
  85. prefect/runner/runner.py +9 -9
  86. prefect/runner/server.py +6 -10
  87. prefect/runner/storage.py +3 -8
  88. prefect/runner/submit.py +2 -2
  89. prefect/runner/utils.py +2 -2
  90. prefect/serializers.py +24 -35
  91. prefect/server/api/collections_data/views/aggregate-worker-metadata.json +5 -14
  92. prefect/settings.py +76 -136
  93. prefect/states.py +22 -50
  94. prefect/task_engine.py +666 -56
  95. prefect/task_runners.py +272 -300
  96. prefect/task_runs.py +203 -0
  97. prefect/{task_server.py → task_worker.py} +89 -60
  98. prefect/tasks.py +358 -341
  99. prefect/transactions.py +224 -0
  100. prefect/types/__init__.py +61 -82
  101. prefect/utilities/asyncutils.py +195 -136
  102. prefect/utilities/callables.py +121 -41
  103. prefect/utilities/collections.py +23 -38
  104. prefect/utilities/dispatch.py +11 -3
  105. prefect/utilities/dockerutils.py +4 -0
  106. prefect/utilities/engine.py +140 -20
  107. prefect/utilities/importtools.py +26 -27
  108. prefect/utilities/pydantic.py +128 -38
  109. prefect/utilities/schema_tools/hydration.py +5 -1
  110. prefect/utilities/templating.py +12 -2
  111. prefect/variables.py +84 -62
  112. prefect/workers/__init__.py +0 -1
  113. prefect/workers/base.py +26 -18
  114. prefect/workers/process.py +3 -8
  115. prefect/workers/server.py +2 -2
  116. {prefect_client-2.19.4.dist-info → prefect_client-3.0.0rc2.dist-info}/METADATA +23 -21
  117. prefect_client-3.0.0rc2.dist-info/RECORD +179 -0
  118. prefect/_internal/pydantic/_base_model.py +0 -51
  119. prefect/_internal/pydantic/_compat.py +0 -82
  120. prefect/_internal/pydantic/_flags.py +0 -20
  121. prefect/_internal/pydantic/_types.py +0 -8
  122. prefect/_internal/pydantic/utilities/__init__.py +0 -0
  123. prefect/_internal/pydantic/utilities/config_dict.py +0 -72
  124. prefect/_internal/pydantic/utilities/field_validator.py +0 -150
  125. prefect/_internal/pydantic/utilities/model_construct.py +0 -56
  126. prefect/_internal/pydantic/utilities/model_copy.py +0 -55
  127. prefect/_internal/pydantic/utilities/model_dump.py +0 -136
  128. prefect/_internal/pydantic/utilities/model_dump_json.py +0 -112
  129. prefect/_internal/pydantic/utilities/model_fields.py +0 -50
  130. prefect/_internal/pydantic/utilities/model_fields_set.py +0 -29
  131. prefect/_internal/pydantic/utilities/model_json_schema.py +0 -82
  132. prefect/_internal/pydantic/utilities/model_rebuild.py +0 -80
  133. prefect/_internal/pydantic/utilities/model_validate.py +0 -75
  134. prefect/_internal/pydantic/utilities/model_validate_json.py +0 -68
  135. prefect/_internal/pydantic/utilities/model_validator.py +0 -87
  136. prefect/_internal/pydantic/utilities/type_adapter.py +0 -71
  137. prefect/_vendor/__init__.py +0 -0
  138. prefect/_vendor/fastapi/__init__.py +0 -25
  139. prefect/_vendor/fastapi/applications.py +0 -946
  140. prefect/_vendor/fastapi/background.py +0 -3
  141. prefect/_vendor/fastapi/concurrency.py +0 -44
  142. prefect/_vendor/fastapi/datastructures.py +0 -58
  143. prefect/_vendor/fastapi/dependencies/__init__.py +0 -0
  144. prefect/_vendor/fastapi/dependencies/models.py +0 -64
  145. prefect/_vendor/fastapi/dependencies/utils.py +0 -877
  146. prefect/_vendor/fastapi/encoders.py +0 -177
  147. prefect/_vendor/fastapi/exception_handlers.py +0 -40
  148. prefect/_vendor/fastapi/exceptions.py +0 -46
  149. prefect/_vendor/fastapi/logger.py +0 -3
  150. prefect/_vendor/fastapi/middleware/__init__.py +0 -1
  151. prefect/_vendor/fastapi/middleware/asyncexitstack.py +0 -25
  152. prefect/_vendor/fastapi/middleware/cors.py +0 -3
  153. prefect/_vendor/fastapi/middleware/gzip.py +0 -3
  154. prefect/_vendor/fastapi/middleware/httpsredirect.py +0 -3
  155. prefect/_vendor/fastapi/middleware/trustedhost.py +0 -3
  156. prefect/_vendor/fastapi/middleware/wsgi.py +0 -3
  157. prefect/_vendor/fastapi/openapi/__init__.py +0 -0
  158. prefect/_vendor/fastapi/openapi/constants.py +0 -2
  159. prefect/_vendor/fastapi/openapi/docs.py +0 -203
  160. prefect/_vendor/fastapi/openapi/models.py +0 -480
  161. prefect/_vendor/fastapi/openapi/utils.py +0 -485
  162. prefect/_vendor/fastapi/param_functions.py +0 -340
  163. prefect/_vendor/fastapi/params.py +0 -453
  164. prefect/_vendor/fastapi/requests.py +0 -4
  165. prefect/_vendor/fastapi/responses.py +0 -40
  166. prefect/_vendor/fastapi/routing.py +0 -1331
  167. prefect/_vendor/fastapi/security/__init__.py +0 -15
  168. prefect/_vendor/fastapi/security/api_key.py +0 -98
  169. prefect/_vendor/fastapi/security/base.py +0 -6
  170. prefect/_vendor/fastapi/security/http.py +0 -172
  171. prefect/_vendor/fastapi/security/oauth2.py +0 -227
  172. prefect/_vendor/fastapi/security/open_id_connect_url.py +0 -34
  173. prefect/_vendor/fastapi/security/utils.py +0 -10
  174. prefect/_vendor/fastapi/staticfiles.py +0 -1
  175. prefect/_vendor/fastapi/templating.py +0 -3
  176. prefect/_vendor/fastapi/testclient.py +0 -1
  177. prefect/_vendor/fastapi/types.py +0 -3
  178. prefect/_vendor/fastapi/utils.py +0 -235
  179. prefect/_vendor/fastapi/websockets.py +0 -7
  180. prefect/_vendor/starlette/__init__.py +0 -1
  181. prefect/_vendor/starlette/_compat.py +0 -28
  182. prefect/_vendor/starlette/_exception_handler.py +0 -80
  183. prefect/_vendor/starlette/_utils.py +0 -88
  184. prefect/_vendor/starlette/applications.py +0 -261
  185. prefect/_vendor/starlette/authentication.py +0 -159
  186. prefect/_vendor/starlette/background.py +0 -43
  187. prefect/_vendor/starlette/concurrency.py +0 -59
  188. prefect/_vendor/starlette/config.py +0 -151
  189. prefect/_vendor/starlette/convertors.py +0 -87
  190. prefect/_vendor/starlette/datastructures.py +0 -707
  191. prefect/_vendor/starlette/endpoints.py +0 -130
  192. prefect/_vendor/starlette/exceptions.py +0 -60
  193. prefect/_vendor/starlette/formparsers.py +0 -276
  194. prefect/_vendor/starlette/middleware/__init__.py +0 -17
  195. prefect/_vendor/starlette/middleware/authentication.py +0 -52
  196. prefect/_vendor/starlette/middleware/base.py +0 -220
  197. prefect/_vendor/starlette/middleware/cors.py +0 -176
  198. prefect/_vendor/starlette/middleware/errors.py +0 -265
  199. prefect/_vendor/starlette/middleware/exceptions.py +0 -74
  200. prefect/_vendor/starlette/middleware/gzip.py +0 -113
  201. prefect/_vendor/starlette/middleware/httpsredirect.py +0 -19
  202. prefect/_vendor/starlette/middleware/sessions.py +0 -82
  203. prefect/_vendor/starlette/middleware/trustedhost.py +0 -64
  204. prefect/_vendor/starlette/middleware/wsgi.py +0 -147
  205. prefect/_vendor/starlette/requests.py +0 -328
  206. prefect/_vendor/starlette/responses.py +0 -347
  207. prefect/_vendor/starlette/routing.py +0 -933
  208. prefect/_vendor/starlette/schemas.py +0 -154
  209. prefect/_vendor/starlette/staticfiles.py +0 -248
  210. prefect/_vendor/starlette/status.py +0 -199
  211. prefect/_vendor/starlette/templating.py +0 -231
  212. prefect/_vendor/starlette/testclient.py +0 -804
  213. prefect/_vendor/starlette/types.py +0 -30
  214. prefect/_vendor/starlette/websockets.py +0 -193
  215. prefect/agent.py +0 -698
  216. prefect/deployments/deployments.py +0 -1042
  217. prefect/deprecated/__init__.py +0 -0
  218. prefect/deprecated/data_documents.py +0 -350
  219. prefect/deprecated/packaging/__init__.py +0 -12
  220. prefect/deprecated/packaging/base.py +0 -96
  221. prefect/deprecated/packaging/docker.py +0 -146
  222. prefect/deprecated/packaging/file.py +0 -92
  223. prefect/deprecated/packaging/orion.py +0 -80
  224. prefect/deprecated/packaging/serializers.py +0 -171
  225. prefect/events/instrument.py +0 -135
  226. prefect/infrastructure/base.py +0 -323
  227. prefect/infrastructure/container.py +0 -818
  228. prefect/infrastructure/kubernetes.py +0 -920
  229. prefect/infrastructure/process.py +0 -289
  230. prefect/new_task_engine.py +0 -423
  231. prefect/pydantic/__init__.py +0 -76
  232. prefect/pydantic/main.py +0 -39
  233. prefect/software/__init__.py +0 -2
  234. prefect/software/base.py +0 -50
  235. prefect/software/conda.py +0 -199
  236. prefect/software/pip.py +0 -122
  237. prefect/software/python.py +0 -52
  238. prefect/workers/block.py +0 -218
  239. prefect_client-2.19.4.dist-info/RECORD +0 -292
  240. {prefect_client-2.19.4.dist-info → prefect_client-3.0.0rc2.dist-info}/LICENSE +0 -0
  241. {prefect_client-2.19.4.dist-info → prefect_client-3.0.0rc2.dist-info}/WHEEL +0 -0
  242. {prefect_client-2.19.4.dist-info → prefect_client-3.0.0rc2.dist-info}/top_level.txt +0 -0
File without changes
@@ -1,350 +0,0 @@
1
- import base64
2
- import json
3
- import uuid
4
- import warnings
5
- from typing import (
6
- TYPE_CHECKING,
7
- Any,
8
- Dict,
9
- Generic,
10
- Iterable,
11
- Tuple,
12
- Type,
13
- TypeVar,
14
- Union,
15
- )
16
-
17
- import cloudpickle
18
-
19
- from prefect._internal.pydantic import HAS_PYDANTIC_V2
20
-
21
- if HAS_PYDANTIC_V2:
22
- import pydantic.v1 as pydantic
23
- else:
24
- import pydantic
25
-
26
- from typing_extensions import Protocol
27
-
28
- from prefect._internal.compatibility.deprecated import (
29
- deprecated_callable,
30
- generate_deprecation_message,
31
- )
32
- from prefect._internal.schemas.bases import PrefectBaseModel
33
-
34
- if TYPE_CHECKING:
35
- from prefect.deprecated.packaging.base import PackageManifest
36
-
37
- T = TypeVar("T", bound="DataDocument") # Generic for DataDocument class types
38
- D = TypeVar("D", bound=Any) # Generic for DataDocument data types
39
-
40
-
41
- _SERIALIZERS: Dict[str, "Serializer"] = {}
42
-
43
-
44
- class Serializer(Protocol[D]):
45
- """
46
- Define a serializer that can encode data of type 'D' into bytes
47
- """
48
-
49
- @staticmethod
50
- def dumps(data: D, **kwargs: Any) -> bytes:
51
- raise NotImplementedError
52
-
53
- @staticmethod
54
- def loads(blob: bytes) -> D:
55
- raise NotImplementedError
56
-
57
-
58
- def register_serializer(
59
- encoding: Union[str, Tuple[str, ...]], serializer: Serializer = None
60
- ):
61
- """Register dispatch of `func` on arguments of encoding `encoding`"""
62
-
63
- def wrapper(serializer):
64
- if isinstance(encoding, tuple):
65
- for e in encoding:
66
- register_serializer(e, serializer)
67
- else:
68
- _SERIALIZERS[encoding] = serializer
69
- return serializer
70
-
71
- return wrapper(serializer) if serializer is not None else wrapper
72
-
73
-
74
- def lookup_serializer(encoding: str) -> Serializer:
75
- """Return the serializer implementation for the given ``encoding``"""
76
- try:
77
- return _SERIALIZERS[encoding]
78
- except KeyError:
79
- raise ValueError(f"Unregistered encoding {encoding!r}")
80
-
81
-
82
- class DataDocument(PrefectBaseModel, Generic[D]):
83
- """
84
- A data document includes an encoding string and a blob of encoded data
85
-
86
- Subclasses can define the expected type for the blob's underlying type using the
87
- generic variable `D`.
88
-
89
- For example `DataDocument[str]` indicates that a string should be passed when
90
- creating the document and a string will be returned when it is decoded.
91
- """
92
-
93
- encoding: str
94
- blob: bytes
95
-
96
- # A cache for the decoded data, see `DataDocument.decode`
97
- _data: D
98
- __slots__ = ["_data"]
99
-
100
- @classmethod
101
- @deprecated_callable(
102
- start_date="Sep 2022",
103
- help="Data documents should not be created. Use result persistence instead.",
104
- )
105
- def encode(
106
- cls: Type["DataDocument"], encoding: str, data: D, **kwargs: Any
107
- ) -> "DataDocument[D]":
108
- """
109
- Create a new data document
110
-
111
- A serializer must be registered for the given `encoding`
112
- """
113
- # Dispatch encoding
114
- blob = lookup_serializer(encoding).dumps(data, **kwargs)
115
-
116
- inst = cls(blob=blob, encoding=encoding)
117
- inst._cache_data(data)
118
- return inst
119
-
120
- def decode(self) -> D:
121
- """
122
- Get the data from a data document
123
-
124
- A serializer must be registered for the document's encoding
125
- """
126
- if self.has_cached_data():
127
- return self._data
128
-
129
- # Dispatch decoding
130
- data = lookup_serializer(self.encoding).loads(self.blob)
131
-
132
- self._cache_data(data)
133
- return data
134
-
135
- def _cache_data(self, data) -> None:
136
- # Use object's setattr to avoid a pydantic 'field does not exist' error
137
- # See https://github.com/samuelcolvin/pydantic/issues/655
138
- object.__setattr__(self, "_data", data)
139
-
140
- def has_cached_data(self):
141
- return hasattr(self, "_data")
142
-
143
- def __str__(self) -> str:
144
- if self.has_cached_data():
145
- return repr(self._data)
146
- else:
147
- return repr(self)
148
-
149
- def __repr__(self) -> str:
150
- return f"{type(self).__name__}(encoding={self.encoding!r})"
151
-
152
-
153
- @register_serializer("json")
154
- class DocumentJSONSerializer:
155
- """
156
- Serializes data to JSON.
157
-
158
- Input types must be compatible with the stdlib json library.
159
-
160
- Wraps the `json` library to serialize to UTF-8 bytes instead of string types.
161
- """
162
-
163
- @staticmethod
164
- @deprecated_callable(
165
- start_date="Sep 2022",
166
- help=(
167
- "Data document serializers should not be used. Use result serializers"
168
- " instead."
169
- ),
170
- )
171
- def dumps(data: Any) -> bytes:
172
- return json.dumps(data).encode()
173
-
174
- @staticmethod
175
- def loads(blob: bytes) -> Any:
176
- return json.loads(blob.decode())
177
-
178
-
179
- @register_serializer("text")
180
- class TextSerializer:
181
- @staticmethod
182
- @deprecated_callable(
183
- start_date="Sep 2022",
184
- help=(
185
- "Data document serializers should not be used. Use result serializers"
186
- " instead."
187
- ),
188
- )
189
- def dumps(data: str) -> bytes:
190
- return data.encode()
191
-
192
- @staticmethod
193
- def loads(blob: bytes) -> str:
194
- return blob.decode()
195
-
196
-
197
- @register_serializer("cloudpickle")
198
- class DocumentPickleSerializer:
199
- """
200
- Serializes arbitrary objects using the pickle protocol.
201
-
202
- Wraps `cloudpickle` to encode bytes in base64 for safe transmission.
203
- """
204
-
205
- @staticmethod
206
- @deprecated_callable(
207
- start_date="Sep 2022",
208
- help=(
209
- "Data document serializers should not be used. Use result serializers"
210
- " instead."
211
- ),
212
- )
213
- def dumps(data: Any) -> bytes:
214
- data_bytes = cloudpickle.dumps(data)
215
-
216
- return base64.encodebytes(data_bytes)
217
-
218
- @staticmethod
219
- def loads(blob: bytes) -> Any:
220
- return cloudpickle.loads(base64.decodebytes(blob))
221
- # TODO: Consider adding python version data to pickle payloads to raise
222
- # more helpful errors for users.
223
- # A TypeError("expected bytes-like object, not int") will be raised if
224
- # a document is deserialized by Python 3.7 and serialized by 3.8+
225
-
226
-
227
- @register_serializer("package-manifest")
228
- class PackageManifestSerializer:
229
- """
230
- Serializes a package manifest.
231
- """
232
-
233
- @staticmethod
234
- @deprecated_callable(
235
- start_date="Sep 2022",
236
- help=(
237
- "Data document serializers should not be used. Use result serializers"
238
- " instead."
239
- ),
240
- )
241
- def dumps(data: "PackageManifest") -> bytes:
242
- return data.json().encode()
243
-
244
- @staticmethod
245
- def loads(blob: bytes) -> "PackageManifest":
246
- from prefect.deprecated.packaging.base import PackageManifest
247
-
248
- return PackageManifest.parse_raw(blob)
249
-
250
-
251
- @register_serializer("result")
252
- class ResultSerializer:
253
- """
254
- Serializes a result object
255
- """
256
-
257
- @staticmethod
258
- @deprecated_callable(
259
- start_date="Sep 2022",
260
- help=(
261
- "Data document serializers should not be used. Use result serializers"
262
- " instead."
263
- ),
264
- )
265
- def dumps(data: "_Result") -> bytes:
266
- return data.json().encode()
267
-
268
- @staticmethod
269
- def loads(blob: bytes) -> "_Result":
270
- return _Result.parse_raw(blob)
271
-
272
-
273
- def result_from_state_with_data_document(state, raise_on_failure: bool) -> Any:
274
- # Complain about usage
275
- warnings.warn(
276
- generate_deprecation_message(
277
- "Retrieving results from states with data documents", start_date="Sep 2022"
278
- ),
279
- DeprecationWarning,
280
- stacklevel=3,
281
- )
282
-
283
- data = None
284
-
285
- if state.data:
286
- data = state.data.decode()
287
-
288
- from prefect.states import State
289
-
290
- if (
291
- state.is_failed() or state.is_crashed() or state.is_cancelled()
292
- ) and raise_on_failure:
293
- if isinstance(data, Exception):
294
- raise data
295
- elif isinstance(data, BaseException):
296
- warnings.warn(
297
- f"State result is a {type(data).__name__!r} type and is not safe "
298
- "to re-raise, it will be returned instead."
299
- )
300
- return data
301
- elif isinstance(data, State):
302
- data.result(fetch=False)
303
- elif isinstance(data, Iterable) and all([isinstance(o, State) for o in data]):
304
- # raise the first failure we find
305
- for state in data:
306
- state.result(fetch=False)
307
-
308
- # we don't make this an else in case any of the above conditionals doesn't raise
309
- raise TypeError(
310
- f"Unexpected result for failure state: {data!r} —— "
311
- f"{type(data).__name__} cannot be resolved into an exception"
312
- )
313
-
314
- return data
315
-
316
-
317
- async def _persist_serialized_result(
318
- content: bytes,
319
- filesystem,
320
- ) -> DataDocument:
321
- key = uuid.uuid4().hex
322
- await filesystem.write_path(key, content)
323
- result = _Result(key=key, filesystem_document_id=filesystem._block_document_id)
324
- return DataDocument.encode("result", result)
325
-
326
-
327
- async def _retrieve_serialized_result(document: DataDocument, client) -> bytes:
328
- from prefect.blocks.core import Block
329
-
330
- if document.encoding != "result":
331
- raise TypeError(
332
- f"Got unsupported data document encoding of {document.encoding!r}. "
333
- "Expected 'result'."
334
- )
335
- result = document.decode()
336
- filesystem_document = await client.read_block_document(
337
- result.filesystem_document_id
338
- )
339
- filesystem = Block._from_block_document(filesystem_document)
340
- return await filesystem.read_path(result.key)
341
-
342
-
343
- async def _retrieve_result(state, client):
344
- serialized_result = await _retrieve_serialized_result(state.data, client)
345
- return DataDocument.parse_raw(serialized_result).decode()
346
-
347
-
348
- class _Result(pydantic.BaseModel):
349
- key: str
350
- filesystem_document_id: uuid.UUID
@@ -1,12 +0,0 @@
1
- """
2
- DEPRECATION WARNING:
3
- This module is deprecated as of March 2024 and will not be available after September 2024.
4
- """
5
- from prefect.deprecated.packaging.docker import DockerPackager
6
- from prefect.deprecated.packaging.file import FilePackager
7
- from prefect.deprecated.packaging.orion import OrionPackager
8
-
9
- # isort: split
10
-
11
- # Register any packaging serializers
12
- import prefect.deprecated.packaging.serializers
@@ -1,96 +0,0 @@
1
- """
2
- DEPRECATION WARNING:
3
- This module is deprecated as of March 2024 and will not be available after September 2024.
4
- """
5
-
6
- import abc
7
- from typing import Generic, Type, TypeVar
8
-
9
- from prefect._internal.compatibility.deprecated import deprecated_class
10
- from prefect._internal.pydantic import HAS_PYDANTIC_V2
11
-
12
- if HAS_PYDANTIC_V2:
13
- from pydantic.v1 import BaseModel
14
- else:
15
- from pydantic import BaseModel
16
-
17
- from prefect.flows import Flow
18
- from prefect.utilities.callables import ParameterSchema, parameter_schema
19
- from prefect.utilities.dispatch import lookup_type
20
- from prefect.utilities.pydantic import add_type_dispatch
21
-
22
- D = TypeVar("D")
23
-
24
-
25
- @deprecated_class(start_date="Mar 2024")
26
- @add_type_dispatch
27
- class Serializer(BaseModel, Generic[D], abc.ABC):
28
- """
29
- DEPRECATION WARNING:
30
-
31
- This class is deprecated as of version March 2024 and will not be available after September 2024.
32
-
33
- A serializer that can encode objects of type 'D' into bytes.
34
- """
35
-
36
- type: str
37
-
38
- def dumps(self, obj: D) -> bytes:
39
- """Encode the object into a blob of bytes."""
40
-
41
- def loads(self, blob: bytes) -> D:
42
- """Decode the blob of bytes into an object."""
43
-
44
-
45
- @deprecated_class(start_date="Mar 2024")
46
- @add_type_dispatch
47
- class PackageManifest(BaseModel, abc.ABC):
48
- """
49
- DEPRECATION WARNING:
50
-
51
- This class is deprecated as of version March 2024 and will not be available after September 2024.
52
-
53
- Describes a package.
54
- """
55
-
56
- type: str
57
- flow_name: str
58
- flow_parameter_schema: ParameterSchema
59
-
60
- @abc.abstractmethod
61
- async def unpackage(self) -> Flow:
62
- """
63
- Retrieve a flow from the package.
64
- """
65
-
66
-
67
- @deprecated_class(start_date="Mar 2024")
68
- @add_type_dispatch
69
- class Packager(BaseModel, abc.ABC):
70
- """
71
- DEPRECATION WARNING:
72
-
73
- This class is deprecated as of version March 2024 and will not be available after September 2024.
74
-
75
- Creates a package for a flow.
76
-
77
- A package contains the flow and is typically stored outside of Prefect. To
78
- facilitate interaction with the package, a manifest is returned that describes how
79
- to access and use the package.
80
- """
81
-
82
- type: str
83
-
84
- def base_manifest(self, flow: Flow) -> PackageManifest:
85
- manifest_cls: Type[BaseModel] = lookup_type(PackageManifest, self.type)
86
- return manifest_cls.construct(
87
- type=self.type,
88
- flow_name=flow.name,
89
- flow_parameter_schema=parameter_schema(flow.fn),
90
- )
91
-
92
- @abc.abstractmethod
93
- async def package(self, flow: Flow) -> "PackageManifest":
94
- """
95
- Package a flow and return a manifest describing the created package.
96
- """
@@ -1,146 +0,0 @@
1
- """
2
- DEPRECATION WARNING:
3
- This module is deprecated as of March 2024 and will not be available after September 2024.
4
- """
5
-
6
- import json
7
- import sys
8
- from pathlib import Path
9
- from typing import Any, Mapping, Optional, Union
10
-
11
- from prefect._internal.compatibility.deprecated import deprecated_class
12
- from prefect._internal.pydantic import HAS_PYDANTIC_V2
13
- from prefect._internal.schemas.validators import (
14
- assign_default_base_image,
15
- base_image_xor_dockerfile,
16
- set_default_python_environment,
17
- validate_registry_url,
18
- )
19
-
20
- if HAS_PYDANTIC_V2:
21
- from pydantic.v1 import AnyHttpUrl, root_validator, validator
22
- else:
23
- from pydantic import AnyHttpUrl, root_validator, validator
24
- from typing_extensions import Literal
25
-
26
- from prefect.deprecated.packaging.base import PackageManifest, Packager
27
- from prefect.deprecated.packaging.serializers import SourceSerializer
28
- from prefect.flows import Flow, load_flow_from_script
29
- from prefect.software import CondaEnvironment, PythonEnvironment
30
- from prefect.utilities.asyncutils import run_sync_in_worker_thread
31
- from prefect.utilities.dockerutils import (
32
- ImageBuilder,
33
- build_image,
34
- push_image,
35
- to_run_command,
36
- )
37
- from prefect.utilities.slugify import slugify
38
-
39
-
40
- @deprecated_class(start_date="Mar 2024")
41
- class DockerPackageManifest(PackageManifest):
42
- """
43
- DEPRECATION WARNING:
44
-
45
- This class is deprecated as of version March 2024 and will not be available after September 2024.
46
-
47
- Represents a flow packaged in a Docker image
48
- """
49
-
50
- type: Literal["docker"] = "docker"
51
-
52
- image: str
53
- image_flow_location: str
54
-
55
- async def unpackage(self) -> Flow:
56
- return load_flow_from_script(self.image_flow_location, self.flow_name)
57
-
58
-
59
- @deprecated_class(start_date="Mar 2024")
60
- class DockerPackager(Packager):
61
- """
62
- DEPRECATION WARNING:
63
-
64
- This class is deprecated as of version March 2024 and will not be available after September 2024.
65
-
66
- This packager builds a Docker image containing the flow and the runtime environment
67
- necessary to run the flow. The resulting image is optionally pushed to a container
68
- registry, given by `registry_url`.
69
- """
70
-
71
- type: str = "docker"
72
-
73
- base_image: Optional[str] = None
74
- python_environment: Optional[Union[PythonEnvironment, CondaEnvironment]] = None
75
- dockerfile: Optional[Path] = None
76
- platform: Optional[str] = (None,)
77
- image_flow_location: str = "/flow.py"
78
- registry_url: Optional[AnyHttpUrl] = None
79
-
80
- @root_validator
81
- def set_default_base_image(cls, values):
82
- return assign_default_base_image(values)
83
-
84
- @root_validator
85
- def base_image_and_dockerfile_exclusive(cls, values: Mapping[str, Any]):
86
- return base_image_xor_dockerfile(values)
87
-
88
- @root_validator
89
- def default_python_environment(cls, values: Mapping[str, Any]):
90
- return set_default_python_environment(values)
91
-
92
- @validator("registry_url", pre=True)
93
- def ensure_registry_url_is_prefixed(cls, value):
94
- validate_registry_url(value)
95
-
96
- async def package(self, flow: Flow) -> DockerPackageManifest:
97
- """
98
- Package a flow as a Docker image and, optionally, push it to a registry
99
- """
100
- image_reference = await self._build_image(flow)
101
-
102
- if self.registry_url:
103
- image_name = f"{slugify(flow.name)}"
104
- image_reference = await run_sync_in_worker_thread(
105
- push_image, image_reference, self.registry_url, image_name
106
- )
107
-
108
- return DockerPackageManifest(
109
- **{
110
- **self.base_manifest(flow).dict(),
111
- **{
112
- "image": image_reference,
113
- "image_flow_location": self.image_flow_location,
114
- },
115
- }
116
- )
117
-
118
- async def _build_image(self, flow: Flow) -> str:
119
- if self.dockerfile:
120
- return await self._build_from_dockerfile()
121
- return await self._build_from_base_image(flow)
122
-
123
- async def _build_from_dockerfile(self) -> str:
124
- context = self.dockerfile.resolve().parent
125
- dockerfile = self.dockerfile.relative_to(context)
126
- return await run_sync_in_worker_thread(
127
- build_image,
128
- platform=self.platform,
129
- context=context,
130
- dockerfile=str(dockerfile),
131
- )
132
-
133
- async def _build_from_base_image(self, flow: Flow) -> str:
134
- with ImageBuilder(
135
- base_image=self.base_image, platform=self.platform
136
- ) as builder:
137
- for command in self.python_environment.install_commands():
138
- builder.add_line(to_run_command(command))
139
-
140
- source_info = json.loads(SourceSerializer().dumps(flow))
141
-
142
- builder.write_text(source_info["source"], self.image_flow_location)
143
-
144
- return await run_sync_in_worker_thread(
145
- builder.build, stream_progress_to=sys.stdout
146
- )
@@ -1,92 +0,0 @@
1
- """
2
- DEPRECATION WARNING:
3
- This module is deprecated as of March 2024 and will not be available after September 2024.
4
- """
5
-
6
- from uuid import UUID
7
-
8
- from prefect._internal.compatibility.deprecated import deprecated_class
9
- from prefect._internal.pydantic import HAS_PYDANTIC_V2
10
-
11
- if HAS_PYDANTIC_V2:
12
- from pydantic.v1 import Field
13
- else:
14
- from pydantic import Field
15
-
16
- from typing_extensions import Literal
17
-
18
- from prefect.blocks.core import Block
19
- from prefect.client.orchestration import PrefectClient
20
- from prefect.client.utilities import inject_client
21
- from prefect.deprecated.packaging.base import PackageManifest, Packager, Serializer
22
- from prefect.deprecated.packaging.serializers import SourceSerializer
23
- from prefect.filesystems import LocalFileSystem, ReadableFileSystem, WritableFileSystem
24
- from prefect.flows import Flow
25
- from prefect.settings import PREFECT_HOME
26
- from prefect.utilities.hashing import stable_hash
27
-
28
-
29
- @deprecated_class(start_date="Mar 2024")
30
- class FilePackageManifest(PackageManifest):
31
- """
32
- DEPRECATION WARNING:
33
-
34
- This class is deprecated as of version March 2024 and will not be available after September 2024.
35
- """
36
-
37
- type: str = "file"
38
- serializer: Serializer
39
- key: str
40
- filesystem_id: UUID
41
-
42
- @inject_client
43
- async def unpackage(self, client: PrefectClient) -> Flow:
44
- block_document = await client.read_block_document(self.filesystem_id)
45
- filesystem: ReadableFileSystem = Block._from_block_document(block_document)
46
- content = await filesystem.read_path(self.key)
47
- return self.serializer.loads(content)
48
-
49
-
50
- @deprecated_class(start_date="Mar 2024")
51
- class FilePackager(Packager):
52
- """
53
- DEPRECATION WARNING:
54
-
55
- This class is deprecated as of version March 2024 and will not be available after September 2024.
56
-
57
- This packager stores the flow as a single file.
58
-
59
- By default, the file is the source code of the module the flow is defined in.
60
- Alternative serialization modes are available in `prefect.deprecated.packaging.serializers`.
61
- """
62
-
63
- type: Literal["file"] = "file"
64
- serializer: Serializer = Field(default_factory=SourceSerializer)
65
- filesystem: WritableFileSystem = Field(
66
- default_factory=lambda: LocalFileSystem(
67
- basepath=PREFECT_HOME.value() / "storage"
68
- )
69
- )
70
-
71
- @inject_client
72
- async def package(self, flow: Flow, client: "PrefectClient") -> FilePackageManifest:
73
- content = self.serializer.dumps(flow)
74
- key = stable_hash(content)
75
-
76
- await self.filesystem.write_path(key, content)
77
-
78
- filesystem_id = (
79
- self.filesystem._block_document_id
80
- or await self.filesystem._save(is_anonymous=True)
81
- )
82
-
83
- return FilePackageManifest(
84
- **{
85
- **self.base_manifest(flow).dict(),
86
- **{
87
- "serializer": self.serializer,
88
- "filesystem_id": filesystem_id,
89
- "key": key,
90
- },
91
- }
92
- )