prefect-client 3.0.0rc3__py3-none-any.whl → 3.0.0rc5__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 (42) hide show
  1. prefect/__init__.py +0 -3
  2. prefect/client/schemas/schedules.py +9 -2
  3. prefect/client/subscriptions.py +3 -3
  4. prefect/client/types/__init__.py +0 -0
  5. prefect/client/types/flexible_schedule_list.py +11 -0
  6. prefect/concurrency/asyncio.py +14 -4
  7. prefect/concurrency/services.py +29 -22
  8. prefect/concurrency/sync.py +3 -5
  9. prefect/context.py +0 -114
  10. prefect/deployments/__init__.py +1 -1
  11. prefect/deployments/runner.py +11 -93
  12. prefect/deployments/schedules.py +5 -7
  13. prefect/docker/__init__.py +20 -0
  14. prefect/docker/docker_image.py +82 -0
  15. prefect/flow_engine.py +96 -20
  16. prefect/flows.py +36 -95
  17. prefect/futures.py +22 -2
  18. prefect/infrastructure/provisioners/cloud_run.py +2 -2
  19. prefect/infrastructure/provisioners/container_instance.py +2 -2
  20. prefect/infrastructure/provisioners/ecs.py +2 -2
  21. prefect/records/result_store.py +5 -1
  22. prefect/results.py +111 -42
  23. prefect/runner/runner.py +5 -3
  24. prefect/runner/server.py +6 -2
  25. prefect/settings.py +1 -1
  26. prefect/states.py +13 -3
  27. prefect/task_engine.py +7 -6
  28. prefect/task_runs.py +23 -9
  29. prefect/task_worker.py +128 -19
  30. prefect/tasks.py +20 -16
  31. prefect/transactions.py +8 -10
  32. prefect/types/__init__.py +10 -3
  33. prefect/types/entrypoint.py +13 -0
  34. prefect/utilities/collections.py +120 -57
  35. prefect/utilities/dockerutils.py +2 -1
  36. prefect/utilities/urls.py +5 -5
  37. {prefect_client-3.0.0rc3.dist-info → prefect_client-3.0.0rc5.dist-info}/METADATA +2 -2
  38. {prefect_client-3.0.0rc3.dist-info → prefect_client-3.0.0rc5.dist-info}/RECORD +41 -37
  39. prefect/blocks/kubernetes.py +0 -115
  40. {prefect_client-3.0.0rc3.dist-info → prefect_client-3.0.0rc5.dist-info}/LICENSE +0 -0
  41. {prefect_client-3.0.0rc3.dist-info → prefect_client-3.0.0rc5.dist-info}/WHEEL +0 -0
  42. {prefect_client-3.0.0rc3.dist-info → prefect_client-3.0.0rc5.dist-info}/top_level.txt +0 -0
@@ -4,6 +4,7 @@ Utilities for extensions of and operations on Python collections.
4
4
 
5
5
  import io
6
6
  import itertools
7
+ import types
7
8
  import warnings
8
9
  from collections import OrderedDict, defaultdict
9
10
  from collections.abc import Iterator as IteratorABC
@@ -220,25 +221,31 @@ class StopVisiting(BaseException):
220
221
 
221
222
 
222
223
  def visit_collection(
223
- expr,
224
- visit_fn: Union[Callable[[Any, dict], Any], Callable[[Any], Any]],
224
+ expr: Any,
225
+ visit_fn: Union[Callable[[Any, Optional[dict]], Any], Callable[[Any], Any]],
225
226
  return_data: bool = False,
226
227
  max_depth: int = -1,
227
228
  context: Optional[dict] = None,
228
229
  remove_annotations: bool = False,
229
- ):
230
+ _seen: Optional[Set[int]] = None,
231
+ ) -> Any:
230
232
  """
231
- This function visits every element of an arbitrary Python collection. If an element
232
- is a Python collection, it will be visited recursively. If an element is not a
233
- collection, `visit_fn` will be called with the element. The return value of
234
- `visit_fn` can be used to alter the element if `return_data` is set.
233
+ Visits and potentially transforms every element of an arbitrary Python collection.
235
234
 
236
- Note that when using `return_data` a copy of each collection is created to avoid
237
- mutating the original object. This may have significant performance penalties and
238
- should only be used if you intend to transform the collection.
235
+ If an element is a Python collection, it will be visited recursively. If an element
236
+ is not a collection, `visit_fn` will be called with the element. The return value of
237
+ `visit_fn` can be used to alter the element if `return_data` is set to `True`.
238
+
239
+ Note:
240
+ - When `return_data` is `True`, a copy of each collection is created only if
241
+ `visit_fn` modifies an element within that collection. This approach minimizes
242
+ performance penalties by avoiding unnecessary copying.
243
+ - When `return_data` is `False`, no copies are created, and only side effects from
244
+ `visit_fn` are applied. This mode is faster and should be used when no transformation
245
+ of the collection is required, because it never has to copy any data.
239
246
 
240
247
  Supported types:
241
- - List
248
+ - List (including iterators)
242
249
  - Tuple
243
250
  - Set
244
251
  - Dict (note: keys are also visited recursively)
@@ -246,32 +253,41 @@ def visit_collection(
246
253
  - Pydantic model
247
254
  - Prefect annotations
248
255
 
256
+ Note that visit_collection will not consume generators or async generators, as it would prevent
257
+ the caller from iterating over them.
258
+
249
259
  Args:
250
- expr (Any): a Python object or expression
251
- visit_fn (Callable[[Any, Optional[dict]], Awaitable[Any]]): a function that
252
- will be applied to every non-collection element of expr. The function can
253
- accept one or two arguments. If two arguments are accepted, the second
254
- argument will be the context dictionary.
255
- return_data (bool): if `True`, a copy of `expr` containing data modified
256
- by `visit_fn` will be returned. This is slower than `return_data=False`
257
- (the default).
258
- max_depth: Controls the depth of recursive visitation. If set to zero, no
259
- recursion will occur. If set to a positive integer N, visitation will only
260
- descend to N layers deep. If set to any negative integer, no limit will be
260
+ expr (Any): A Python object or expression.
261
+ visit_fn (Callable[[Any, Optional[dict]], Any] or Callable[[Any], Any]): A function
262
+ that will be applied to every non-collection element of `expr`. The function can
263
+ accept one or two arguments. If two arguments are accepted, the second argument
264
+ will be the context dictionary.
265
+ return_data (bool): If `True`, a copy of `expr` containing data modified by `visit_fn`
266
+ will be returned. This is slower than `return_data=False` (the default).
267
+ max_depth (int): Controls the depth of recursive visitation. If set to zero, no
268
+ recursion will occur. If set to a positive integer `N`, visitation will only
269
+ descend to `N` layers deep. If set to any negative integer, no limit will be
261
270
  enforced and recursion will continue until terminal items are reached. By
262
271
  default, recursion is unlimited.
263
- context: An optional dictionary. If passed, the context will be sent to each
264
- call to the `visit_fn`. The context can be mutated by each visitor and will
265
- be available for later visits to expressions at the given depth. Values
272
+ context (Optional[dict]): An optional dictionary. If passed, the context will be sent
273
+ to each call to the `visit_fn`. The context can be mutated by each visitor and
274
+ will be available for later visits to expressions at the given depth. Values
266
275
  will not be available "up" a level from a given expression.
267
-
268
276
  The context will be automatically populated with an 'annotation' key when
269
- visiting collections within a `BaseAnnotation` type. This requires the
270
- caller to pass `context={}` and will not be activated by default.
271
- remove_annotations: If set, annotations will be replaced by their contents. By
277
+ visiting collections within a `BaseAnnotation` type. This requires the caller to
278
+ pass `context={}` and will not be activated by default.
279
+ remove_annotations (bool): If set, annotations will be replaced by their contents. By
272
280
  default, annotations are preserved but their contents are visited.
281
+ _seen (Optional[Set[int]]): A set of object ids that have already been visited. This
282
+ prevents infinite recursion when visiting recursive data structures.
283
+
284
+ Returns:
285
+ Any: The modified collection if `return_data` is `True`, otherwise `None`.
273
286
  """
