prefect-client 3.0.0rc18__py3-none-any.whl → 3.0.0rc20__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 (55) hide show
  1. prefect/__init__.py +0 -3
  2. prefect/_internal/concurrency/services.py +14 -0
  3. prefect/_internal/schemas/bases.py +1 -0
  4. prefect/blocks/core.py +41 -30
  5. prefect/blocks/system.py +48 -12
  6. prefect/client/cloud.py +56 -7
  7. prefect/client/collections.py +1 -1
  8. prefect/client/orchestration.py +111 -8
  9. prefect/client/schemas/objects.py +40 -2
  10. prefect/concurrency/asyncio.py +8 -2
  11. prefect/concurrency/services.py +16 -6
  12. prefect/concurrency/sync.py +4 -1
  13. prefect/concurrency/v1/__init__.py +0 -0
  14. prefect/concurrency/v1/asyncio.py +143 -0
  15. prefect/concurrency/v1/context.py +27 -0
  16. prefect/concurrency/v1/events.py +61 -0
  17. prefect/concurrency/v1/services.py +116 -0
  18. prefect/concurrency/v1/sync.py +92 -0
  19. prefect/context.py +2 -2
  20. prefect/deployments/flow_runs.py +0 -7
  21. prefect/deployments/runner.py +11 -0
  22. prefect/events/clients.py +41 -0
  23. prefect/events/related.py +72 -73
  24. prefect/events/utilities.py +2 -0
  25. prefect/events/worker.py +12 -3
  26. prefect/exceptions.py +6 -0
  27. prefect/flow_engine.py +5 -0
  28. prefect/flows.py +9 -2
  29. prefect/logging/handlers.py +4 -1
  30. prefect/main.py +8 -6
  31. prefect/records/base.py +74 -18
  32. prefect/records/filesystem.py +207 -0
  33. prefect/records/memory.py +16 -3
  34. prefect/records/result_store.py +19 -14
  35. prefect/results.py +232 -169
  36. prefect/runner/runner.py +7 -4
  37. prefect/settings.py +14 -15
  38. prefect/states.py +73 -18
  39. prefect/task_engine.py +127 -221
  40. prefect/task_worker.py +7 -39
  41. prefect/tasks.py +0 -7
  42. prefect/transactions.py +89 -27
  43. prefect/utilities/annotations.py +4 -3
  44. prefect/utilities/asyncutils.py +4 -4
  45. prefect/utilities/callables.py +1 -3
  46. prefect/utilities/dispatch.py +16 -11
  47. prefect/utilities/engine.py +1 -4
  48. prefect/utilities/schema_tools/hydration.py +13 -0
  49. prefect/workers/base.py +78 -18
  50. {prefect_client-3.0.0rc18.dist-info → prefect_client-3.0.0rc20.dist-info}/METADATA +3 -4
  51. {prefect_client-3.0.0rc18.dist-info → prefect_client-3.0.0rc20.dist-info}/RECORD +54 -48
  52. prefect/manifests.py +0 -21
  53. {prefect_client-3.0.0rc18.dist-info → prefect_client-3.0.0rc20.dist-info}/LICENSE +0 -0
  54. {prefect_client-3.0.0rc18.dist-info → prefect_client-3.0.0rc20.dist-info}/WHEEL +0 -0
  55. {prefect_client-3.0.0rc18.dist-info → prefect_client-3.0.0rc20.dist-info}/top_level.txt +0 -0
prefect/states.py CHANGED
@@ -18,12 +18,13 @@ from prefect.exceptions import (
18
18
  CancelledRun,
19
19
  CrashedRun,
20
20
  FailedRun,
21
+ MissingContextError,
21
22
  MissingResult,
22
23
  PausedRun,
23
24
  TerminationSignal,
24
25
  UnfinishedRun,
25
26
  )
26
- from prefect.logging.loggers import get_logger
27
+ from prefect.logging.loggers import get_logger, get_run_logger
27
28
  from prefect.results import BaseResult, R, ResultFactory
28
29
  from prefect.settings import PREFECT_ASYNC_FETCH_STATE_RESULT
29
30
  from prefect.utilities.annotations import BaseAnnotation
