prefect-client 3.8.4.dev6__tar.gz → 3.8.5.dev1__tar.gz

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 (458) hide show
  1. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/PKG-INFO +2 -2
  2. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/pyproject.toml +1 -1
  3. prefect_client-3.8.5.dev1/src/prefect/_build_info.py +5 -0
  4. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/bundles/__init__.py +45 -3
  5. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/bundles/_ignore_filter.py +53 -28
  6. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/events/filters.py +11 -0
  7. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/events/worker.py +26 -3
  8. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/flows.py +57 -9
  9. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/logging/handlers.py +22 -1
  10. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/AGENTS.md +7 -7
  11. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/_cancellation_manager.py +2 -2
  12. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/_flow_run_executor.py +19 -5
  13. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/_hook_runner.py +7 -1
  14. prefect_client-3.8.5.dev1/src/prefect/runner/_process_manager.py +446 -0
  15. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/_starter_engine.py +23 -4
  16. prefect_client-3.8.5.dev1/src/prefect/runner/_workspace_hook_runner.py +80 -0
  17. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/_workspace_resolver.py +8 -1
  18. prefect_client-3.8.5.dev1/src/prefect/runner/_workspace_runtime.py +53 -0
  19. prefect_client-3.8.5.dev1/src/prefect/runner/_workspace_runtime_bootstrap.py +200 -0
  20. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/_workspace_starter.py +76 -146
  21. prefect_client-3.8.5.dev1/src/prefect/runner/_workspace_supervisor.py +204 -0
  22. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/automations.py +7 -1
  23. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/workers/AGENTS.md +2 -2
  24. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/workers/base.py +12 -1
  25. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/workers/process.py +43 -47
  26. prefect_client-3.8.4.dev6/src/prefect/_build_info.py +0 -5
  27. prefect_client-3.8.4.dev6/src/prefect/runner/_process_manager.py +0 -264
  28. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/.gitignore +0 -0
  29. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/LICENSE +0 -0
  30. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/README.md +0 -0
  31. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/hatch_build.py +0 -0
  32. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/.prefectignore +0 -0
  33. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/AGENTS.md +0 -0
  34. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/__init__.py +0 -0
  35. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/__main__.py +0 -0
  36. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_experimental/__init__.py +0 -0
  37. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_experimental/_launchers.py +0 -0
  38. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_experimental/bundles/__init__.py +0 -0
  39. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_experimental/bundles/execute.py +0 -0
  40. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_experimental/plugins/__init__.py +0 -0
  41. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_experimental/plugins/apply.py +0 -0
  42. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_experimental/plugins/diagnostics.py +0 -0
  43. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_experimental/plugins/manager.py +0 -0
  44. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_experimental/plugins/spec.py +0 -0
  45. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_experimental/sla/__init__.py +0 -0
  46. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_experimental/sla/client.py +0 -0
  47. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_experimental/sla/objects.py +0 -0
  48. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_flow_run_suspension.py +0 -0
  49. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/__init__.py +0 -0
  50. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/_logging.py +0 -0
  51. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/analytics/__init__.py +0 -0
  52. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/analytics/ci_detection.py +0 -0
  53. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/analytics/client.py +0 -0
  54. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/analytics/device_id.py +0 -0
  55. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/analytics/emit.py +0 -0
  56. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/analytics/enabled.py +0 -0
  57. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/analytics/events.py +0 -0
  58. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/analytics/milestones.py +0 -0
  59. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/analytics/notice.py +0 -0
  60. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/analytics/service.py +0 -0
  61. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/ast_utils.py +0 -0
  62. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/attempt_control.py +0 -0
  63. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/buildx.py +0 -0
  64. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/compatibility/__init__.py +0 -0
  65. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/compatibility/async_dispatch.py +0 -0
  66. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/compatibility/backports.py +0 -0
  67. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/compatibility/blocks.py +0 -0
  68. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/compatibility/deprecated.py +0 -0
  69. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/compatibility/deprecated_paths.py +0 -0
  70. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/compatibility/migration.py +0 -0
  71. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/compatibility/starlette.py +0 -0
  72. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/concurrency/__init__.py +0 -0
  73. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/concurrency/api.py +0 -0
  74. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/concurrency/calls.py +0 -0
  75. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/concurrency/cancellation.py +0 -0
  76. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/concurrency/event_loop.py +0 -0
  77. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/concurrency/inspection.py +0 -0
  78. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/concurrency/primitives.py +0 -0
  79. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/concurrency/services.py +0 -0
  80. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/concurrency/threads.py +0 -0
  81. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/concurrency/waiters.py +0 -0
  82. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/control_listener.py +0 -0
  83. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/deprecated.py +0 -0
  84. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/engine.py +0 -0
  85. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/git.py +0 -0
  86. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/infrastructure_exit_codes.py +0 -0
  87. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/installation.py +0 -0
  88. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/integrations.py +0 -0
  89. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/launchers.py +0 -0
  90. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/lazy.py +0 -0
  91. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/metrics.py +0 -0
  92. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/observability.py +0 -0
  93. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/observers.py +0 -0
  94. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/plugins/__init__.py +0 -0
  95. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/plugins/apply.py +0 -0
  96. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/plugins/collections.py +0 -0
  97. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/plugins/diagnostics.py +0 -0
  98. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/plugins/manager.py +0 -0
  99. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/plugins/spec.py +0 -0
  100. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/plugins/startup.py +0 -0
  101. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/pydantic/__init__.py +0 -0
  102. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/pydantic/schemas.py +0 -0
  103. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/pydantic/v1_schema.py +0 -0
  104. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/pydantic/v2_schema.py +0 -0
  105. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/pydantic/validated_func.py +0 -0
  106. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/pytz.py +0 -0
  107. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/result_records.py +0 -0
  108. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/retries.py +0 -0
  109. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/schema.py +0 -0
  110. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/schemas/__init__.py +0 -0
  111. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/schemas/_registry.py +0 -0
  112. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/schemas/bases.py +0 -0
  113. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/schemas/fields.py +0 -0
  114. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/schemas/serializers.py +0 -0
  115. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/schemas/validators.py +0 -0
  116. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/send_entrypoint_logs.py +0 -0
  117. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/states.py +0 -0
  118. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/testing.py +0 -0
  119. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/urls.py +0 -0
  120. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/uuid7.py +0 -0
  121. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/version_checking.py +0 -0
  122. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/versioning.py +0 -0
  123. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/waiters.py +0 -0
  124. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_internal/websockets.py +0 -0
  125. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_sdk/__init__.py +0 -0
  126. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_sdk/fetcher.py +0 -0
  127. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_sdk/generator.py +0 -0
  128. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_sdk/models.py +0 -0
  129. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_sdk/naming.py +0 -0
  130. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_sdk/renderer.py +0 -0
  131. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_sdk/schema_converter.py +0 -0
  132. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_sdk/templates/__init__.py +0 -0
  133. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_sdk/templates/sdk.py.jinja +0 -0
  134. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_sdk/types.py +0 -0
  135. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_sdk/unions.py +0 -0
  136. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_vendor/croniter/__init__.py +0 -0
  137. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/_vendor/croniter/croniter.py +0 -0
  138. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/agent.py +0 -0
  139. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/analytics/__init__.py +0 -0
  140. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/artifacts.py +0 -0
  141. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/assets/__init__.py +0 -0
  142. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/assets/core.py +0 -0
  143. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/assets/materialize.py +0 -0
  144. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/automations.py +0 -0
  145. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/blocks/AGENTS.md +0 -0
  146. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/blocks/__init__.py +0 -0
  147. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/blocks/abstract.py +0 -0
  148. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/blocks/core.py +0 -0
  149. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/blocks/fields.py +0 -0
  150. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/blocks/notifications.py +0 -0
  151. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/blocks/redis.py +0 -0
  152. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/blocks/system.py +0 -0
  153. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/blocks/webhook.py +0 -0
  154. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/bundles/_file_collector.py +0 -0
  155. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/bundles/_path_resolver.py +0 -0
  156. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/bundles/_zip_builder.py +0 -0
  157. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/bundles/_zip_extractor.py +0 -0
  158. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/bundles/execute.py +0 -0
  159. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/cache_policies.py +0 -0
  160. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/AGENTS.md +0 -0
  161. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/__init__.py +0 -0
  162. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/attribution.py +0 -0
  163. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/base.py +0 -0
  164. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/cloud.py +0 -0
  165. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/collections.py +0 -0
  166. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/constants.py +0 -0
  167. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/__init__.py +0 -0
  168. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_artifacts/__init__.py +0 -0
  169. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_artifacts/client.py +0 -0
  170. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_automations/__init__.py +0 -0
  171. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_automations/client.py +0 -0
  172. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_blocks_documents/__init__.py +0 -0
  173. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_blocks_documents/client.py +0 -0
  174. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_blocks_schemas/__init__.py +0 -0
  175. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_blocks_schemas/client.py +0 -0
  176. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_blocks_types/__init__.py +0 -0
  177. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_blocks_types/client.py +0 -0
  178. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_concurrency_limits/__init__.py +0 -0
  179. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_concurrency_limits/client.py +0 -0
  180. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_deployments/__init__.py +0 -0
  181. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_deployments/client.py +0 -0
  182. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_events/__init__.py +0 -0
  183. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_events/client.py +0 -0
  184. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_flow_runs/__init__.py +0 -0
  185. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_flow_runs/client.py +0 -0
  186. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_flows/__init__.py +0 -0
  187. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_flows/client.py +0 -0
  188. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_logs/__init__.py +0 -0
  189. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_logs/client.py +0 -0
  190. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_variables/__init__.py +0 -0
  191. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_variables/client.py +0 -0
  192. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_work_pools/__init__.py +0 -0
  193. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/_work_pools/client.py +0 -0
  194. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/base.py +0 -0
  195. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/orchestration/routes.py +0 -0
  196. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/schemas/__init__.py +0 -0
  197. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/schemas/actions.py +0 -0
  198. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/schemas/events.py +0 -0
  199. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/schemas/filters.py +0 -0
  200. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/schemas/objects.py +0 -0
  201. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/schemas/responses.py +0 -0
  202. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/schemas/schedules.py +0 -0
  203. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/schemas/sorting.py +0 -0
  204. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/schemas/worker_channel.py +0 -0
  205. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/subscriptions.py +0 -0
  206. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/types/__init__.py +0 -0
  207. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/types/flexible_schedule_list.py +0 -0
  208. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/client/utilities.py +0 -0
  209. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/concurrency/AGENTS.md +0 -0
  210. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/concurrency/__init__.py +0 -0
  211. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/concurrency/_asyncio.py +0 -0
  212. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/concurrency/_events.py +0 -0
  213. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/concurrency/_leases.py +0 -0
  214. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/concurrency/_sync.py +0 -0
  215. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/concurrency/asyncio.py +0 -0
  216. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/concurrency/context.py +0 -0
  217. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/concurrency/services.py +0 -0
  218. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/concurrency/sync.py +0 -0
  219. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/concurrency/v1/__init__.py +0 -0
  220. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/concurrency/v1/_asyncio.py +0 -0
  221. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/concurrency/v1/_events.py +0 -0
  222. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/concurrency/v1/asyncio.py +0 -0
  223. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/concurrency/v1/context.py +0 -0
  224. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/concurrency/v1/services.py +0 -0
  225. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/concurrency/v1/sync.py +0 -0
  226. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/context.py +0 -0
  227. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/deployments/AGENTS.md +0 -0
  228. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/deployments/__init__.py +0 -0
  229. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/deployments/base.py +0 -0
  230. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/deployments/deployments.py +0 -0
  231. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/deployments/flow_runs.py +0 -0
  232. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/deployments/runner.py +0 -0
  233. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/deployments/schedules.py +0 -0
  234. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/deployments/steps/__init__.py +0 -0
  235. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/deployments/steps/core.py +0 -0
  236. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/deployments/steps/pull.py +0 -0
  237. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/deployments/steps/utility.py +0 -0
  238. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/docker/__init__.py +0 -0
  239. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/docker/_buildx.py +0 -0
  240. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/docker/docker_image.py +0 -0
  241. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/engine.py +0 -0
  242. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/events/AGENTS.md +0 -0
  243. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/events/__init__.py +0 -0
  244. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/events/actions.py +0 -0
  245. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/events/clients.py +0 -0
  246. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/events/related.py +0 -0
  247. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/events/schemas/__init__.py +0 -0
  248. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/events/schemas/automations.py +0 -0
  249. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/events/schemas/deployment_triggers.py +0 -0
  250. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/events/schemas/events.py +0 -0
  251. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/events/schemas/labelling.py +0 -0
  252. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/events/subscribers.py +0 -0
  253. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/events/utilities.py +0 -0
  254. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/exceptions.py +0 -0
  255. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/filesystems.py +0 -0
  256. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/flow_engine.py +0 -0
  257. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/flow_runs.py +0 -0
  258. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/futures.py +0 -0
  259. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/infrastructure/__init__.py +0 -0
  260. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/infrastructure/base.py +0 -0
  261. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/infrastructure/provisioners/__init__.py +0 -0
  262. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/infrastructure/provisioners/cloud_run.py +0 -0
  263. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/infrastructure/provisioners/coiled.py +0 -0
  264. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/infrastructure/provisioners/container_instance.py +0 -0
  265. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/infrastructure/provisioners/ecs.py +0 -0
  266. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/infrastructure/provisioners/modal.py +0 -0
  267. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/input/__init__.py +0 -0
  268. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/input/actions.py +0 -0
  269. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/input/run_input.py +0 -0
  270. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/locking/__init__.py +0 -0
  271. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/locking/_filelock.py +0 -0
  272. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/locking/filesystem.py +0 -0
  273. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/locking/memory.py +0 -0
  274. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/locking/protocol.py +0 -0
  275. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/logging/AGENTS.md +0 -0
  276. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/logging/__init__.py +0 -0
  277. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/logging/clients.py +0 -0
  278. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/logging/configuration.py +0 -0
  279. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/logging/filters.py +0 -0
  280. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/logging/formatters.py +0 -0
  281. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/logging/highlighters.py +0 -0
  282. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/logging/loggers.py +0 -0
  283. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/logging/logging.yml +0 -0
  284. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/main.py +0 -0
  285. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/plugins.py +0 -0
  286. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/py.typed +0 -0
  287. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/results.py +0 -0
  288. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/__init__.py +0 -0
  289. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/_cancel_finalizer.py +0 -0
  290. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/_control_channel.py +0 -0
  291. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/_deployment_registry.py +0 -0
  292. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/_event_emitter.py +0 -0
  293. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/_flow_resolver.py +0 -0
  294. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/_limit_manager.py +0 -0
  295. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/_scheduled_run_poller.py +0 -0
  296. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/_starter_bundle.py +0 -0
  297. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/_starter_direct.py +0 -0
  298. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/_state_proposer.py +0 -0
  299. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/_uv_command.py +0 -0
  300. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/runner.py +0 -0
  301. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/server.py +0 -0
  302. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runner/storage.py +0 -0
  303. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runtime/__init__.py +0 -0
  304. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runtime/deployment.py +0 -0
  305. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runtime/flow_run.py +0 -0
  306. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/runtime/task_run.py +0 -0
  307. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/schedules.py +0 -0
  308. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/serializers.py +0 -0
  309. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/__init__.py +0 -0
  310. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/_ui_static.py +0 -0
  311. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/admin.py +0 -0
  312. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/artifacts.py +0 -0
  313. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/background_workers.py +0 -0
  314. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/block_capabilities.py +0 -0
  315. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/block_documents.py +0 -0
  316. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/block_schemas.py +0 -0
  317. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/block_types.py +0 -0
  318. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/clients.py +0 -0
  319. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/collections.py +0 -0
  320. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/collections_data/views/aggregate-worker-metadata.json +0 -0
  321. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/concurrency_limits.py +0 -0
  322. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/concurrency_limits_v2.py +0 -0
  323. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/csrf_token.py +0 -0
  324. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/dependencies.py +0 -0
  325. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/deployments.py +0 -0
  326. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/events.py +0 -0
  327. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/flow_run_states.py +0 -0
  328. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/flow_runs.py +0 -0
  329. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/flows.py +0 -0
  330. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/logs.py +0 -0
  331. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/middleware.py +0 -0
  332. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/root.py +0 -0
  333. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/run_history.py +0 -0
  334. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/saved_searches.py +0 -0
  335. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/server.py +0 -0
  336. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/static/prefect-logo-mark-gradient.png +0 -0
  337. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/task_run_states.py +0 -0
  338. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/task_runs.py +0 -0
  339. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/task_workers.py +0 -0
  340. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/templates.py +0 -0
  341. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/ui/__init__.py +0 -0
  342. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/ui/flow_runs.py +0 -0
  343. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/ui/flows.py +0 -0
  344. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/ui/schemas.py +0 -0
  345. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/ui/task_runs.py +0 -0
  346. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/validation.py +0 -0
  347. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/variables.py +0 -0
  348. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/work_queues.py +0 -0
  349. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/server/api/workers.py +0 -0
  350. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/AGENTS.md +0 -0
  351. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/__init__.py +0 -0
  352. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/_types.py +0 -0
  353. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/base.py +0 -0
  354. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/constants.py +0 -0
  355. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/context.py +0 -0
  356. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/legacy.py +0 -0
  357. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/__init__.py +0 -0
  358. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/_defaults.py +0 -0
  359. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/api.py +0 -0
  360. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/cli.py +0 -0
  361. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/client.py +0 -0
  362. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/cloud.py +0 -0
  363. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/deployments.py +0 -0
  364. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/events.py +0 -0
  365. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/experiments.py +0 -0
  366. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/flows.py +0 -0
  367. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/internal.py +0 -0
  368. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/logging.py +0 -0
  369. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/plugins.py +0 -0
  370. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/results.py +0 -0
  371. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/root.py +0 -0
  372. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/runner.py +0 -0
  373. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/server/__init__.py +0 -0
  374. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/server/api.py +0 -0
  375. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/server/concurrency.py +0 -0
  376. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/server/database.py +0 -0
  377. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/server/deployments.py +0 -0
  378. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/server/docket.py +0 -0
  379. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/server/ephemeral.py +0 -0
  380. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/server/events.py +0 -0
  381. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/server/flow_run_graph.py +0 -0
  382. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/server/logs.py +0 -0
  383. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/server/root.py +0 -0
  384. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/server/services.py +0 -0
  385. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/server/tasks.py +0 -0
  386. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/server/ui.py +0 -0
  387. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/server/worker_channel.py +0 -0
  388. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/tasks.py +0 -0
  389. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/telemetry.py +0 -0
  390. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/testing.py +0 -0
  391. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/models/worker.py +0 -0
  392. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/profiles.py +0 -0
  393. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/profiles.toml +0 -0
  394. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/settings/sources.py +0 -0
  395. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/states.py +0 -0
  396. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/task_engine.py +0 -0
  397. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/task_runners.py +0 -0
  398. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/task_runs.py +0 -0
  399. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/task_worker.py +0 -0
  400. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/tasks.py +0 -0
  401. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/telemetry/__init__.py +0 -0
  402. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/telemetry/run_telemetry.py +0 -0
  403. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/transactions.py +0 -0
  404. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/types/__init__.py +0 -0
  405. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/types/_concurrency.py +0 -0
  406. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/types/_datetime.py +0 -0
  407. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/types/entrypoint.py +0 -0
  408. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/types/names.py +0 -0
  409. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/AGENTS.md +0 -0
  410. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/__init__.py +0 -0
  411. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/annotations.py +0 -0
  412. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/asyncutils/AGENTS.md +0 -0
  413. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/asyncutils/__init__.py +0 -0
  414. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/callables/AGENTS.md +0 -0
  415. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/callables/__init__.py +0 -0
  416. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/collections.py +0 -0
  417. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/compat.py +0 -0
  418. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/context.py +0 -0
  419. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/dispatch.py +0 -0
  420. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/dockerutils.py +0 -0
  421. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/engine/AGENTS.md +0 -0
  422. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/engine/__init__.py +0 -0
  423. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/filesystem/AGENTS.md +0 -0
  424. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/filesystem/__init__.py +0 -0
  425. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/generics.py +0 -0
  426. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/hashing.py +0 -0
  427. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/importtools.py +0 -0
  428. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/math.py +0 -0
  429. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/names.py +0 -0
  430. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/processutils/AGENTS.md +0 -0
  431. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/processutils/__init__.py +0 -0
  432. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/pydantic.py +0 -0
  433. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/render_swagger.py +0 -0
  434. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/schema_tools/AGENTS.md +0 -0
  435. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/schema_tools/__init__.py +0 -0
  436. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/schema_tools/hydration.py +0 -0
  437. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/schema_tools/validation.py +0 -0
  438. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/services.py +0 -0
  439. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/slugify.py +0 -0
  440. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/templating/AGENTS.md +0 -0
  441. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/templating/__init__.py +0 -0
  442. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/text.py +0 -0
  443. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/timeout.py +0 -0
  444. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/urls.py +0 -0
  445. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/utilities/visualization.py +0 -0
  446. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/variables.py +0 -0
  447. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/workers/__init__.py +0 -0
  448. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/workers/_cleanup.py +0 -0
  449. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/workers/_cleanup_handlers.py +0 -0
  450. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/workers/_worker_channel/__init__.py +0 -0
  451. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/workers/_worker_channel/_protocol.py +0 -0
  452. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/workers/_worker_channel/_state.py +0 -0
  453. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/workers/_worker_channel/_sync.py +0 -0
  454. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/workers/_worker_channel/_transport.py +0 -0
  455. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/workers/block.py +0 -0
  456. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/workers/cloud.py +0 -0
  457. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/workers/server.py +0 -0
  458. {prefect_client-3.8.4.dev6 → prefect_client-3.8.5.dev1}/src/prefect/workers/utilities.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: prefect-client