274
287
 
288
+ if _seen is None:
289
+ _seen = set()
290
+
275
291
  def visit_nested(expr):
276
292
  # Utility for a recursive call, preserving options and updating the depth.
277
293
  return visit_collection(
@@ -282,6 +298,7 @@ def visit_collection(
282
298
  max_depth=max_depth - 1,
283
299
  # Copy the context on nested calls so it does not "propagate up"
284
300
  context=context.copy() if context is not None else None,
301
+ _seen=_seen,
285
302
  )
286
303
 
287
304
  def visit_expression(expr):
@@ -290,7 +307,7 @@ def visit_collection(
290
307
  else:
291
308
  return visit_fn(expr)
292
309
 
293
- # Visit every expression
310
+ # --- 1. Visit every expression
294
311
  try:
295
312
  result = visit_expression(expr)
296
313
  except StopVisiting:
@@ -298,47 +315,92 @@ def visit_collection(
298
315
  result = expr
299
316
 
300
317
  if return_data:
301
- # Only mutate the expression while returning data, otherwise it could be null
318
+ # Only mutate the root expression if the user indicated we're returning data,
319
+ # otherwise the function could return null and we have no collection to check
302
320
  expr = result
303
321
 
304
- # Then, visit every child of the expression recursively
322
+ # --- 2. Visit every child of the expression recursively
305
323
 
306
- # If we have reached the maximum depth, do not perform any recursion
307
- if max_depth == 0:
324
+ # If we have reached the maximum depth or we have already visited this object,
325
+ # return the result if we are returning data, otherwise return None
326
+ if max_depth == 0 or id(expr) in _seen:
308
327
  return result if return_data else None
328
+ else:
329
+ _seen.add(id(expr))
309
330
 
310
331
  # Get the expression type; treat iterators like lists
311
332
  typ = list if isinstance(expr, IteratorABC) and isiterable(expr) else type(expr)
312
333
  typ = cast(type, typ) # mypy treats this as 'object' otherwise and complains
313
334
 
314
335
  # Then visit every item in the expression if it is a collection
315
- if isinstance(expr, Mock):
336
+
337
+ # presume that the result is the original expression.
338
+ # in each of the following cases, we will update the result if we need to.
339
+ result = expr
340
+
341
+ # --- Generators
342
+
343
+ if isinstance(expr, (types.GeneratorType, types.AsyncGeneratorType)):
344
+ # Do not attempt to iterate over generators, as it will exhaust them
345
+ pass
346
+
347
+ # --- Mocks
348
+
349
+ elif isinstance(expr, Mock):
316
350
  # Do not attempt to recurse into mock objects
317
- result = expr
351
+ pass
352
+
353
+ # --- Annotations (unmapped, quote, etc.)
318
354
 
319
355
  elif isinstance(expr, BaseAnnotation):
320
356
  if context is not None:
321
357
  context["annotation"] = expr
322
- value = visit_nested(expr.unwrap())
358
+ unwrapped = expr.unwrap()
359
+ value = visit_nested(unwrapped)
323
360
 
324
- if remove_annotations:
325
- result = value if return_data else None
326
- else:
327
- result = expr.rewrap(value) if return_data else None
361
+ if return_data:
362
+ # if we are removing annotations, return the value
363
+ if remove_annotations:
364
+ result = value
365
+ # if the value was modified, rewrap it
366
+ elif value is not unwrapped:
367
+ result = expr.rewrap(value)
368
+ # otherwise return the expr
369
+
370
+ # --- Sequences
328
371
 
329
372
  elif typ in (list, tuple, set):
330
373
  items = [visit_nested(o) for o in expr]
331
- result = typ(items) if return_data else None
374
+ if return_data:
375
+ modified = any(item is not orig for item, orig in zip(items, expr))
376
+ if modified:
377
+ result = typ(items)
378
+
379
+ # --- Dictionaries
332
380
 
333
381
  elif typ in (dict, OrderedDict):
334
382
  assert isinstance(expr, (dict, OrderedDict)) # typecheck assertion
335
383
  items = [(visit_nested(k), visit_nested(v)) for k, v in expr.items()]
336
- result = typ(items) if return_data else None
384
+ if return_data:
385
+ modified = any(
386
+ k1 is not k2 or v1 is not v2
387
+ for (k1, v1), (k2, v2) in zip(items, expr.items())
388
+ )
389
+ if modified:
390
+ result = typ(items)
391
+
392
+ # --- Dataclasses
337
393
 
338
394
  elif is_dataclass(expr) and not isinstance(expr, type):
339
395
  values = [visit_nested(getattr(expr, f.name)) for f in fields(expr)]
340
- items = {field.name: value for field, value in zip(fields(expr), values)}
341
- result = typ(**items) if return_data else None
396
+ if return_data:
397
+ modified = any(
398
+ getattr(expr, f.name) is not v for f, v in zip(fields(expr), values)
399
+ )
400
+ if modified:
401
+ result = typ(**{f.name: v for f, v in zip(fields(expr), values)})
402
+
403
+ # --- Pydantic models
342
404
 
343
405
  elif isinstance(expr, pydantic.BaseModel):
344
406
  typ = cast(Type[pydantic.BaseModel], typ)
@@ -355,20 +417,21 @@ def visit_collection(
355
417
  }
356
418
 
357
419
  if return_data:
358
- # Use construct to avoid validation and handle immutability
359
- model_instance = typ.model_construct(
360
- _fields_set=expr.model_fields_set, **updated_data
420
+ modified = any(
421
+ getattr(expr, field) is not updated_data[field]
422
+ for field in model_fields
361
423
  )
362
- for private_attr in expr.__private_attributes__:
363
- setattr(model_instance, private_attr, getattr(expr, private_attr))
364
- result = model_instance
365
- else:
366
- result = None
424
+ if modified:
425
+ # Use construct to avoid validation and handle immutability
426
+ model_instance = typ.model_construct(
427
+ _fields_set=expr.model_fields_set, **updated_data
428
+ )
429
+ for private_attr in expr.__private_attributes__:
430
+ setattr(model_instance, private_attr, getattr(expr, private_attr))
431
+ result = model_instance
367
432
 
368
- else:
369
- result = result if return_data else None
370
-
371
- return result
433
+ if return_data:
434
+ return result
372
435
 
373
436
 
374
437
  def remove_nested_keys(keys_to_remove: List[Hashable], obj):
@@ -9,6 +9,7 @@ from tempfile import TemporaryDirectory
9
9
  from types import TracebackType
10
10
  from typing import (
11
11
  TYPE_CHECKING,
12
+ Any,
12
13
  Generator,
13
14
  Iterable,
14
15
  List,
@@ -142,7 +143,7 @@ def build_image(
142
143
  pull: bool = False,
143
144
  platform: Optional[str] = None,
144
145
  stream_progress_to: Optional[TextIO] = None,
145
- **kwargs,
146
+ **kwargs: Any,
146
147
  ) -> str:
147
148
  """Builds a Docker image, returning the image ID
148
149
 
prefect/utilities/urls.py CHANGED
@@ -117,7 +117,7 @@ def url_for(
117
117
  if obj.id.startswith("prefect."):
118
118
  name = obj.id.split(".")[1]
119
119
  else:
120
- logger.warning(f"No URL known for resource with ID: {obj.id}")
120
+ logger.debug(f"No URL known for resource with ID: {obj.id}")
121
121
  return None
122
122
  elif isinstance(obj, str):
123
123
  name = obj
@@ -133,10 +133,10 @@ def url_for(
133
133
  raise ValueError(f"Invalid URL type: {url_type}. Use 'ui' or 'api'.")
134
134
 
135
135
  if url_type == "ui" and name not in UI_URL_FORMATS:
136
- logger.error("No UI URL known for this object: %s", name)
136
+ logger.debug("No UI URL known for this object: %s", name)
137
137
  return None
138
138
  elif url_type == "api" and name not in API_URL_FORMATS:
139
- logger.error("No API URL known for this object: %s", name)
139
+ logger.debug("No API URL known for this object: %s", name)
140
140
  return None
141
141
 
142
142
  if isinstance(obj, str) and not obj_id:
@@ -152,7 +152,7 @@ def url_for(
152
152
  base_url = base_url or default_base_url
153
153
 
154
154
  if not base_url:
155
- logger.warning(
155
+ logger.debug(
156
156
  f"No URL found for the Prefect {'UI' if url_type == 'ui' else 'API'}, "
157
157
  f"and no default base path provided."
158
158
  )
@@ -174,7 +174,7 @@ def url_for(
174
174
  else:
175
175
  obj_id = getattr(obj, "id", None)
176
176
  if not obj_id:
177
- logger.error(
177
+ logger.debug(
178
178
  "An ID is required to build a URL, but object did not have one: %s", obj
179
179
  )
180
180
  return ""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: prefect-client
3
- Version: 3.0.0rc3
3
+ Version: 3.0.0rc5
4
4
  Summary: Workflow orchestration and management.
5
5
  Home-page: https://www.prefect.io
6
6
  Author: Prefect Technologies, Inc.
@@ -46,7 +46,7 @@ Requires-Dist: pathspec >=0.8.0
46
46
  Requires-Dist: pendulum <4,>=3.0.0
47
47
  Requires-Dist: pydantic <3.0.0,>=2.7
48
48
  Requires-Dist: pydantic-core <3.0.0,>=2.12.0
49
- Requires-Dist: pydantic-extra-types !=2.8.1,<3.0.0,>2.7
49
+ Requires-Dist: pydantic-extra-types <3.0.0,>=2.8.2
50
50
  Requires-Dist: pydantic-settings
51
51
  Requires-Dist: python-dateutil <3.0.0,>=2.8.2
52
52
  Requires-Dist: python-slugify <9.0,>=5.0
@@ -1,30 +1,30 @@
1
1
  prefect/.prefectignore,sha256=awSprvKT0vI8a64mEOLrMxhxqcO-b0ERQeYpA2rNKVQ,390
2
- prefect/__init__.py,sha256=7U1KgTkcvbIuof0yse4_i181D98rih8y_SkZhPQStyA,2952
2
+ prefect/__init__.py,sha256=YmPor6iCXeKOr8jfH08qD9CBiRsEY6pXs4mRSQRo6ro,2873
3
3
  prefect/_version.py,sha256=I9JsXwt7BjAAbMEZgtmE3a6dJ2jqV-wqWto9D6msb3k,24597
4
4
  prefect/artifacts.py,sha256=G-jCyce3XGtTyQpCk_s3L7e-TWFyJY8Dcnk_i4_CsY4,12647
5
5
  prefect/automations.py,sha256=NlQ62GPJzy-gnWQqX7c6CQJKw7p60WLGDAFcy82vtg4,5613
6
- prefect/context.py,sha256=1dGUGcVXbx6rd04cwtz7Oz1qVPCMlIrAkF-Xo5GtcVY,23196
6
+ prefect/context.py,sha256=OEmbC61D3l0E50HIaMlVNNJShhYC6I1-4TQhpP321tw,19480
7
7
  prefect/engine.py,sha256=asH7iMb1IfEOOIVIxM3ZalfvCe9PUp7f9ceKyT6isa8,2019
8
8
  prefect/exceptions.py,sha256=kRiEX6qpT9errs0SuYJDYG7ioMNddTvqK7gT8RVFajk,11076
9
9
  prefect/filesystems.py,sha256=HrPoehZKpuVxzWDXaTiuJqgVCgxlQ4lyTEZKSYKiZUc,17169
10
- prefect/flow_engine.py,sha256=4AekqZxCSrro_PL40jxdVELHby5YJ3QOaYbSFO0jjlI,23164
10
+ prefect/flow_engine.py,sha256=3JM3LpgqCGLUsTbrh5-CL3IFnHSHRWHbqV9xMEC3nyM,26149
11
11
  prefect/flow_runs.py,sha256=7mHGjb3-6MfR4XKQjy9sJPS9dS0yTxVO6MYQ8YlGjGw,16071
12
- prefect/flows.py,sha256=XT-RPAsY4twN5hQOoM_8AsB5zfI_pLVuq7KL46hPr1A,81075
13
- prefect/futures.py,sha256=-ElpB4lcjJxMS1Jl-iHnUEofpgoSs2xCtMgR3_F4bTE,9139
12
+ prefect/flows.py,sha256=fODMwvsgkNkIy1eWCqh5zHLDpLaL1LXCN17Ygpg0MdU,79204
13
+ prefect/futures.py,sha256=mI3WuaH3k0LkqwPbM6V7WbG0ssT-NjpX1wROS7vSKE0,9882
14
14
  prefect/manifests.py,sha256=477XcmfdC_yE81wT6zIAKnEUEJ0lH9ZLfOVSgX2FohE,676
15
15
  prefect/plugins.py,sha256=-IqPJvQGoMZBioHCF0s1IDNHYA7OxIRaUlkaGM2CgLY,4164
16
16
  prefect/profiles.toml,sha256=Fs8hD_BdWHZgAijgk8pK_Zx-Pm-YFixqDIfEP6fM-qU,38
17
17
  prefect/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- prefect/results.py,sha256=oFJkqoZKXTvTdfDCY9Lz1pnCiTK_fZ74BwzUshf_pBg,25161
18
+ prefect/results.py,sha256=qG-5mAlZTRV7GneuQVS7GpHHt3QXcZbwLwn03fHAi4M,27326
19
19
  prefect/serializers.py,sha256=8ON--RmaLX3Td3Rpd1lshGcqWyjlCFkmO3sblxsdT_c,8699
20
- prefect/settings.py,sha256=7SQtJWmHdJl5iA0EY-Q_FC3WZ9fCTwgnFT6N34p4STA,74607
21
- prefect/states.py,sha256=GDpFM6UUMB5MkCDWyqo8F9ELnkskr1BTg4YdU_bnv7Q,20395
22
- prefect/task_engine.py,sha256=LnHRiEZKjZjsSodnO2996OerVj-V-ozV0mAm3yDeF34,32179
20
+ prefect/settings.py,sha256=JkCgcFO7Zw0Kv_azK9XLabx08ypVgL76E6r8nD-HZLM,74598
21
+ prefect/states.py,sha256=JdN01UMYFelFybPoAEKbiPJNuPaj6pksLJ3o0_oNz5Q,20690
22
+ prefect/task_engine.py,sha256=dzMID0AhbRlJnrm7U-PjJ8DxvW2J0j2jStOvDRuZDJs,32317
23
23
  prefect/task_runners.py,sha256=TQHyQATPkZE6BNVJ_JQBNmiL1kdgZRjY_Fjs3-N1UiE,11869
24
- prefect/task_runs.py,sha256=oeH1JKeg214UMpdEUoX1SOq1C2raGVOW-VwZLltzkK8,7175
25
- prefect/task_worker.py,sha256=Jw64k3Nigye3FgHvG4DM3z808YaTaLBneO4IB2wbBHc,13074
26
- prefect/tasks.py,sha256=fntgTe9X_XX1-i7X3ch45QVyMz2zOVV1e4oz5sSRCg8,60189
27
- prefect/transactions.py,sha256=gGf7La0AyhMZJoWIlmVxoHkFpcWb6roGrVf2DGlZfOE,9443
24
+ prefect/task_runs.py,sha256=eDWYH5H1K4SyduhKmn3GzO6vM3fZSwOZxAb8KhkMGsk,7798
25
+ prefect/task_worker.py,sha256=iawQZn4hNcrXR-CHtM4jzhlnotqeNHiRuHc-eumJ9Oc,16788
26
+ prefect/tasks.py,sha256=-j9ZCxvfvgHkyUsaRuj9EhEWmfO4NLN76Pg2_yGCaL0,60243
27
+ prefect/transactions.py,sha256=XhEXdhid1457m5V7VTz1U8JCek6U6jSFD7EffGhCLag,9149
28
28
  prefect/variables.py,sha256=-t5LVY0N-K4f0fa6YwruVVQqwnU3fGWBMYXXE32XPkA,4821
29
29
  prefect/_internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
30
  prefect/_internal/_logging.py,sha256=HvNHY-8P469o5u4LYEDBTem69XZEt1QUeUaLToijpak,810
@@ -59,7 +59,6 @@ prefect/blocks/__init__.py,sha256=BUfh6gIwA6HEjRyVCAiv0he3M1zfM-oY-JrlBfeWeY8,18
59
59
  prefect/blocks/abstract.py,sha256=YLzCaf3yXv6wFCF5ZqCIHJNwH7fME1rLxC-SijARHzk,16319
60
60
  prefect/blocks/core.py,sha256=cgkPF1rpNl_4Asekh2RJ0RiMmjqtuQEbp52BDXgxdbY,46657
61
61
  prefect/blocks/fields.py,sha256=1m507VVmkpOnMF_7N-qboRjtw4_ceIuDneX3jZ3Jm54,63
62
- prefect/blocks/kubernetes.py,sha256=1AHzcI2hPeu5zOEKLC4FBjjv8VdZ8ianuv6oVEh4ou8,4016
63
62
  prefect/blocks/notifications.py,sha256=QV2ndeiERBbL9vNW2zR1LzH86llDY1sJVh2DN0sh1eo,28198
64
63
  prefect/blocks/redis.py,sha256=GUKYyx2QLtyNvgf5FT_dJxbgQcOzWCja3I23J1-AXhM,5629
65
64
  prefect/blocks/system.py,sha256=tkONKzDlaQgR6NtWXON0ZQm7nGuFKt0_Du3sj8ubs-M,3605
@@ -70,30 +69,34 @@ prefect/client/cloud.py,sha256=5T84QP9IRa_cqL7rmY3lR1wxFW6C41PajFZgelurhK0,4124
70
69
  prefect/client/collections.py,sha256=I9EgbTg4Fn57gn8vwP_WdDmgnATbx9gfkm2jjhCORjw,1037
71
70
  prefect/client/constants.py,sha256=Z_GG8KF70vbbXxpJuqW5pLnwzujTVeHbcYYRikNmGH0,29
72
71
  prefect/client/orchestration.py,sha256=0wK6LEWgKgsrgy6kF654EiweorId8nmX5nzXp-BtSgU,142641
73
- prefect/client/subscriptions.py,sha256=LGMxFO20fp4gRgGTIq62HZemTgVNHHSHzbpPn6syw0U,3374
72
+ prefect/client/subscriptions.py,sha256=J9uK9NGHO4VX4Y3NGgBJ4pIG_0cf-dJWPhF3f3PGYL4,3388
74
73
  prefect/client/utilities.py,sha256=Ni1DsFDhnvxpXWerlvZpK8tCg-uZ8UyZwOmDTKEb1DI,3269
75
74
  prefect/client/schemas/__init__.py,sha256=KlyqFV-hMulMkNstBn_0ijoHoIwJZaBj6B1r07UmgvE,607
76
75
  prefect/client/schemas/actions.py,sha256=t-JJCikwa_ZrTPu7VJDwkLQ2fgNQuYHUwAi_3PHpwoU,28113
77
76
  prefect/client/schemas/filters.py,sha256=HyIYZQowhkHa_D6syj83zUp5uFEzA8UADLaS9mt1MTo,35305
78
77
  prefect/client/schemas/objects.py,sha256=htwlQ1CYcouNPWENVLyWyWSGRfjNXRIxvuYG_nKcnlE,53308
79
78
  prefect/client/schemas/responses.py,sha256=YnofjvPxaDE0kPw7SLfK5TuZSJ0IlqP2G17rQgz_buk,15135
80
- prefect/client/schemas/schedules.py,sha256=EIvVQN01ZnLf6Yu-3_Ar1iHybDwJ6C767AAnqMhVxWo,12846
79
+ prefect/client/schemas/schedules.py,sha256=8rpqjOYtknu2-1n5_WD4cOplgu93P3mCyX86B22LfL4,13070
81
80
  prefect/client/schemas/sorting.py,sha256=EIQ6FUjUWMwk6fn6ckVLQLXOP-GI5kce7ftjUkDFWV0,2490
81
+ prefect/client/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
+ prefect/client/types/flexible_schedule_list.py,sha256=F1VFAXGLM89dJRBLnVsxwAMGLmrRF2i81FirEMpbB5s,368
82
83
  prefect/concurrency/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
83
- prefect/concurrency/asyncio.py,sha256=P9e69XYik9QBSlUYyq1OcyqyUJaFjvW8jm6nfMkZ7uA,4304
84
+ prefect/concurrency/asyncio.py,sha256=sn5Wm6pOnU0bnfJiwltwWBcouj-rhGg27Zkzw7zfVuA,4684
84
85
  prefect/concurrency/events.py,sha256=rQLSBwcYCzvdKTXr7bLjgMIklllObxB33MAL6dylXAM,1802
85
- prefect/concurrency/services.py,sha256=JP74IUjdoDoljy-BdZQTa1IOEuSZZxMgsMyr7KJAYS0,2598
86
- prefect/concurrency/sync.py,sha256=gXyiiA0bul7jjpHWPm6su8pFdBiMOekhu9FHnjiPWBQ,3339
87
- prefect/deployments/__init__.py,sha256=9MnrUjil46PHWq-ni-3BLmgyJWAzlzORF5XZA-KdhYc,432
86
+ prefect/concurrency/services.py,sha256=pxqfjA5DpzcpbU-E2TQT1Rq8BhOGf3Sfz5eTFE8sYu8,2981
87
+ prefect/concurrency/sync.py,sha256=QtnPRfVX9GqVyuZOt6W9yJuT9G-PlCSVnxlZKFTjuKY,3271
88
+ prefect/deployments/__init__.py,sha256=yAtuBvqhQNhlJHjPW6yQyjkPFCgew3t26NAKO2RnQyk,428
88
89
  prefect/deployments/base.py,sha256=j2VUHkghXCqbfYJD8Joeh12Ejh4KCzr2DgVPRpDpbLw,16600
89
90
  prefect/deployments/deployments.py,sha256=EvC9qBdvJRc8CHJqRjFTqtzx75SE8bpZOl5C-2eULyA,109
90
91
  prefect/deployments/flow_runs.py,sha256=eatcBD7pg-aaEqs9JxQQcKN_flf614O4gAvedAlRyNo,6803
91
- prefect/deployments/runner.py,sha256=5f3pFGxw_DOA9k169KFIzILTZ_TkKIWI9DLhl1iK1Ck,44716
92
- prefect/deployments/schedules.py,sha256=c8ONC9t_buAWVxfcWAQEGhuIkU5rAjetuvU87PLJx48,2031
92
+ prefect/deployments/runner.py,sha256=wVz2Ltis_tOpWLvLzPuOBJBIsdWqs8aXY2oCOuwhssc,41763
93
+ prefect/deployments/schedules.py,sha256=l1xOHBmJJ-VZFPTX4RWScJ802P-iE81Vzp4EniQ65k4,2004
93
94
  prefect/deployments/steps/__init__.py,sha256=Dlz9VqMRyG1Gal8dj8vfGpPr0LyQhZdvcciozkK8WoY,206
94
95
  prefect/deployments/steps/core.py,sha256=yKBVi8pi_7fzdng28kUD8vcSl5aED5yFnu9KxCdquKA,6627
95
96
  prefect/deployments/steps/pull.py,sha256=ylp3fd72hEfmY67LQs7sMwdcK6KKobsTZOeay-YUl8Q,7125
96
97
  prefect/deployments/steps/utility.py,sha256=s5mMBmHVCS1ZRBRUCunwPueU_7Dii_GK6CqCoznwUCc,8134
98
+ prefect/docker/__init__.py,sha256=jumlacz2HY9l1ee0L9_kE0PFi9NO3l3pWINm9T5N9hs,524
99
+ prefect/docker/docker_image.py,sha256=Y84_ooCYA9NGl6FElJul9-FaW3teT-eia2SiNtZ1LG8,2999
97
100
  prefect/events/__init__.py,sha256=GtKl2bE--pJduTxelH2xy7SadlLJmmis8WR1EYixhuA,2094
98
101
  prefect/events/actions.py,sha256=4kBV2NwFlC6oXVeMp9Qb2HMNqv1IZ7FcOqeXz1zlRf0,8983
99
102
  prefect/events/clients.py,sha256=nDP8AQCoPNOfRPgS9QbEvdpx0wKyE4_4gwxQEtsnuUA,19860
@@ -110,9 +113,9 @@ prefect/events/schemas/events.py,sha256=RqosMukGfHvLPnYDcyxkm6VuifCeH5-aQ4POdMPm
110
113
  prefect/events/schemas/labelling.py,sha256=bU-XYaHXhI2MEBIHngth96R9D02m8HHb85KNcHZ_1Gc,3073
111
114
  prefect/infrastructure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
112
115
  prefect/infrastructure/provisioners/__init__.py,sha256=wn240gHrQbien2g_g2A8Ujb2iFyjmDgMHLQ7tgQngf4,1706
113
- prefect/infrastructure/provisioners/cloud_run.py,sha256=A2q9LhYQbbOZd-W5VG_Uy8KbEkttXu7Fj2DiQrOUhL0,17758
114
- prefect/infrastructure/provisioners/container_instance.py,sha256=-PNd-A088SnEDhj3m7foSE9iBsmVqoHUEmtT26XtJt8,41294
115
- prefect/infrastructure/provisioners/ecs.py,sha256=PVH3ByIqm0aoJ39nDpW1LsSsi7rcERFBdqO16KxIUic,47736
116
+ prefect/infrastructure/provisioners/cloud_run.py,sha256=K6_8AO_fZRfuI0hGx_EwvlRkiNPcmR5yD9P8B-QSjuc,17745
117
+ prefect/infrastructure/provisioners/container_instance.py,sha256=ZaiaAOywMjbhZI6emzqsDQh-xBePajzjjMT_JY8lwNA,41281
118
+ prefect/infrastructure/provisioners/ecs.py,sha256=8cqabILtoy7t3ISuX8VbFCcG3IOFr3ODWWLi3ls2NyU,47723
116
119
  prefect/infrastructure/provisioners/modal.py,sha256=4-VanBPqWlAj_5ckpXT7NonbqP0YwznTXFa4P8cthIs,9080
117
120
  prefect/input/__init__.py,sha256=Ue2h-YhYP71nEtsVJaslqMwO6C0ckjhjTYwwEgp-E3g,701
118
121
  prefect/input/actions.py,sha256=IGdWjVcesnRjLmPCzB4ZM7FkRWXDKCku6yhE-7p0vKk,3777
@@ -127,11 +130,11 @@ prefect/logging/loggers.py,sha256=qWM-5IxN3U5MlK7srfALOC9sCpGqt20Vu9WSxpU2zIs,11
127
130
  prefect/logging/logging.yml,sha256=UkEewf0c3_dURI2uCU4RrxkhI5Devoa1s93fl7hilcg,3160
128
131
  prefect/records/__init__.py,sha256=7q-lwyevfVgb5S7K9frzawmiJmpZ5ET0m5yXIHBYcVA,31
129
132
  prefect/records/cache_policies.py,sha256=2R6tQioujG2qr5rQgg7kPK-SLMM1lUHplEKcOfJbrh0,4761
130
- prefect/records/result_store.py,sha256=pyhMr5OKto1NhWuVrEVBd6-Z4Dc0N0xdYApwDAQL8IM,1557
133
+ prefect/records/result_store.py,sha256=6Yh9zqqXMWjn0qWSfcjQBSfXCM7jVg9pve5TVsOodDc,1734
131
134
  prefect/records/store.py,sha256=eQM1p2vZDshXZYg6SkJwL-DP3kUehL_Zgs8xa2-0DZs,224
132
135
  prefect/runner/__init__.py,sha256=7U-vAOXFkzMfRz1q8Uv6Otsvc0OrPYLLP44srwkJ_8s,89
133
- prefect/runner/runner.py,sha256=7WhYpDXQwtO4XyfLKNk27QuFXnrLKD4rJPiSfUab6OI,45098
134
- prefect/runner/server.py,sha256=UN44qjP1SjuA5OCp5PoPhRAfKXMVGEm9E2b-bWB-suk,10519
136
+ prefect/runner/runner.py,sha256=aR9Figoyvn0PAKv8zussaT7sJP9zM-SAmrcYZN19ZB8,45152
137
+ prefect/runner/server.py,sha256=pXyNGDw2aBYCXRr3zyFCaflxUaQOG4M07zxwXiFngoQ,10676
135
138
  prefect/runner/storage.py,sha256=nuzkEjmAZYAjCEpXhuuZSGJAqBARICIBmDQNqDgI4yk,22316
136
139
  prefect/runner/submit.py,sha256=EpgYNR-tAub0VFVTIkijp8qwHcS1iojLAZN5NM0X39s,8552
137
140
  prefect/runner/utils.py,sha256=wVgVa7p5uUL7tfYfDOVuq6QIGf-I8U9dfAjYBmYf6n4,3286
@@ -141,16 +144,17 @@ prefect/runtime/flow_run.py,sha256=Fxbyc4r3kPj2m3AIJT8gud2PB5w9aKTwkI-g4dysikE,8
141
144
  prefect/runtime/task_run.py,sha256=B6v_nZiHy9nKZfnKFQF7izZjAjaiZOT0j80m-VcLxmY,3403
142
145
  prefect/server/api/collections_data/views/aggregate-worker-metadata.json,sha256=gqrwGyylzBEzlFSPOJcMuUwdoK_zojpU0SZaBDgK5FE,79748
143
146
  prefect/server/api/static/prefect-logo-mark-gradient.png,sha256=ylRjJkI_JHCw8VbQasNnXQHwZW-sH-IQiUGSD3aWP1E,73430
144
- prefect/types/__init__.py,sha256=SsjNhBX_O-z8gqtCm-ettrg481gqz1qVZUoxAY9fhrM,2169
147
+ prefect/types/__init__.py,sha256=SAHJDtWEGidTKXQACJ38nj6fq8r57Gj0Pwo4Gy7pVWs,2234
148
+ prefect/types/entrypoint.py,sha256=2FF03-wLPgtnqR_bKJDB2BsXXINPdu8ptY9ZYEZnXg8,328
145
149
  prefect/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
146
150
  prefect/utilities/annotations.py,sha256=bXB43j5Zsq5gaBcJe9qnszBlnNwCTwqSTgcu2OkkRLo,2776
147
151
  prefect/utilities/asyncutils.py,sha256=GRDiA3S9vGRpM3aKSq6iZnNP9XNBcfUg0NBwbjUFeAw,19200
148
152
  prefect/utilities/callables.py,sha256=rkPPzwiVFRoVszSUq612s9S0v3nxcMC-rIwfXoJTn0E,24915
149
- prefect/utilities/collections.py,sha256=9vUZA8j_NAOcsRZ45UWGYpO1EuUErcpcPTyZap5q28I,14883
153
+ prefect/utilities/collections.py,sha256=2W7cgdB_c_LGMbHPmFSKJbwue_Ai8h5CukSmFoZ8svE,17248
150
154
  prefect/utilities/compat.py,sha256=mNQZDnzyKaOqy-OV-DnmH_dc7CNF5nQgW_EsA4xMr7g,906
151
155
  prefect/utilities/context.py,sha256=BThuUW94-IYgFYTeMIM9KMo8ShT3oiI7w5ajZHzU1j0,1377
152
156
  prefect/utilities/dispatch.py,sha256=c8G-gBo7hZlyoD7my9nO50Rzy8Retk-np5WGq9_E2AM,5856
153
- prefect/utilities/dockerutils.py,sha256=b3_kzba6kXRtzQNcgyigrY4N4LuH_jr6J_L2kOD9lHU,20310
157
+ prefect/utilities/dockerutils.py,sha256=kRozGQ7JO6Uxl-ljWtDryzxhf96rHL78aHYDh255Em4,20324
154
158
  prefect/utilities/engine.py,sha256=E5WSLg9XsvkEN56M8Q5Wl4k0INUpaqmvdToQPFjYWNo,30160
155
159
  prefect/utilities/filesystem.py,sha256=frAyy6qOeYa7c-jVbEUGZQEe6J1yF8I_SvUepPd59gI,4415
156
160
  prefect/utilities/hashing.py,sha256=EOwZLmoIZImuSTxAvVqInabxJ-4RpEfYeg9e2EDQF8o,1752
@@ -165,7 +169,7 @@ prefect/utilities/slugify.py,sha256=57Vb14t13F3zm1P65KAu8nVeAz0iJCd1Qc5eMG-R5y8,
165
169
  prefect/utilities/templating.py,sha256=nAiOGMMHGbIDFkGYy-g-dzcbY311WfycdgAhsM3cLpY,13298
166
170
  prefect/utilities/text.py,sha256=eXGIsCcZ7h_6hy8T5GDQjL8GiKyktoOqavYub0QjgO4,445
167
171
  prefect/utilities/timeout.py,sha256=nxmuPxROIT-i8gPffpARuxnxu58H0vkmbjTVIgef0_0,805
168
- prefect/utilities/urls.py,sha256=Qw6IlI7CKAlA3t2Ii-b09fXRJTaHuqLFNM2KVhI_yQI,6400
172
+ prefect/utilities/urls.py,sha256=GuiV3mk-XfzXx139ySyNQNbNaolA3T-hUZvW3T_PhXU,6396
169
173
  prefect/utilities/visualization.py,sha256=Lum4IvLQ0nHsdLt6GGzS3Wwo-828u1rmOKc5mmWu994,6502
170
174
  prefect/utilities/schema_tools/__init__.py,sha256=KsFsTEHQqgp89TkDpjggkgBBywoHQPxbx-m6YQhiNEI,322
171
175
  prefect/utilities/schema_tools/hydration.py,sha256=Nitnmr35Mcn5z9NXIvh9DuZW5nCZxpjyMc9RFawMsgs,8376
@@ -175,8 +179,8 @@ prefect/workers/base.py,sha256=62E0Q41pPr3eQdSBSUBfiR4WYx01OfuqUp5INRqHGgo,46942
175
179
  prefect/workers/process.py,sha256=vylkSSswaSCew-V65YW0HcxIxyKI-uqWkbSKpkkLamQ,9372
176
180
  prefect/workers/server.py,sha256=EfPiMxI7TVgkqpHkdPwSaYG-ydi99sG7jwXhkAcACbI,1519
177
181
  prefect/workers/utilities.py,sha256=VfPfAlGtTuDj0-Kb8WlMgAuOfgXCdrGAnKMapPSBrwc,2483
178
- prefect_client-3.0.0rc3.dist-info/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
179
- prefect_client-3.0.0rc3.dist-info/METADATA,sha256=S_JWxgOm7Nj3tN3KKouc_NzXeAMLWBZMyYW6BqZwfFo,7397
180
- prefect_client-3.0.0rc3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
181
- prefect_client-3.0.0rc3.dist-info/top_level.txt,sha256=MJZYJgFdbRc2woQCeB4vM6T33tr01TmkEhRcns6H_H4,8
182
- prefect_client-3.0.0rc3.dist-info/RECORD,,
182
+ prefect_client-3.0.0rc5.dist-info/LICENSE,sha256=MCxsn8osAkzfxKC4CC_dLcUkU8DZLkyihZ8mGs3Ah3Q,11357
183
+ prefect_client-3.0.0rc5.dist-info/METADATA,sha256=fGHLD4XaLt3FzjMoZxnEJcK-rByrMfxN-Bpu27Y66Ao,7392
184
+ prefect_client-3.0.0rc5.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
185
+ prefect_client-3.0.0rc5.dist-info/top_level.txt,sha256=MJZYJgFdbRc2woQCeB4vM6T33tr01TmkEhRcns6H_H4,8
186
+ prefect_client-3.0.0rc5.dist-info/RECORD,,
@@ -1,115 +0,0 @@
1
- from pathlib import Path
2
- from typing import TYPE_CHECKING, Dict, Optional, Type
3
-
4
- import yaml
5
- from pydantic import Field, field_validator
6
- from typing_extensions import Self
7
-
8
- from prefect._internal.compatibility.deprecated import deprecated_class
9
- from prefect._internal.schemas.validators import validate_yaml
10
- from prefect.blocks.core import Block
11
- from prefect.utilities.collections import listrepr
12
- from prefect.utilities.importtools import lazy_import
13
-
14
- if TYPE_CHECKING:
15
- import kubernetes
16
- from kubernetes.client.api_client import ApiClient
17
- else:
18
- kubernetes = lazy_import("kubernetes")
19
-
20
-
21
- @deprecated_class(
22
- start_date="Mar 2024",
23
- help="Use the KubernetesClusterConfig block from prefect-kubernetes instead.",
24
- )
25
- class KubernetesClusterConfig(Block):
26
- """
27
- Stores configuration for interaction with Kubernetes clusters.
28
-
29
- See `from_file` for creation.
30
-
31
- Attributes:
32
- config: The entire loaded YAML contents of a kubectl config file
33
- context_name: The name of the kubectl context to use
34
-
35
- Example:
36
- Load a saved Kubernetes cluster config:
37
- ```python
38
- from prefect.blocks.kubernetes import KubernetesClusterConfig
39
-
40
- cluster_config_block = KubernetesClusterConfig.load("BLOCK_NAME")
41
- ```
42
- """
43
-
44
- _block_type_name = "Kubernetes Cluster Config"
45
- _logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/2d0b896006ad463b49c28aaac14f31e00e32cfab-250x250.png"
46
- _documentation_url = "https://docs.prefect.io/api-ref/prefect/blocks/kubernetes/#prefect.blocks.kubernetes.KubernetesClusterConfig"
47
-
48
- config: Dict = Field(
49
- default=..., description="The entire contents of a kubectl config file."
50
- )
51
- context_name: str = Field(
52
- default=..., description="The name of the kubectl context to use."
53
- )
54
-
55
- @field_validator("config", mode="before")
56
- @classmethod
57
- def parse_yaml_config(cls, value):
58
- return validate_yaml(value)
59
-
60
- @classmethod
61
- def from_file(
62
- cls: Type[Self], path: Optional[Path] = None, context_name: Optional[str] = None
63
- ) -> Self:
64
- """
65
- Create a cluster config from the a Kubernetes config file.
66
-
67
- By default, the current context in the default Kubernetes config file will be
68
- used.
69
-
70
- An alternative file or context may be specified.
71
-
72
- The entire config file will be loaded and stored.
73
- """
74
- kube_config = kubernetes.config.kube_config
75
-
76
- path = Path(path or kube_config.KUBE_CONFIG_DEFAULT_LOCATION)
77
- path = path.expanduser().resolve()
78
-
79
- # Determine the context
80
- existing_contexts, current_context = kube_config.list_kube_config_contexts(
81
- config_file=str(path)
82
- )
83
- context_names = {ctx["name"] for ctx in existing_contexts}
84
- if context_name:
85
- if context_name not in context_names:
86
- raise ValueError(
87
- f"Context {context_name!r} not found. "
88
- f"Specify one of: {listrepr(context_names, sep=', ')}."
89
- )
90
- else:
91
- context_name = current_context["name"]
92
-
93
- # Load the entire config file
94
- config_file_contents = path.read_text()
95
- config_dict = yaml.safe_load(config_file_contents)
96
-
97
- return cls(config=config_dict, context_name=context_name)
98
-
99
- def get_api_client(self) -> "ApiClient":
100
- """
101
- Returns a Kubernetes API client for this cluster config.
102
- """
103
- return kubernetes.config.kube_config.new_client_from_config_dict(
104
- config_dict=self.config, context=self.context_name
105
- )
106
-
107
- def configure_client(self) -> None:
108
- """
109
- Activates this cluster configuration by loading the configuration into the
110
- Kubernetes Python client. After calling this, Kubernetes API clients can use
111
- this config's context.
112
- """
113
- kubernetes.config.kube_config.load_kube_config_from_dict(
114
- config_dict=self.config, context=self.context_name
115
- )