@@ -218,11 +219,17 @@ async def exception_to_crashed_state(
218
219
  async def exception_to_failed_state(
219
220
  exc: Optional[BaseException] = None,
220
221
  result_factory: Optional[ResultFactory] = None,
222
+ write_result: bool = False,
221
223
  **kwargs,
222
224
  ) -> State:
223
225
  """
224
226
  Convenience function for creating `Failed` states from exceptions
225
227
  """
228
+ try:
229
+ local_logger = get_run_logger()
230
+ except MissingContextError:
231
+ local_logger = logger
232
+
226
233
  if not exc:
227
234
  _, exc, _ = sys.exc_info()
228
235
  if exc is None:
@@ -234,6 +241,14 @@ async def exception_to_failed_state(
234
241
 
235
242
  if result_factory:
236
243
  data = await result_factory.create_result(exc)
244
+ if write_result:
245
+ try:
246
+ await data.write()
247
+ except Exception as exc:
248
+ local_logger.warning(
249
+ "Failed to write result: %s Execution will continue, but the result has not been written",
250
+ exc,
251
+ )
237
252
  else:
238
253
  # Attach the exception for local usage, will not be available when retrieved
239
254
  # from the API
@@ -258,7 +273,7 @@ async def return_value_to_state(
258
273
  result_factory: ResultFactory,
259
274
  key: Optional[str] = None,
260
275
  expiration: Optional[datetime.datetime] = None,
261
- defer_persistence: bool = False,
276
+ write_result: bool = False,
262
277
  ) -> State[R]:
263
278
  """
264
279
  Given a return value from a user's function, create a `State` the run should
@@ -280,6 +295,10 @@ async def return_value_to_state(
280
295
  Callers should resolve all futures into states before passing return values to this
281
296
  function.
282
297
  """
298
+ try:
299
+ local_logger = get_run_logger()
300
+ except MissingContextError:
301
+ local_logger = logger
283
302
 
284
303
  if (
285
304
  isinstance(retval, State)
@@ -291,13 +310,20 @@ async def return_value_to_state(
291
310
  # Unless the user has already constructed a result explicitly, use the factory
292
311
  # to update the data to the correct type
293
312
  if not isinstance(state.data, BaseResult):
294
- state.data = await result_factory.create_result(
313
+ result = await result_factory.create_result(
295
314
  state.data,
296
315
  key=key,
297
316
  expiration=expiration,
298
- defer_persistence=defer_persistence,
299
317
  )
300
-
318
+ if write_result:
319
+ try:
320
+ await result.write()
321
+ except Exception as exc:
322
+ local_logger.warning(
323
+ "Encountered an error while persisting result: %s Execution will continue, but the result has not been persisted",
324
+ exc,
325
+ )
326
+ state.data = result
301
327
  return state
302
328
 
303
329
  # Determine a new state from the aggregate of contained states
@@ -333,15 +359,23 @@ async def return_value_to_state(
333
359
  # TODO: We may actually want to set the data to a `StateGroup` object and just
334
360
  # allow it to be unpacked into a tuple and such so users can interact with
335
361
  # it
362
+ result = await result_factory.create_result(
363
+ retval,
364
+ key=key,
365
+ expiration=expiration,
366
+ )
367
+ if write_result:
368
+ try:
369
+ await result.write()
370
+ except Exception as exc:
371
+ local_logger.warning(
372
+ "Encountered an error while persisting result: %s Execution will continue, but the result has not been persisted",
373
+ exc,
374
+ )
336
375
  return State(
337
376
  type=new_state_type,
338
377
  message=message,
339
- data=await result_factory.create_result(
340
- retval,
341
- key=key,
342
- expiration=expiration,
343
- defer_persistence=defer_persistence,
344
- ),
378
+ data=result,
345
379
  )
346
380
 
347
381
  # Generators aren't portable, implicitly convert them to a list.
@@ -354,14 +388,20 @@ async def return_value_to_state(
354
388
  if isinstance(data, BaseResult):
355
389
  return Completed(data=data)
356
390
  else:
357
- return Completed(
358
- data=await result_factory.create_result(
359
- data,
360
- key=key,
361
- expiration=expiration,
362
- defer_persistence=defer_persistence,
363
- )
391
+ result = await result_factory.create_result(
392
+ data,
393
+ key=key,
394
+ expiration=expiration,
364
395
  )
396
+ if write_result:
397
+ try:
398
+ await result.write()
399
+ except Exception as exc:
400
+ local_logger.warning(
401
+ "Encountered an error while persisting result: %s Execution will continue, but the result has not been persisted",
402
+ exc,
403
+ )
404
+ return Completed(data=result)
365
405
 
366
406
 
367
407
  @sync_compatible
@@ -684,6 +724,21 @@ def AwaitingRetry(
684
724
  )
685
725
 
686
726
 
727
+ def AwaitingConcurrencySlot(
728
+ cls: Type[State[R]] = State,
729
+ scheduled_time: Optional[datetime.datetime] = None,
730
+ **kwargs: Any,
731
+ ) -> State[R]:
732
+ """Convenience function for creating `AwaitingConcurrencySlot` states.
733
+
734
+ Returns:
735
+ State: a AwaitingConcurrencySlot state
736
+ """
737
+ return Scheduled(
738
+ cls=cls, scheduled_time=scheduled_time, name="AwaitingConcurrencySlot", **kwargs
739
+ )
740
+
741
+
687
742
  def Retrying(cls: Type[State[R]] = State, **kwargs: Any) -> State[R]:
688
743
  """Convenience function for creating `Retrying` states.
689
744