3
- Version: 3.8.4.dev6
3
+ Version: 3.8.5.dev1
4
4
  Summary: Workflow orchestration and management.
5
5
  Project-URL: Changelog, https://github.com/PrefectHQ/prefect/releases
6
6
  Project-URL: Documentation, https://docs.prefect.io
@@ -64,7 +64,7 @@ Requires-Dist: uvicorn!=0.29.0,>=0.14.0
64
64
  Requires-Dist: websockets<17.0,>=15.0.1
65
65
  Requires-Dist: whenever<0.11.0,>=0.7.3; python_version >= '3.13'
66
66
  Provides-Extra: notifications
67
- Requires-Dist: apprise<2.0.0,>=1.1.0; extra == 'notifications'
67
+ Requires-Dist: apprise<2.0.0,>=1.13.0; extra == 'notifications'
68
68
  Description-Content-Type: text/markdown
69
69
 
70
70
  <p align="center"><img src="https://github.com/PrefectHQ/prefect/assets/3407835/c654cbc6-63e8-4ada-a92a-efd2f8f24b85" width=1000></p>
@@ -74,7 +74,7 @@ Documentation = "https://docs.prefect.io"
74
74
  Source = "https://github.com/PrefectHQ/prefect"
75
75
  Tracker = "https://github.com/PrefectHQ/prefect/issues"
76
76
  [project.optional-dependencies]
77
- notifications = ["apprise>=1.1.0, <2.0.0"]
77
+ notifications = ["apprise>=1.13.0, <2.0.0"]
78
78
 
79
79
 
80
80
  [tool.hatch.version]
@@ -0,0 +1,5 @@
1
+ # Generated by versioningit
2
+ __version__ = "3.8.5.dev1"
3
+ __build_date__ = "2026-08-27 11:29:02.793270+00:00"
4
+ __git_commit__ = "38041e65c47f7e3c350fce8f7e5c64de3bc1e103"
5
+ __dirty__ = False
@@ -11,6 +11,7 @@ import logging
11
11
  import multiprocessing
12
12
  import multiprocessing.context
13
13
  import os
14
+ import stat
14
15
  import subprocess
15
16
  import sys
16
17
  import tempfile
@@ -395,6 +396,41 @@ def _pickle_local_modules_by_value(flow: Flow[Any, Any]):
395
396
  )
396
397
 
397
398
 
399
+ def _resolve_include_files_base_dir(value: Path | str) -> Path:
400
+ """Resolve and validate an explicitly configured include-files base directory."""
401
+ try:
402
+ candidate = Path(value).expanduser()
403
+ except RuntimeError as exc:
404
+ raise ValueError(
405
+ f"Invalid include_files_base_dir {str(value)!r}: {exc}"
406
+ ) from exc
407
+
408
+ if not candidate.is_absolute():
409
+ candidate = Path.cwd() / candidate
410
+
411
+ try:
412
+ base_dir = candidate.resolve(strict=True)
413
+ if not stat.S_ISDIR(base_dir.stat().st_mode):
414
+ raise ValueError(
415
+ f"include_files_base_dir {str(value)!r} must be a directory."
416
+ )
417
+
418
+ # Open the directory to verify that collection can read it. `os.access` is
419
+ # not sufficient because its result can differ from the actual operation.
420
+ with os.scandir(base_dir):
421
+ pass
422
+ except FileNotFoundError as exc:
423
+ raise ValueError(
424
+ f"include_files_base_dir {str(value)!r} does not exist."
425
+ ) from exc
426
+ except NotADirectoryError as exc:
427
+ raise ValueError(
428
+ f"include_files_base_dir {str(value)!r} must be a directory."
429
+ ) from exc
430
+
431
+ return base_dir
432
+
433
+
398
434
  def create_bundle_for_flow_run(
399
435
  flow: Flow[Any, Any],
400
436
  flow_run: FlowRun,
@@ -463,12 +499,16 @@ def create_bundle_for_flow_run(
463
499
  files_key: str | None = None
464
500
  zip_path: Path | None = None
465
501
  include_files = getattr(flow, "include_files", None)
502
+ include_files_base_dir = getattr(flow, "include_files_base_dir", None)
466
503
 
467
504
  if include_files:
468
505
  try:
469
- # Get base directory from flow file location
470
- flow_file = Path(inspect.getfile(flow.fn))
471
- base_dir = flow_file.parent.resolve()
506
+ if include_files_base_dir is None:
507
+ # Preserve the existing default relative to the flow definition.
508
+ flow_file = Path(inspect.getfile(flow.fn))
509
+ base_dir = flow_file.parent.resolve()
510
+ else:
511
+ base_dir = _resolve_include_files_base_dir(include_files_base_dir)
472
512
 
473
513
  # Pipeline: collect -> filter -> check -> zip
474
514
  collector = FileCollector(base_dir)
@@ -498,6 +538,8 @@ def create_bundle_for_flow_run(
498
538
  files_key,
499
539
  )
500
540
  except (OSError, TypeError, AttributeError) as e:
541
+ if include_files_base_dir is not None:
542
+ raise
501
543
  # Handle cases where flow has no file (dynamic flow) or other IO errors
502
544
  logger.warning(
503
545
  "Could not collect included files: %s. Files will not be bundled.",
@@ -87,23 +87,9 @@ def _read_ignore_file(path: Path) -> list[str]:
87
87
  return [line for line in lines if line.strip() and not line.startswith("#")]
88
88
 
89
89
 
90
- def load_ignore_patterns(flow_dir: Path) -> list[str]:
91
- """
92
- Load patterns from cascading .prefectignore files.
93
-
94
- Load order (patterns combined via union):
95
- 1. Project root .prefectignore (if found via pyproject.toml detection)
96
- 2. Flow directory .prefectignore (if different from project root)
97
-
98
- Missing .prefectignore files emit debug log, not warning.
99
-
100
- Args:
101
- flow_dir: Flow file's directory (base for relative paths).
102
-
103
- Returns:
104
- Combined list of pattern strings from all .prefectignore files.
105
- """
106
- patterns: list[str] = []
90
+ def _load_ignore_pattern_sources(flow_dir: Path) -> list[tuple[Path, list[str]]]:
91
+ """Load ignore patterns together with the directory they are relative to."""
92
+ sources: list[tuple[Path, list[str]]] = []
107
93
 
108
94
  # 1. Find and load project root .prefectignore
109
95
  project_root = find_project_root(flow_dir)
@@ -111,7 +97,7 @@ def load_ignore_patterns(flow_dir: Path) -> list[str]:
111
97
  project_ignore = project_root / ".prefectignore"
112
98
  if project_ignore.exists():
113
99
  logger.debug(f"Loading .prefectignore from project root: {project_ignore}")
114
- patterns.extend(_read_ignore_file(project_ignore))
100
+ sources.append((project_root.resolve(), _read_ignore_file(project_ignore)))
115
101
  else:
116
102
  logger.debug(f"No .prefectignore found at project root: {project_root}")
117
103
  else:
@@ -123,11 +109,34 @@ def load_ignore_patterns(flow_dir: Path) -> list[str]:
123
109
  # Only load if different from project root's .prefectignore
124
110
  if project_root is None or flow_dir.resolve() != project_root.resolve():
125
111
  logger.debug(f"Loading .prefectignore from flow directory: {flow_ignore}")
126
- patterns.extend(_read_ignore_file(flow_ignore))
112
+ sources.append((flow_dir.resolve(), _read_ignore_file(flow_ignore)))
127
113
  else:
128
114
  logger.debug(f"No .prefectignore found in flow directory: {flow_dir}")
129
115
 
130
- return patterns
116
+ return sources
117
+
118
+
119
+ def load_ignore_patterns(flow_dir: Path) -> list[str]:
120
+ """
121
+ Load patterns from cascading .prefectignore files.
122
+
123
+ Load order (later matching patterns override earlier patterns):
124
+ 1. Project root .prefectignore (if found via pyproject.toml detection)
125
+ 2. Flow directory .prefectignore (if different from project root)
126
+
127
+ Missing .prefectignore files emit debug log, not warning.
128
+
129
+ Args:
130
+ flow_dir: Flow file's directory (base for relative paths).
131
+
132
+ Returns:
133
+ Combined list of pattern strings from all .prefectignore files.
134
+ """
135
+ return [
136
+ pattern
137
+ for _, patterns in _load_ignore_pattern_sources(flow_dir)
138
+ for pattern in patterns
139
+ ]
131
140
 
132
141
 
133
142
  class IgnoreFilter:
@@ -155,14 +164,16 @@ class IgnoreFilter:
155
164
  flow_dir: Base directory for file collection (typically flow file's parent).
156
165
  """
157
166
  self.flow_dir = flow_dir.resolve()
158
- self._spec: pathspec.GitIgnoreSpec | None = None
167
+ self._specs: list[tuple[Path, pathspec.GitIgnoreSpec]] = []
159
168
  self._load_patterns()
160
169
 
161
170
  def _load_patterns(self) -> None:
162
171
  """Load patterns and compile into pathspec."""
163
- patterns = load_ignore_patterns(self.flow_dir)
164
- if patterns:
165
- self._spec = pathspec.GitIgnoreSpec.from_lines(patterns)
172
+ for pattern_root, patterns in _load_ignore_pattern_sources(self.flow_dir):
173
+ if patterns:
174
+ self._specs.append(
175
+ (pattern_root, pathspec.GitIgnoreSpec.from_lines(patterns))
176
+ )
166
177
 
167
178
  def filter(
168
179
  self,
@@ -202,11 +213,25 @@ class IgnoreFilter:
202
213
  result.excluded_by_ignore.append(file)
203
214
  continue
204
215
 
205
- # Check against ignore spec
216
+ # Check against ignore specs in cascade order. A later source only
217
+ # overrides the current decision when one of its patterns matches.
206
218
  excluded = False
207
- if self._spec is not None:
208
- if self._spec.match_file(rel_path):
209
- excluded = True
219
+ for pattern_root, spec in self._specs:
220
+ try:
221
+ pattern_path = str(file.relative_to(pattern_root))
222
+ except ValueError:
223
+ try:
224
+ pattern_path = str(file.resolve().relative_to(pattern_root))
225
+ except ValueError:
226
+ continue
227
+
228
+ normalized_path = pathspec.util.normalize_file(pattern_path)
229
+ if any(
230
+ pattern.include is not None
231
+ and pattern.match_file(normalized_path) is not None
232
+ for pattern in spec.patterns
233
+ ):
234
+ excluded = spec.match_file(normalized_path)
210
235
 
211
236
  if excluded:
212
237
  result.excluded_by_ignore.append(file)
@@ -14,6 +14,14 @@ from prefect.utilities.collections import AutoEnum
14
14
  from .schemas.events import Event, Resource, ResourceSpecification
15
15
 
16
16
 
17
+ class AutomationFilterId(PrefectBaseModel):
18
+ """Filter by `Automation.id`."""
19
+
20
+ any_: Optional[list[UUID]] = Field(
21
+ default=None, description="A list of automation ids to include"
22
+ )
23
+
24
+
17
25
  class AutomationFilterCreated(PrefectBaseModel):
18
26
  """Filter by `Automation.created`."""
19
27
 
@@ -52,6 +60,9 @@ class AutomationFilterTags(PrefectBaseModel):
52
60
 
53
61
 
54
62
  class AutomationFilter(PrefectBaseModel):
63
+ id: Optional[AutomationFilterId] = Field(
64
+ default=None, description="Filter criteria for `Automation.id`"
65
+ )
55
66
  name: Optional[AutomationFilterName] = Field(
56
67
  default=None, description="Filter criteria for `Automation.name`"
57
68
  )
@@ -6,10 +6,12 @@ from uuid import UUID
6
6
  from typing_extensions import Self
7
7
 
8
8
  from prefect._internal.concurrency.services import QueueService
9
+ from prefect.logging import get_logger
9
10
  from prefect.settings import (
10
11
  PREFECT_API_KEY,
11
12
  PREFECT_API_URL,
12
13
  PREFECT_CLOUD_API_URL,
14
+ get_current_settings,
13
15
  )
14
16
  from prefect.utilities.context import temporary_context
15
17
 
@@ -23,8 +25,12 @@ from .related import related_resources_from_run_context
23
25
  from .schemas.events import Event
24
26
 
25
27
  if TYPE_CHECKING:
28
+ import logging
29
+
26
30
  from prefect.client.orchestration import PrefectClient
27
31
 
32
+ logger: "logging.Logger" = get_logger(__name__)
33
+
28
34
 
29
35
  class ProcessPoolForwardingEventsClient(EventsClient):
30
36
  """An events client that forwards events to a parent process queue."""
@@ -69,8 +75,6 @@ class EventsWorker(QueueService[Event]):
69
75
  def __init__(
70
76
  self, client_type: Type[EventsClient], client_options: Tuple[Tuple[str, Any]]
71
77
  ):
72
- from prefect.settings import get_current_settings
73
-
74
78
  self._max_queue_size = get_current_settings().events.worker_max_queue_size
75
79
  super().__init__(client_type, client_options)
76
80
  self.client_type = client_type
@@ -113,10 +117,29 @@ class EventsWorker(QueueService[Event]):
113
117
  return
114
118
 
115
119
  exclude = {resource.id for resource in event.involved_resources}
116
- event.related += await related_resources_from_run_context(
120
+ related = await related_resources_from_run_context(
117
121
  client=self._orchestration_client, exclude=exclude
118
122
  )
119
123
 
124
+ # The event was validated when it was created, before these resources were
125
+ # known, so only attach as many as keep the event within the same maximum that
126
+ # the Event schema validates. Otherwise the event is no longer valid to send.
127
+ maximum = get_current_settings().server.events.maximum_related_resources
128
+ room = max(maximum - len(event.related), 0)
129
+ if len(related) > room:
130
+ logger.warning(
131
+ "Attaching only %s of the %s related resources from the run context "
132
+ "to event %s, which already has %s of a maximum %s related resources",
133
+ room,
134
+ len(related),
135
+ event.id,
136
+ len(event.related),
137
+ maximum,
138
+ )
139
+ related = related[:room]
140
+
141
+ event.related += related
142
+
120
143
  @classmethod
121
144
  def set_client_override(
122
145
  cls, client_type: Optional[Type[EventsClient]], **client_kwargs: Any
@@ -2397,6 +2397,10 @@ class InfrastructureBoundFlow(Flow[P, R]):
2397
2397
  job_variables: Infrastructure configuration that will override the base job
2398
2398
  configuration of the work pool.
2399
2399
  launcher: Optional upload and execution launcher overrides.
2400
+ include_files: Optional file patterns to include with the flow bundle.
2401
+ include_files_base_dir: Optional base directory for `include_files`. Relative
2402
+ paths are resolved from the working directory when the bundle is created.
2403
+ Defaults to the flow file's directory.
2400
2404
  worker_cls: The class of the worker to use to spin up infrastructure and submit
2401
2405
  the flow to it.
2402
2406
  """
@@ -2409,6 +2413,7 @@ class InfrastructureBoundFlow(Flow[P, R]):
2409
2413
  worker_cls: type["BaseWorker[Any, Any, Any]"],
2410
2414
  launcher: BundleLauncher | None = None,
2411
2415
  include_files: Sequence[str] | None = None,
2416
+ include_files_base_dir: Path | str | None = None,
2412
2417
  **kwargs: Any,
2413
2418
  ):
2414
2419
  super().__init__(*args, **kwargs)
@@ -2419,6 +2424,9 @@ class InfrastructureBoundFlow(Flow[P, R]):
2419
2424
  self.include_files: list[str] | None = (
2420
2425
  list(include_files) if include_files is not None else None
2421
2426
  )
2427
+ self.include_files_base_dir: str | None = (
2428
+ str(include_files_base_dir) if include_files_base_dir is not None else None
2429
+ )
2422
2430
 
2423
2431
  @overload
2424
2432
  def __call__(self: "Flow[P, NoReturn]", *args: P.args, **kwargs: P.kwargs) -> None:
@@ -2648,7 +2656,7 @@ class InfrastructureBoundFlow(Flow[P, R]):
2648
2656
  get_result_store,
2649
2657
  resolve_result_storage,
2650
2658
  )
2651
- from prefect.states import Pending, Scheduled
2659
+ from prefect.states import Failed, Pending, Scheduled
2652
2660
  from prefect.tasks import Task
2653
2661
 
2654
2662
  # Get parameters to error early if they are invalid
@@ -2753,14 +2761,28 @@ class InfrastructureBoundFlow(Flow[P, R]):
2753
2761
  parent_task_run_id=getattr(parent_task_run, "id", None),
2754
2762
  )
2755
2763
 
2756
- result = create_bundle_for_flow_run(flow=flow, flow_run=flow_run)
2757
- upload_bundle_to_storage(
2758
- result["bundle"],
2759
- bundle_key,
2760
- upload_command,
2761
- zip_path=result["zip_path"],
2762
- upload_step=upload_step,
2763
- )
2764
+ try:
2765
+ result = create_bundle_for_flow_run(flow=flow, flow_run=flow_run)
2766
+ upload_bundle_to_storage(
2767
+ result["bundle"],
2768
+ bundle_key,
2769
+ upload_command,
2770
+ zip_path=result["zip_path"],
2771
+ upload_step=upload_step,
2772
+ )
2773
+ except Exception as exc:
2774
+ try:
2775
+ client.set_flow_run_state(
2776
+ flow_run.id,
2777
+ state=Failed(message=f"Flow run submission failed: {exc}"),
2778
+ force=True,
2779
+ )
2780
+ except Exception:
2781
+ logger.exception(
2782
+ "Failed to update flow run %s after submission failed",
2783
+ flow_run.id,
2784
+ )
2785
+ raise
2764
2786
 
2765
2787
  # Set flow run to scheduled now that the bundle is uploaded and ready to be executed
2766
2788
  client.set_flow_run_state(flow_run.id, state=Scheduled())
@@ -2795,6 +2817,7 @@ class InfrastructureBoundFlow(Flow[P, R]):
2795
2817
  job_variables: Optional[dict[str, Any]] = None,
2796
2818
  launcher: BundleLauncher | None = NotSet, # type: ignore
2797
2819
  include_files: Optional[list[str]] = NotSet, # type: ignore
2820
+ include_files_base_dir: Path | str | None = NotSet, # type: ignore
2798
2821
  ) -> "InfrastructureBoundFlow[P, R]":
2799
2822
  new_flow = super().with_options(
2800
2823
  name=name,
@@ -2828,6 +2851,9 @@ class InfrastructureBoundFlow(Flow[P, R]):
2828
2851
  include_files=include_files
2829
2852
  if include_files is not NotSet
2830
2853
  else self.include_files,
2854
+ include_files_base_dir=include_files_base_dir
2855
+ if include_files_base_dir is not NotSet
2856
+ else self.include_files_base_dir,
2831
2857
  )
2832
2858
  return new_infrastructure_bound_flow
2833
2859
 
@@ -2839,7 +2865,25 @@ def bind_flow_to_infrastructure(
2839
2865
  job_variables: dict[str, Any] | None = None,
2840
2866
  launcher: BundleLauncher | None = None,
2841
2867
  include_files: Sequence[str] | None = None,
2868
+ *,
2869
+ include_files_base_dir: Path | str | None = None,
2842
2870
  ) -> InfrastructureBoundFlow[P, R]:
2871
+ """Bind a flow to execution on a specific infrastructure work pool.
2872
+
2873
+ Args:
2874
+ flow: The flow to bind.
2875
+ work_pool: The name of the work pool to use.
2876
+ worker_cls: The worker class that submits the flow.
2877
+ job_variables: Infrastructure overrides for the work pool's base job template.
2878
+ launcher: Optional upload and execution launcher overrides.
2879
+ include_files: Optional file patterns to include with the flow bundle.
2880
+ include_files_base_dir: Optional base directory for `include_files`. Relative
2881
+ paths are resolved from the working directory when the bundle is created.
2882
+ Defaults to the flow file's directory.
2883
+
2884
+ Returns:
2885
+ An infrastructure-bound copy of the flow.
2886
+ """
2843
2887
  new = InfrastructureBoundFlow[P, R](
2844
2888
  flow.fn,
2845
2889
  work_pool=work_pool,
@@ -2847,6 +2891,7 @@ def bind_flow_to_infrastructure(
2847
2891
  worker_cls=worker_cls,
2848
2892
  launcher=launcher,
2849
2893
  include_files=include_files,
2894
+ include_files_base_dir=include_files_base_dir,
2850
2895
  )
2851
2896
  # Copy all attributes from the original flow
2852
2897
  for attr, value in flow.__dict__.items():
@@ -2856,6 +2901,9 @@ def bind_flow_to_infrastructure(
2856
2901
  new.worker_cls = worker_cls
2857
2902
  new.launcher = normalize_launcher(launcher)
2858
2903
  new.include_files = list(include_files) if include_files is not None else None
2904
+ new.include_files_base_dir = (
2905
+ str(include_files_base_dir) if include_files_base_dir is not None else None
2906
+ )
2859
2907
  return new
2860
2908
 
2861
2909
 
@@ -9,7 +9,7 @@ import traceback
9
9
  import uuid
10
10
  import warnings
11
11
  from contextlib import asynccontextmanager
12
- from typing import TYPE_CHECKING, Any, Callable, Dict, TextIO, Type
12
+ from typing import TYPE_CHECKING, Any, Callable, Dict, TextIO, Type, cast
13
13
 
14
14
  from rich.console import Console
15
15
  from rich.highlighter import Highlighter, NullHighlighter
@@ -334,8 +334,29 @@ class _SafeStreamHandler(StreamHandler):
334
334
  it to handleError(), which prints a noisy traceback to sys.stderr. We
335
335
  suppress that for ValueError so background threads logging after stream
336
336
  teardown stay silent.
337
+
338
+ Context-managed locking also prevents asynchronous cancellation from
339
+ leaving the handler locked on Python 3.12 and earlier.
337
340
  """
338
341
 
342
+ def handle(self, record: logging.LogRecord) -> bool:
343
+ filtered = self.filter(record)
344
+ if isinstance(filtered, logging.LogRecord):
345
+ record = filtered
346
+ if filtered:
347
+ lock = self.lock
348
+ assert lock is not None
349
+ with lock:
350
+ self.emit(record)
351
+ return cast(bool, filtered)
352
+
353
+ def flush(self) -> None:
354
+ lock = self.lock
355
+ assert lock is not None
356
+ with lock:
357
+ if self.stream and hasattr(self.stream, "flush"):
358
+ self.stream.flush()
359
+
339
360
  def handleError(self, record: logging.LogRecord) -> None:
340
361
  _, exc, _ = sys.exc_info()
341
362
  if isinstance(exc, ValueError) and "closed file" in str(exc):
@@ -23,7 +23,7 @@ Thin facade over single-responsibility extracted classes. New behavior belongs i
23
23
  | FlowRunExecutorContext | _flow_run_executor.py | Async context manager for one-shot execution outside Runner (workers, CLI, bundles) |
24
24
  | DirectSubprocessStarter | _starter_direct.py | Runs Flow object via run_flow_in_subprocess |
25
25
  | EngineCommandStarter | _starter_engine.py | Spawns `python -m prefect.engine` subprocess |
26
- | WorkspaceResolvingEngineCommandStarter | _workspace_starter.py | Resolves workspace (pull steps) via `_workspace_resolver` subprocess then delegates to EngineCommandStarter; used by `prefect flow-run execute` |
26
+ | WorkspaceResolvingEngineCommandStarter | _workspace_starter.py | Starts a managed supervisor that prepares the workspace, launches the selected engine command, and records the prepared runtime for hooks |
27
27
  | BundleExecutionStarter | _starter_bundle.py | Executes serialized bundle in SpawnProcess |
28
28
 
29
29
  ## Key Contracts
@@ -45,7 +45,7 @@ Thin facade over single-responsibility extracted classes. New behavior belongs i
45
45
  - `execute_bundle()` -- deprecated (Mar 2026); use `execute_bundle()` from `prefect.bundles.execute`
46
46
  - `reschedule_current_flow_runs()` -- deprecated (Mar 2026); SIGTERM rescheduling is now handled inline by the CLI execute path
47
47
 
48
- These will be removed once internal callers are migrated. Direct ProcessWorker flow runs already use `FlowRunExecutorContext` with `EngineCommandStarter`; only its ad hoc bundle path still calls deprecated `Runner.execute_bundle()`. Keep lifecycle behavior in the extracted classes and do not route direct worker execution back through Runner.
48
+ These will be removed once internal callers are migrated. Direct ProcessWorker flow runs already use `FlowRunExecutorContext`; generated commands use `WorkspaceResolvingEngineCommandStarter`, while explicitly configured commands use `EngineCommandStarter`. Only the ad hoc bundle path still calls deprecated `Runner.execute_bundle()`. Keep lifecycle behavior in the extracted classes and do not route direct worker execution back through Runner.
49
49
 
50
50
  ## EventEmitter WebSocket Degradation
51
51
 
@@ -108,7 +108,7 @@ The cancelling precheck (step 1a) still runs unconditionally even when `propose_
108
108
 
109
109
  ## ProcessWorker Execution Paths
110
110
 
111
- Direct ProcessWorker runs use `FlowRunExecutorContext` with `EngineCommandStarter` and `propose_submitting=False`. The executor owns process tracking, cancellation, Attempt Control Session evidence, crash inference, and normalized infrastructure status. Ad hoc ProcessWorker submissions still call deprecated `Runner.execute_bundle()` and remain a migration target.
111
+ Direct ProcessWorker runs use `FlowRunExecutorContext` with `propose_submitting=False`. Generated commands use `WorkspaceResolvingEngineCommandStarter` so command selection follows workspace preparation; explicitly configured commands use `EngineCommandStarter` and retain their own pull-step semantics. The executor owns process tracking, cancellation, Attempt Control Session evidence, crash inference, and normalized infrastructure status. Ad hoc ProcessWorker submissions still call deprecated `Runner.execute_bundle()` and remain a migration target.
112
112
 
113
113
  ## BlockStorageAdapter Pull Behavior
114
114
 
@@ -133,19 +133,19 @@ These validations exist to prevent git argument injection. Do not bypass them wh
133
133
 
134
134
  ## Workspace Resolver Subprocess
135
135
 
136
- `_workspace_resolver.py` prepares a flow run workspace in an isolated subprocess (storage pull, pull steps, CWD/env/sys.path capture). Runs as `python -m prefect.runner._workspace_resolver`.
136
+ `_workspace_resolver.py` prepares a flow run workspace inside the managed workspace supervisor (storage pull, pull steps, and CWD/environment/sys.path capture).
137
137
 
138
138
  **Stdout is reserved for the JSON `PreparedWorkspaceResult` payload only.** Pull step output (including inherited stdout from child processes) is redirected to stderr. Parse `process.stdout` for the result, `process.stderr` for diagnostics. Violating this breaks callers silently.
139
139
 
140
- **Caller-facing API:** Use `WorkspaceResolvingEngineCommandStarter` (`_workspace_starter.py`) rather than calling the resolver directly. It wraps the subprocess call, memoizes the resolved workspace (one subprocess call per starter instance), and provides `resolve_flow()` that loads the flow inside the resolved workspace context. Pass `starter.resolve_flow` as the `resolve_flow` argument to `FlowRunExecutorContext.create_executor()` using a separate lambda bypasses the workspace context and will fail to find the flow.
140
+ **Caller-facing API:** Use `WorkspaceResolvingEngineCommandStarter` (`_workspace_starter.py`) rather than calling the resolver directly when the caller owns workspace preparation. Pass `starter.hook_runner` as the `hook_runner` argument to `FlowRunExecutorContext.create_executor()`. The hook runner reads the prepared runtime manifest and loads hooks in a subprocess using the same command prefix, working directory, and environment as the engine. Treat explicitly configured commands as opaque; ProcessWorker launches them with `EngineCommandStarter` so their existing pull behavior is not duplicated.
141
141
 
142
- **Env/sys.path isolation:** `_prepared_workspace_context` mutates `os.environ` and `sys.path` in the caller process but does NOT change `os.getcwd()`. The parent working directory is preserved.
142
+ **Environment isolation:** Workspace preparation, engine execution, and hook loading stay in child processes. Do not install a prepared workspace's environment, CWD, or `sys.path` in the long-lived runner process.
143
143
 
144
144
  **Local path in-place execution:** When no pull steps are configured and the entrypoint file exists at `deployment.path` but not in the workspace root, `prepare_workspace` sets `working_directory` to the local path — not under `workspace_root`. The workspace directory is still created but is not the execution root. This is the "image-baked" pattern: code lives at a fixed local path (e.g., inside a container), not in object storage.
145
145
 
146
146
  **Pull-step directory fallback:** When pull steps run but none produces a `directory` output or changes CWD, `_ensure_entrypoint_in_workspace` copies storage into the workspace root as a fallback. This handles setup-only pull steps (e.g., `run_shell_script` for environment prep) that do not control the working directory themselves.
147
147
 
148
- **Automatic dependency installation:** By default, `WorkspaceResolvingEngineCommandStarter` does not install dependencies before starting a flow run. When no explicit command is passed and `PREFECT_RUNNER_AUTO_INSTALL_DEPENDENCIES` is true, it auto-selects `uv run --no-default-groups --project <project_root> -m prefect.flow_engine` — but only when all three conditions hold: `pyproject.toml` exists at `project_root`, the `project.dependencies` list includes `prefect`, and `uv` is found via the workspace's `PATH` env var (not the system PATH). If the setting is false or any condition fails, the command falls back to `None`. Explicit commands always take precedence.
148
+ **Automatic dependency installation:** By default, `WorkspaceResolvingEngineCommandStarter` does not install dependencies before starting a flow run. When no explicit command is passed and `PREFECT_RUNNER_AUTO_INSTALL_DEPENDENCIES` is true, it auto-selects `uv run --no-default-groups --project <project_root>` with the worker-supplied workspace bootstrap — but only when all three conditions hold: `pyproject.toml` exists at `project_root`, the `project.dependencies` list includes `prefect`, and `uv` is found via the workspace's `PATH` env var (not the system PATH). The bootstrap uses the prepared entrypoint with `prefect.flow_engine` when that module exposes its executable `_main`; older selected runtimes fall back to `prefect.engine` with `PREFECT__FLOW_ENTRYPOINT`, preserving the prepared workspace. If the setting is false or any condition fails, the command falls back to `None`. Explicit commands always take precedence.
149
149
 
150
150
  ## Reference
151
151
 
@@ -19,7 +19,7 @@ if TYPE_CHECKING:
19
19
  from prefect.client.schemas.objects import FlowRun
20
20
  from prefect.runner._control_channel import ControlChannel
21
21
  from prefect.runner._event_emitter import EventEmitter
22
- from prefect.runner._hook_runner import HookRunner
22
+ from prefect.runner._hook_runner import FlowRunHookRunner
23
23
  from prefect.runner._process_manager import ProcessManager
24
24
  from prefect.runner._state_proposer import StateProposer
25
25
 
@@ -42,7 +42,7 @@ class CancellationManager:
42
42
  self,
43
43
  *,
44
44
  process_manager: ProcessManager,
45
- hook_runner: HookRunner,
45
+ hook_runner: FlowRunHookRunner,
46
46
  state_proposer: StateProposer,
47
47
  event_emitter: EventEmitter,
48
48
  client: PrefectClient,
@@ -18,7 +18,7 @@ from prefect.logging import get_logger
18
18
  from prefect.runner._cancellation_manager import CancellationManager
19
19
  from prefect.runner._control_channel import ControlChannel
20
20
  from prefect.runner._event_emitter import EventEmitter
21
- from prefect.runner._hook_runner import HookRunner
21
+ from prefect.runner._hook_runner import FlowRunHookRunner, HookRunner
22
22
  from prefect.runner._process_manager import ProcessHandle, ProcessManager
23
23
  from prefect.runner._state_proposer import StateProposer
24
24
  from prefect.settings.context import get_current_settings
@@ -94,7 +94,7 @@ class FlowRunExecutor:
94
94
  starter: ProcessStarter,
95
95
  process_manager: ProcessManager,
96
96
  state_proposer: StateProposer,
97
- hook_runner: HookRunner,
97
+ hook_runner: FlowRunHookRunner,
98
98
  get_attempt_conclusion: Callable[[UUID], AttemptConclusion | None],
99
99
  propose_submitting: bool = True,
100
100
  ) -> None:
@@ -267,6 +267,7 @@ class FlowRunExecutorContext:
267
267
  async def __aenter__(self) -> FlowRunExecutorContext:
268
268
  self._stack = AsyncExitStack()
269
269
  await self._stack.__aenter__()
270
+ self._after_exit_callbacks: list[Callable[[], object]] = []
270
271
  self._logger = get_logger("runner.executor_context")
271
272
 
272
273
  # Step 1: client
@@ -339,7 +340,15 @@ class FlowRunExecutorContext:
339
340
  exc_value: BaseException | None,
340
341
  traceback: TracebackType | None,
341
342
  ) -> bool | None:
342
- return await self._stack.__aexit__(exc_type, exc_value, traceback)
343
+ try:
344
+ return await self._stack.__aexit__(exc_type, exc_value, traceback)
345
+ finally:
346
+ for callback in reversed(self._after_exit_callbacks):
347
+ callback()
348
+
349
+ def call_after_exit(self, callback: Callable[[], object]) -> None:
350
+ """Keep attempt resources alive until cancellation work has drained."""
351
+ self._after_exit_callbacks.append(callback)
343
352
 
344
353
  def _handle_cancellation_observer_failure(self, flow_run_ids: set) -> None:
345
354
  """Handle failure of both cancellation observer mechanisms.
@@ -369,10 +378,15 @@ class FlowRunExecutorContext:
369
378
  self,
370
379
  flow_run: FlowRun,
371
380
  starter: ProcessStarter,
372
- resolve_flow: Callable[[FlowRun], Awaitable[Flow[Any, Any]]],
381
+ resolve_flow: Callable[[FlowRun], Awaitable[Flow[Any, Any]]] | None = None,
373
382
  propose_submitting: bool = True,
383
+ hook_runner: FlowRunHookRunner | None = None,
374
384
  ) -> FlowRunExecutor:
375
- hook_runner = HookRunner(resolve_flow=resolve_flow)
385
+ if (resolve_flow is None) == (hook_runner is None):
386
+ raise ValueError("Provide exactly one of resolve_flow or hook_runner.")
387
+ if hook_runner is None:
388
+ assert resolve_flow is not None
389
+ hook_runner = HookRunner(resolve_flow=resolve_flow)
376
390
  # Wire the real resolver into CancellationManager for on_cancellation hooks
377
391
  self._cancellation_manager._hook_runner = hook_runner
378
392
  return FlowRunExecutor(
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Any, Awaitable, Callable
3
+ from typing import TYPE_CHECKING, Any, Awaitable, Callable, Protocol
4
4
 
5
5
  from prefect._internal.concurrency.api import create_call, from_async
6
6
  from prefect._internal.engine import get_hook_name
@@ -13,6 +13,12 @@ if TYPE_CHECKING:
13
13
  from prefect.states import State
14
14
 
15
15
 
16
+ class FlowRunHookRunner(Protocol):
17
+ async def run_cancellation_hooks(self, flow_run: FlowRun, state: State) -> None: ...
18
+
19
+ async def run_crashed_hooks(self, flow_run: FlowRun, state: State) -> None: ...
20
+
21
+
16
22
  async def _run_hooks(
17
23
  hooks: list[Any],
18
24
  flow_run: FlowRun,