prefect-client 3.6.30.dev1__tar.gz → 3.6.30.dev3__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 (426) hide show
  1. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/.gitignore +2 -0
  2. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/PKG-INFO +1 -1
  3. prefect_client-3.6.30.dev3/hatch_build.py +61 -0
  4. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/AGENTS.md +1 -1
  5. prefect_client-3.6.30.dev3/src/prefect/_build_info.py +5 -0
  6. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/__init__.py +42 -0
  7. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/routes.py +1 -0
  8. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/schemas/objects.py +18 -0
  9. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/deployments/AGENTS.md +2 -0
  10. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/deployments/steps/core.py +43 -0
  11. prefect_client-3.6.30.dev3/src/prefect/locking/_filelock.py +242 -0
  12. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/AGENTS.md +16 -1
  13. prefect_client-3.6.30.dev3/src/prefect/runner/_workspace_resolver.py +360 -0
  14. prefect_client-3.6.30.dev3/src/prefect/runner/_workspace_starter.py +217 -0
  15. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/storage.py +17 -0
  16. prefect_client-3.6.30.dev3/src/prefect/server/api/admin.py +85 -0
  17. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/server.py +252 -60
  18. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/ui.py +1 -1
  19. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/templating/__init__.py +64 -39
  20. prefect_client-3.6.30.dev1/src/prefect/_build_info.py +0 -5
  21. prefect_client-3.6.30.dev1/src/prefect/server/api/admin.py +0 -25
  22. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/LICENSE +0 -0
  23. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/README.md +0 -0
  24. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/pyproject.toml +0 -0
  25. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/.prefectignore +0 -0
  26. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/__init__.py +0 -0
  27. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/__main__.py +0 -0
  28. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/__init__.py +0 -0
  29. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/_launchers.py +0 -0
  30. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/bundles/__init__.py +0 -0
  31. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/bundles/_file_collector.py +0 -0
  32. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/bundles/_ignore_filter.py +0 -0
  33. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/bundles/_path_resolver.py +0 -0
  34. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/bundles/_zip_builder.py +0 -0
  35. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/bundles/_zip_extractor.py +0 -0
  36. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/bundles/execute.py +0 -0
  37. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/plugins/__init__.py +0 -0
  38. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/plugins/apply.py +0 -0
  39. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/plugins/diagnostics.py +0 -0
  40. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/plugins/manager.py +0 -0
  41. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/plugins/spec.py +0 -0
  42. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/sla/__init__.py +0 -0
  43. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/sla/client.py +0 -0
  44. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_experimental/sla/objects.py +0 -0
  45. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/__init__.py +0 -0
  46. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/_logging.py +0 -0
  47. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/__init__.py +0 -0
  48. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/ci_detection.py +0 -0
  49. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/client.py +0 -0
  50. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/device_id.py +0 -0
  51. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/emit.py +0 -0
  52. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/enabled.py +0 -0
  53. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/events.py +0 -0
  54. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/milestones.py +0 -0
  55. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/notice.py +0 -0
  56. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/analytics/service.py +0 -0
  57. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/compatibility/__init__.py +0 -0
  58. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/compatibility/async_dispatch.py +0 -0
  59. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/compatibility/backports.py +0 -0
  60. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/compatibility/blocks.py +0 -0
  61. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/compatibility/deprecated.py +0 -0
  62. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/compatibility/migration.py +0 -0
  63. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/compatibility/starlette.py +0 -0
  64. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/__init__.py +0 -0
  65. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/api.py +0 -0
  66. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/calls.py +0 -0
  67. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/cancellation.py +0 -0
  68. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/event_loop.py +0 -0
  69. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/inspection.py +0 -0
  70. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/primitives.py +0 -0
  71. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/services.py +0 -0
  72. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/threads.py +0 -0
  73. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/concurrency/waiters.py +0 -0
  74. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/control_listener.py +0 -0
  75. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/installation.py +0 -0
  76. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/integrations.py +0 -0
  77. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/lazy.py +0 -0
  78. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/observability.py +0 -0
  79. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/pydantic/__init__.py +0 -0
  80. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/pydantic/schemas.py +0 -0
  81. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/pydantic/v1_schema.py +0 -0
  82. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/pydantic/v2_schema.py +0 -0
  83. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/pydantic/validated_func.py +0 -0
  84. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/pytz.py +0 -0
  85. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/retries.py +0 -0
  86. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/schemas/__init__.py +0 -0
  87. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/schemas/bases.py +0 -0
  88. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/schemas/fields.py +0 -0
  89. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/schemas/serializers.py +0 -0
  90. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/schemas/validators.py +0 -0
  91. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/send_entrypoint_logs.py +0 -0
  92. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/testing.py +0 -0
  93. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/urls.py +0 -0
  94. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/uuid7.py +0 -0
  95. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_internal/websockets.py +0 -0
  96. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_observers.py +0 -0
  97. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_result_records.py +0 -0
  98. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/__init__.py +0 -0
  99. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/fetcher.py +0 -0
  100. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/generator.py +0 -0
  101. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/models.py +0 -0
  102. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/naming.py +0 -0
  103. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/renderer.py +0 -0
  104. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/schema_converter.py +0 -0
  105. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/templates/__init__.py +0 -0
  106. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/templates/sdk.py.jinja +0 -0
  107. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/types.py +0 -0
  108. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_sdk/unions.py +0 -0
  109. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_states.py +0 -0
  110. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_vendor/croniter/__init__.py +0 -0
  111. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_vendor/croniter/croniter.py +0 -0
  112. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_versioning.py +0 -0
  113. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/_waiters.py +0 -0
  114. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/agent.py +0 -0
  115. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/analytics/__init__.py +0 -0
  116. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/artifacts.py +0 -0
  117. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/assets/__init__.py +0 -0
  118. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/assets/core.py +0 -0
  119. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/assets/materialize.py +0 -0
  120. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/automations.py +0 -0
  121. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/blocks/AGENTS.md +0 -0
  122. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/blocks/__init__.py +0 -0
  123. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/blocks/abstract.py +0 -0
  124. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/blocks/core.py +0 -0
  125. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/blocks/fields.py +0 -0
  126. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/blocks/notifications.py +0 -0
  127. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/blocks/redis.py +0 -0
  128. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/blocks/system.py +0 -0
  129. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/blocks/webhook.py +0 -0
  130. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/cache_policies.py +0 -0
  131. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/AGENTS.md +0 -0
  132. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/__init__.py +0 -0
  133. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/_version_checking.py +0 -0
  134. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/attribution.py +0 -0
  135. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/base.py +0 -0
  136. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/cloud.py +0 -0
  137. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/collections.py +0 -0
  138. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/constants.py +0 -0
  139. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_artifacts/__init__.py +0 -0
  140. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_artifacts/client.py +0 -0
  141. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_automations/__init__.py +0 -0
  142. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_automations/client.py +0 -0
  143. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_blocks_documents/__init__.py +0 -0
  144. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_blocks_documents/client.py +0 -0
  145. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_blocks_schemas/__init__.py +0 -0
  146. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_blocks_schemas/client.py +0 -0
  147. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_blocks_types/__init__.py +0 -0
  148. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_blocks_types/client.py +0 -0
  149. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_concurrency_limits/__init__.py +0 -0
  150. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_concurrency_limits/client.py +0 -0
  151. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_deployments/__init__.py +0 -0
  152. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_deployments/client.py +0 -0
  153. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_events/__init__.py +0 -0
  154. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_events/client.py +0 -0
  155. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_flow_runs/__init__.py +0 -0
  156. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_flow_runs/client.py +0 -0
  157. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_flows/__init__.py +0 -0
  158. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_flows/client.py +0 -0
  159. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_logs/__init__.py +0 -0
  160. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_logs/client.py +0 -0
  161. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_variables/__init__.py +0 -0
  162. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_variables/client.py +0 -0
  163. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_work_pools/__init__.py +0 -0
  164. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/_work_pools/client.py +0 -0
  165. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/orchestration/base.py +0 -0
  166. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/schemas/__init__.py +0 -0
  167. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/schemas/actions.py +0 -0
  168. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/schemas/events.py +0 -0
  169. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/schemas/filters.py +0 -0
  170. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/schemas/responses.py +0 -0
  171. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/schemas/schedules.py +0 -0
  172. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/schemas/sorting.py +0 -0
  173. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/subscriptions.py +0 -0
  174. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/types/__init__.py +0 -0
  175. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/types/flexible_schedule_list.py +0 -0
  176. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/client/utilities.py +0 -0
  177. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/AGENTS.md +0 -0
  178. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/__init__.py +0 -0
  179. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/_asyncio.py +0 -0
  180. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/_events.py +0 -0
  181. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/_leases.py +0 -0
  182. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/_sync.py +0 -0
  183. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/asyncio.py +0 -0
  184. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/context.py +0 -0
  185. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/services.py +0 -0
  186. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/sync.py +0 -0
  187. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/v1/__init__.py +0 -0
  188. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/v1/_asyncio.py +0 -0
  189. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/v1/_events.py +0 -0
  190. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/v1/asyncio.py +0 -0
  191. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/v1/context.py +0 -0
  192. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/v1/services.py +0 -0
  193. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/concurrency/v1/sync.py +0 -0
  194. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/context.py +0 -0
  195. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/deployments/__init__.py +0 -0
  196. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/deployments/base.py +0 -0
  197. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/deployments/deployments.py +0 -0
  198. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/deployments/flow_runs.py +0 -0
  199. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/deployments/runner.py +0 -0
  200. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/deployments/schedules.py +0 -0
  201. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/deployments/steps/__init__.py +0 -0
  202. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/deployments/steps/pull.py +0 -0
  203. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/deployments/steps/utility.py +0 -0
  204. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/docker/__init__.py +0 -0
  205. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/docker/_buildx.py +0 -0
  206. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/docker/docker_image.py +0 -0
  207. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/engine.py +0 -0
  208. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/events/AGENTS.md +0 -0
  209. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/events/__init__.py +0 -0
  210. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/events/actions.py +0 -0
  211. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/events/clients.py +0 -0
  212. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/events/filters.py +0 -0
  213. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/events/related.py +0 -0
  214. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/events/schemas/__init__.py +0 -0
  215. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/events/schemas/automations.py +0 -0
  216. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/events/schemas/deployment_triggers.py +0 -0
  217. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/events/schemas/events.py +0 -0
  218. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/events/schemas/labelling.py +0 -0
  219. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/events/subscribers.py +0 -0
  220. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/events/utilities.py +0 -0
  221. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/events/worker.py +0 -0
  222. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/exceptions.py +0 -0
  223. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/filesystems.py +0 -0
  224. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/flow_engine.py +0 -0
  225. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/flow_runs.py +0 -0
  226. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/flows.py +0 -0
  227. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/futures.py +0 -0
  228. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/infrastructure/__init__.py +0 -0
  229. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/infrastructure/base.py +0 -0
  230. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/infrastructure/provisioners/__init__.py +0 -0
  231. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/infrastructure/provisioners/cloud_run.py +0 -0
  232. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/infrastructure/provisioners/coiled.py +0 -0
  233. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/infrastructure/provisioners/container_instance.py +0 -0
  234. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/infrastructure/provisioners/ecs.py +0 -0
  235. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/infrastructure/provisioners/modal.py +0 -0
  236. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/input/__init__.py +0 -0
  237. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/input/actions.py +0 -0
  238. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/input/run_input.py +0 -0
  239. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/locking/__init__.py +0 -0
  240. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/locking/filesystem.py +0 -0
  241. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/locking/memory.py +0 -0
  242. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/locking/protocol.py +0 -0
  243. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/logging/AGENTS.md +0 -0
  244. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/logging/__init__.py +0 -0
  245. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/logging/clients.py +0 -0
  246. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/logging/configuration.py +0 -0
  247. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/logging/filters.py +0 -0
  248. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/logging/formatters.py +0 -0
  249. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/logging/handlers.py +0 -0
  250. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/logging/highlighters.py +0 -0
  251. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/logging/loggers.py +0 -0
  252. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/logging/logging.yml +0 -0
  253. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/main.py +0 -0
  254. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/plugins.py +0 -0
  255. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/py.typed +0 -0
  256. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/results.py +0 -0
  257. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/__init__.py +0 -0
  258. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/_cancel_finalizer.py +0 -0
  259. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/_cancellation_manager.py +0 -0
  260. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/_control_channel.py +0 -0
  261. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/_deployment_registry.py +0 -0
  262. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/_event_emitter.py +0 -0
  263. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/_flow_resolver.py +0 -0
  264. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/_flow_run_executor.py +0 -0
  265. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/_hook_runner.py +0 -0
  266. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/_limit_manager.py +0 -0
  267. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/_process_manager.py +0 -0
  268. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/_scheduled_run_poller.py +0 -0
  269. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/_starter_bundle.py +0 -0
  270. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/_starter_direct.py +0 -0
  271. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/_starter_engine.py +0 -0
  272. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/_state_proposer.py +0 -0
  273. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/runner.py +0 -0
  274. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runner/server.py +0 -0
  275. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runtime/__init__.py +0 -0
  276. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runtime/deployment.py +0 -0
  277. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runtime/flow_run.py +0 -0
  278. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/runtime/task_run.py +0 -0
  279. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/schedules.py +0 -0
  280. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/serializers.py +0 -0
  281. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/__init__.py +0 -0
  282. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/artifacts.py +0 -0
  283. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/automations.py +0 -0
  284. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/background_workers.py +0 -0
  285. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/block_capabilities.py +0 -0
  286. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/block_documents.py +0 -0
  287. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/block_schemas.py +0 -0
  288. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/block_types.py +0 -0
  289. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/clients.py +0 -0
  290. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/collections.py +0 -0
  291. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/collections_data/views/aggregate-worker-metadata.json +0 -0
  292. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/concurrency_limits.py +0 -0
  293. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/concurrency_limits_v2.py +0 -0
  294. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/csrf_token.py +0 -0
  295. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/dependencies.py +0 -0
  296. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/deployments.py +0 -0
  297. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/events.py +0 -0
  298. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/flow_run_states.py +0 -0
  299. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/flow_runs.py +0 -0
  300. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/flows.py +0 -0
  301. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/logs.py +0 -0
  302. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/middleware.py +0 -0
  303. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/root.py +0 -0
  304. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/run_history.py +0 -0
  305. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/saved_searches.py +0 -0
  306. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/static/prefect-logo-mark-gradient.png +0 -0
  307. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/task_run_states.py +0 -0
  308. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/task_runs.py +0 -0
  309. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/task_workers.py +0 -0
  310. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/templates.py +0 -0
  311. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/ui/__init__.py +0 -0
  312. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/ui/flow_runs.py +0 -0
  313. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/ui/flows.py +0 -0
  314. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/ui/schemas.py +0 -0
  315. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/ui/task_runs.py +0 -0
  316. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/validation.py +0 -0
  317. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/variables.py +0 -0
  318. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/work_queues.py +0 -0
  319. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/server/api/workers.py +0 -0
  320. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/AGENTS.md +0 -0
  321. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/__init__.py +0 -0
  322. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/base.py +0 -0
  323. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/constants.py +0 -0
  324. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/context.py +0 -0
  325. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/legacy.py +0 -0
  326. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/__init__.py +0 -0
  327. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/_defaults.py +0 -0
  328. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/api.py +0 -0
  329. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/cli.py +0 -0
  330. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/client.py +0 -0
  331. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/cloud.py +0 -0
  332. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/deployments.py +0 -0
  333. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/events.py +0 -0
  334. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/experiments.py +0 -0
  335. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/flows.py +0 -0
  336. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/internal.py +0 -0
  337. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/logging.py +0 -0
  338. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/results.py +0 -0
  339. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/root.py +0 -0
  340. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/runner.py +0 -0
  341. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/__init__.py +0 -0
  342. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/api.py +0 -0
  343. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/concurrency.py +0 -0
  344. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/database.py +0 -0
  345. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/deployments.py +0 -0
  346. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/docket.py +0 -0
  347. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/ephemeral.py +0 -0
  348. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/events.py +0 -0
  349. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/flow_run_graph.py +0 -0
  350. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/logs.py +0 -0
  351. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/root.py +0 -0
  352. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/services.py +0 -0
  353. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/server/tasks.py +0 -0
  354. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/tasks.py +0 -0
  355. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/telemetry.py +0 -0
  356. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/testing.py +0 -0
  357. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/models/worker.py +0 -0
  358. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/profiles.py +0 -0
  359. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/profiles.toml +0 -0
  360. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/settings/sources.py +0 -0
  361. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/states.py +0 -0
  362. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/task_engine.py +0 -0
  363. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/task_runners.py +0 -0
  364. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/task_runs.py +0 -0
  365. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/task_worker.py +0 -0
  366. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/tasks.py +0 -0
  367. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/telemetry/__init__.py +0 -0
  368. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/telemetry/_metrics.py +0 -0
  369. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/telemetry/run_telemetry.py +0 -0
  370. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/transactions.py +0 -0
  371. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/types/__init__.py +0 -0
  372. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/types/_concurrency.py +0 -0
  373. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/types/_datetime.py +0 -0
  374. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/types/_schema.py +0 -0
  375. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/types/entrypoint.py +0 -0
  376. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/types/names.py +0 -0
  377. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/AGENTS.md +0 -0
  378. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/__init__.py +0 -0
  379. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/_ast.py +0 -0
  380. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/_deprecated.py +0 -0
  381. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/_engine.py +0 -0
  382. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/_git.py +0 -0
  383. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/_infrastructure_exit_codes.py +0 -0
  384. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/annotations.py +0 -0
  385. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/asyncutils/AGENTS.md +0 -0
  386. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/asyncutils/__init__.py +0 -0
  387. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/callables/AGENTS.md +0 -0
  388. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/callables/__init__.py +0 -0
  389. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/collections.py +0 -0
  390. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/compat.py +0 -0
  391. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/context.py +0 -0
  392. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/dispatch.py +0 -0
  393. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/dockerutils.py +0 -0
  394. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/engine/AGENTS.md +0 -0
  395. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/engine/__init__.py +0 -0
  396. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/filesystem/AGENTS.md +0 -0
  397. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/filesystem/__init__.py +0 -0
  398. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/generics.py +0 -0
  399. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/hashing.py +0 -0
  400. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/importtools.py +0 -0
  401. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/math.py +0 -0
  402. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/names.py +0 -0
  403. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/processutils/AGENTS.md +0 -0
  404. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/processutils/__init__.py +0 -0
  405. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/pydantic.py +0 -0
  406. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/render_swagger.py +0 -0
  407. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/schema_tools/AGENTS.md +0 -0
  408. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/schema_tools/__init__.py +0 -0
  409. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/schema_tools/hydration.py +0 -0
  410. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/schema_tools/validation.py +0 -0
  411. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/services.py +0 -0
  412. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/slugify.py +0 -0
  413. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/templating/AGENTS.md +0 -0
  414. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/text.py +0 -0
  415. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/timeout.py +0 -0
  416. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/urls.py +0 -0
  417. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/utilities/visualization.py +0 -0
  418. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/variables.py +0 -0
  419. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/workers/AGENTS.md +0 -0
  420. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/workers/__init__.py +0 -0
  421. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/workers/base.py +0 -0
  422. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/workers/block.py +0 -0
  423. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/workers/cloud.py +0 -0
  424. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/workers/process.py +0 -0
  425. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/workers/server.py +0 -0
  426. {prefect_client-3.6.30.dev1 → prefect_client-3.6.30.dev3}/src/prefect/workers/utilities.py +0 -0
@@ -54,6 +54,8 @@ src/mkdocs-material
54
54
  # UI artifacts
55
55
  src/prefect/server/ui/*
56
56
  src/prefect/server/ui_build/*
57
+ src/prefect/server/ui-v2/*
58
+ src/prefect/server/ui_v2_build/*
57
59
  **/node_modules
58
60
 
59
61
  # Databases
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: prefect-client
3
- Version: 3.6.30.dev1
3
+ Version: 3.6.30.dev3
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
@@ -0,0 +1,61 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ from pathlib import Path
5
+ from typing import Any
6
+
7
+ try:
8
+ from hatchling.builders.hooks.plugin.interface import BuildHookInterface
9
+ except ModuleNotFoundError: # pragma: no cover - only used when testing helpers
10
+
11
+ class BuildHookInterface: # type: ignore[no-redef]
12
+ root: str
13
+ target_name: str
14
+
15
+
16
+ PACKAGED_UI_INDEX_FILES = (
17
+ Path("src/prefect/server/ui/index.html"),
18
+ Path("src/prefect/server/ui-v2/index.html"),
19
+ )
20
+ REQUIRE_PACKAGED_UI_ENV_VAR = "PREFECT_REQUIRE_PACKAGED_UI_BUNDLES"
21
+
22
+
23
+ def _truthy_env_var(name: str) -> bool:
24
+ return os.environ.get(name, "").lower() not in {"", "0", "false", "no", "off"}
25
+
26
+
27
+ def should_validate_packaged_ui_index_files(root: str | Path) -> bool:
28
+ if _truthy_env_var(REQUIRE_PACKAGED_UI_ENV_VAR):
29
+ return True
30
+
31
+ root_path = Path(root)
32
+ return any(
33
+ (root_path / index_file.parent).exists()
34
+ for index_file in PACKAGED_UI_INDEX_FILES
35
+ )
36
+
37
+
38
+ def validate_packaged_ui_index_files(root: str | Path) -> None:
39
+ root_path = Path(root)
40
+ missing_index_files = [
41
+ str(index_file)
42
+ for index_file in PACKAGED_UI_INDEX_FILES
43
+ if not (root_path / index_file).is_file()
44
+ ]
45
+
46
+ if missing_index_files:
47
+ raise RuntimeError(
48
+ "Prefect package builds require both UI bundles to be built. "
49
+ "Missing index.html files: "
50
+ f"{', '.join(missing_index_files)}"
51
+ )
52
+
53
+
54
+ class CustomBuildHook(BuildHookInterface):
55
+ def initialize(self, version: str, build_data: dict[str, Any]) -> None:
56
+ if (
57
+ version != "editable"
58
+ and self.target_name in {"sdist", "wheel"}
59
+ and should_validate_packaged_ui_index_files(self.root)
60
+ ):
61
+ validate_packaged_ui_index_files(self.root)
@@ -21,7 +21,7 @@ There is no formal public/private boundary beyond the `_` prefix convention. Mod
21
21
 
22
22
  - **Engine ordering matters.** The engines apply features (retries, caching, result persistence, transactions) in a specific order. Changing the order or forgetting a feature in one engine path is the most common source of breakage.
23
23
  - **Sync and async must stay in sync.** Both `flow_engine.py` and `task_engine.py` have sync and async paths. Any behavior change must be applied to both.
24
- - **Use `whenever` compat helpers for all datetime conversions on Python 3.13+.** `types/_datetime.py` provides `_whenever_to_stdlib()`, `_whenever_zdt_from_py()`, and `_whenever_pdt_from_py()` to abstract over API differences between whenever 0.7.x–0.9.x and ≥ 0.10.0. The `_WHENEVER_NEW_API` flag (True when whenever ≥ 0.10.0) guards version-specific code. Never call `ZonedDateTime.from_py_datetime()`, `PlainDateTime.from_py_datetime()`, or `.py_datetime()` directly — use the helpers instead. Violations will silently break on whichever whenever version the helpers weren't written for.
24
+ - **Use `whenever` compat helpers for all datetime conversions on Python 3.13+.** `types/_datetime.py` provides `now()`, `_whenever_to_stdlib()`, `_whenever_zdt_from_py()`, and `_whenever_pdt_from_py()` to abstract over API differences between whenever 0.7.x–0.9.x and ≥ 0.10.0. The `_WHENEVER_NEW_API` flag (True when whenever ≥ 0.10.0) guards version-specific code. Never call `DateTime.now()` or `pendulum.now()` directly — use `now()` from `types/_datetime.py` instead. Never call `ZonedDateTime.from_py_datetime()`, `PlainDateTime.from_py_datetime()`, or `.py_datetime()` directly — use the helpers instead. Violations will silently break on whichever whenever version the helpers weren't written for.
25
25
  - **Flow and task engines advance state differently.** The flow engine makes blocking API calls to the server to propose and advance states. The task engine emits `prefect.task_run.*` events (delivered via WebSockets) but advances state locally through `set_state` calls with polling/backoff — do not assume the two engines work the same way.
26
26
  - **Flow state transitions go through the server.** The flow engine proposes states to the server, which accepts or rejects them via orchestration rules. The task engine, by contrast, manages state transitions locally via `set_state` and emits `prefect.task_run.*` events — it does not propose states to the server.
27
27
  - **`ProcessPoolTaskRunner` requires picklable data across subprocess boundaries.** `PrefectFuture` objects are not picklable and cannot be passed to worker subprocesses. Any `wait_for` futures must be waited on in the parent process and converted to `State` objects before submission. The subprocess task engine handles `State` objects via `resolve_to_final_result`, which raises `UpstreamTaskError` for non-completed upstreams.
@@ -0,0 +1,5 @@
1
+ # Generated by versioningit
2
+ __version__ = "3.6.30.dev3"
3
+ __build_date__ = "2026-05-05 08:51:50.984328+00:00"
4
+ __git_commit__ = "39cb01298f84ceabc816f0beb3696849f412d313"
5
+ __dirty__ = False
@@ -110,6 +110,8 @@ from prefect.client.schemas.objects import (
110
110
  FlowRunResult,
111
111
  Parameter,
112
112
  Constant,
113
+ ServerDefaultResultStorage,
114
+ ServerDefaultResultStorageUpdate,
113
115
  TaskRunPolicy,
114
116
  WorkQueue,
115
117
  WorkQueueStatusDetail,
@@ -1079,6 +1081,27 @@ class PrefectClient(
1079
1081
  res = await self._client.get("/admin/version")
1080
1082
  return res.json()
1081
1083
 
1084
+ async def read_server_default_result_storage(
1085
+ self,
1086
+ ) -> ServerDefaultResultStorage:
1087
+ response = await self._client.get("/admin/storage")
1088
+ return ServerDefaultResultStorage.model_validate(response.json())
1089
+
1090
+ async def update_server_default_result_storage(
1091
+ self,
1092
+ default_result_storage_block_id: UUID,
1093
+ ) -> ServerDefaultResultStorage:
1094
+ response = await self._client.put(
1095
+ "/admin/storage",
1096
+ json=ServerDefaultResultStorageUpdate(
1097
+ default_result_storage_block_id=default_result_storage_block_id
1098
+ ).model_dump(mode="json"),
1099
+ )
1100
+ return ServerDefaultResultStorage.model_validate(response.json())
1101
+
1102
+ async def clear_server_default_result_storage(self) -> None:
1103
+ await self._client.delete("/admin/storage")
1104
+
1082
1105
  def client_version(self) -> str:
1083
1106
  return prefect.__version__
1084
1107
 
@@ -1451,6 +1474,25 @@ class SyncPrefectClient(
1451
1474
  res = self._client.get("/admin/version")
1452
1475
  return res.json()
1453
1476
 
1477
+ def read_server_default_result_storage(self) -> ServerDefaultResultStorage:
1478
+ response = self._client.get("/admin/storage")
1479
+ return ServerDefaultResultStorage.model_validate(response.json())
1480
+
1481
+ def update_server_default_result_storage(
1482
+ self,
1483
+ default_result_storage_block_id: UUID,
1484
+ ) -> ServerDefaultResultStorage:
1485
+ response = self._client.put(
1486
+ "/admin/storage",
1487
+ json=ServerDefaultResultStorageUpdate(
1488
+ default_result_storage_block_id=default_result_storage_block_id
1489
+ ).model_dump(mode="json"),
1490
+ )
1491
+ return ServerDefaultResultStorage.model_validate(response.json())
1492
+
1493
+ def clear_server_default_result_storage(self) -> None:
1494
+ self._client.delete("/admin/storage")
1495
+
1454
1496
  def client_version(self) -> str:
1455
1497
  return prefect.__version__
1456
1498
 
@@ -1,6 +1,7 @@
1
1
  from typing import Literal
2
2
 
3
3
  ServerRoutes = Literal[
4
+ "/admin/storage",
4
5
  "/admin/settings",
5
6
  "/admin/version",
6
7
  "/artifacts/",
@@ -1550,6 +1550,24 @@ class WorkPoolStorageConfiguration(PrefectBaseModel):
1550
1550
  )
1551
1551
 
1552
1552
 
1553
+ class ServerDefaultResultStorage(PrefectBaseModel):
1554
+ """Server-side default result storage configuration."""
1555
+
1556
+ default_result_storage_block_id: Optional[UUID] = Field(
1557
+ default=None,
1558
+ description="The block document ID of the server default result storage block.",
1559
+ )
1560
+
1561
+
1562
+ class ServerDefaultResultStorageUpdate(PrefectBaseModel):
1563
+ """Request payload for setting the server default result storage block."""
1564
+
1565
+ default_result_storage_block_id: UUID = Field(
1566
+ default=...,
1567
+ description="The block document ID of the server default result storage block.",
1568
+ )
1569
+
1570
+
1553
1571
  class WorkPool(ObjectBaseModel):
1554
1572
  """An ORM representation of a work pool"""
1555
1573
 
@@ -23,6 +23,8 @@ Built-in steps:
23
23
  - `steps/pull.py` — `git_clone`, `set_working_directory`, `pull_from_remote_storage`
24
24
  - `steps/utility.py` — `run_shell_script`, `pip_install_requirements`
25
25
 
26
+ **Step observer**: `run_steps` does not accept a step completion callback as a parameter by design — inject one via `_observe_step_completion(callback)` context manager from `steps/core.py`. The callback receives `(step, output, cwd_before, cwd_after)` after each step; either CWD arg is `None` when the directory becomes inaccessible (e.g., the step deleted its working directory).
27
+
26
28
  ## Entrypoint Formats
27
29
 
28
30
  `runner.py`'s `from_storage` / `afrom_storage` (and `Flow.from_source`) support two entrypoint formats:
@@ -17,8 +17,12 @@ import os
17
17
  import re
18
18
  import subprocess
19
19
  import warnings
20
+ from collections.abc import Callable, Iterator
21
+ from contextlib import contextmanager
22
+ from contextvars import ContextVar
20
23
  from copy import deepcopy
21
24
  from importlib import import_module
25
+ from pathlib import Path
22
26
  from typing import Any
23
27
  from uuid import UUID
24
28
 
@@ -39,6 +43,15 @@ from prefect.utilities.templating import (
39
43
 
40
44
  RESERVED_KEYWORDS = {"id", "requires"}
41
45
 
46
+ _StepCompletionObserver = Callable[
47
+ [dict[str, Any], Any, Path | None, Path | None],
48
+ None,
49
+ ]
50
+ _STEP_COMPLETION_OBSERVER: ContextVar[_StepCompletionObserver | None] = ContextVar(
51
+ "step_completion_observer",
52
+ default=None,
53
+ )
54
+
42
55
 
43
56
  class StepExecutionError(Exception):
44
57
  """
@@ -46,6 +59,22 @@ class StepExecutionError(Exception):
46
59
  """
47
60
 
48
61
 
62
+ def _safe_current_working_directory() -> Path | None:
63
+ try:
64
+ return Path.cwd().resolve()
65
+ except OSError:
66
+ return None
67
+
68
+
69
+ @contextmanager
70
+ def _observe_step_completion(callback: _StepCompletionObserver) -> Iterator[None]:
71
+ token = _STEP_COMPLETION_OBSERVER.set(callback)
72
+ try:
73
+ yield
74
+ finally:
75
+ _STEP_COMPLETION_OBSERVER.reset(token)
76
+
77
+
49
78
  def _strip_version(requirement: str) -> str:
50
79
  """
51
80
  Strips the version from a requirement string.
@@ -152,6 +181,7 @@ async def run_steps(
152
181
  logger: Any | None = None,
153
182
  ) -> dict[str, Any]:
154
183
  upstream_outputs = deepcopy(upstream_outputs) if upstream_outputs else {}
184
+ step_completion_observer = _STEP_COMPLETION_OBSERVER.get()
155
185
  for step_index, step in enumerate(steps):
156
186
  if not step:
157
187
  continue
@@ -177,6 +207,11 @@ async def run_steps(
177
207
 
178
208
  try:
179
209
  # catch warnings to ensure deprecation warnings are printed
210
+ step_start_cwd = (
211
+ _safe_current_working_directory()
212
+ if step_completion_observer is not None
213
+ else None
214
+ )
180
215
  with warnings.catch_warnings(record=True) as w:
181
216
  warnings.simplefilter(
182
217
  "always",
@@ -201,6 +236,14 @@ async def run_steps(
201
236
  print_function(message)
202
237
  printed_messages.append(message)
203
238
 
239
+ if step_completion_observer is not None:
240
+ step_completion_observer(
241
+ step,
242
+ step_output,
243
+ step_start_cwd,
244
+ _safe_current_working_directory(),
245
+ )
246
+
204
247
  if not isinstance(step_output, dict):
205
248
  if PREFECT_DEBUG_MODE:
206
249
  get_logger().warning(
@@ -0,0 +1,242 @@
1
+ """Internal cross-platform file lock using lock file creation.
2
+
3
+ Uses the existence of a lock file to indicate the lock is held, following
4
+ the same pattern as FileSystemLockManager. The lock file is created
5
+ atomically and removed on release. No OS-specific locking primitives are
6
+ required.
7
+
8
+ The owning process's PID is written to the lock file so that stale locks
9
+ left behind by crashed processes can be detected and recovered.
10
+ """
11
+
12
+ import asyncio
13
+ import os
14
+ import sys
15
+ import tempfile
16
+ import time
17
+ from pathlib import Path
18
+
19
+
20
+ def _is_pid_alive(pid: int) -> bool:
21
+ """Check whether a process with the given PID is still running.
22
+
23
+ Uses `os.kill(pid, 0)` on Unix (harmless signal-0 probe). On Windows
24
+ `os.kill` terminates the target process, so we use
25
+ `kernel32.OpenProcess` instead.
26
+ """
27
+ if sys.platform == "win32":
28
+ import ctypes
29
+
30
+ _PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
31
+ handle = ctypes.windll.kernel32.OpenProcess( # type: ignore[attr-defined]
32
+ _PROCESS_QUERY_LIMITED_INFORMATION, False, pid
33
+ )
34
+ if handle:
35
+ ctypes.windll.kernel32.CloseHandle(handle) # type: ignore[attr-defined]
36
+ return True
37
+ return False
38
+
39
+ try:
40
+ os.kill(pid, 0)
41
+ except ProcessLookupError:
42
+ return False
43
+ except OSError:
44
+ # PermissionError means the process exists but we can't signal it
45
+ return True
46
+ return True
47
+
48
+
49
+ _STALE_EMPTY_THRESHOLD = 5 # seconds before an empty/malformed lock is stale
50
+
51
+
52
+ def _remove_stale_lock(path: Path) -> None:
53
+ """Remove the lock file if the owning process is no longer alive.
54
+
55
+ For empty or malformed lock files (e.g. from a writer that crashed
56
+ between creating the file and writing the PID), the file's mtime is
57
+ checked: if it was last modified more than _STALE_EMPTY_THRESHOLD
58
+ seconds ago the writer must have crashed, so the file is removed.
59
+ If the mtime is recent the writer may still be running, so the file
60
+ is left alone and the poll loop will retry.
61
+
62
+ To avoid a TOCTOU race where another waiter removes the stale file
63
+ and acquires a new lock between our read and our unlink, we record
64
+ the file's inode before deciding it is stale and verify it has not
65
+ changed before unlinking.
66
+ """
67
+ try:
68
+ st = os.stat(str(path))
69
+ contents = path.read_text().strip()
70
+ except (FileNotFoundError, OSError):
71
+ return
72
+
73
+ original_ino = st.st_ino
74
+
75
+ if not contents:
76
+ # Empty file -- check mtime to decide if the writer crashed.
77
+ _remove_if_same(path, original_ino, st.st_mtime)
78
+ return
79
+
80
+ try:
81
+ pid = int(contents)
82
+ except ValueError:
83
+ # Malformed content -- check mtime to decide if the writer crashed.
84
+ _remove_if_same(path, original_ino, st.st_mtime)
85
+ return
86
+
87
+ if not _is_pid_alive(pid):
88
+ _unlink_if_same_inode(path, original_ino)
89
+
90
+
91
+ def _remove_if_same(path: Path, original_ino: int, mtime: float) -> None:
92
+ """Remove *path* if mtime is stale and the inode has not changed."""
93
+ if time.time() - mtime > _STALE_EMPTY_THRESHOLD:
94
+ _unlink_if_same_inode(path, original_ino)
95
+
96
+
97
+ def _unlink_if_same_inode(path: Path, expected_ino: int) -> None:
98
+ """Unlink *path* only if its current inode matches *expected_ino*.
99
+
100
+ This prevents removing a fresh lock file that was created by another
101
+ process between our staleness check and the unlink call.
102
+ """
103
+ try:
104
+ current_st = os.stat(str(path))
105
+ except (FileNotFoundError, OSError):
106
+ return
107
+ if current_st.st_ino == expected_ino:
108
+ path.unlink(missing_ok=True)
109
+
110
+
111
+ def _write_lock(path: Path) -> None:
112
+ """Atomically create the lock file with the current PID.
113
+
114
+ Writes the PID to a temporary file in the same directory and then
115
+ uses `os.rename` (atomic on POSIX, atomic on Windows for same
116
+ volume) to move it into place. This guarantees the lock file is
117
+ never visible in an empty or partial state, which prevents a
118
+ concurrent `_remove_stale_lock` from falsely treating it as stale.
119
+
120
+ Raises `FileExistsError` if the lock file already exists (via
121
+ `os.link` on POSIX for true atomic create-or-fail, or
122
+ `os.open(O_CREAT | O_EXCL)` as a fallback on filesystems without
123
+ hard-link support).
124
+ """
125
+ # Ensure the parent directory exists so that mkstemp and the lock
126
+ # file can be created even when the storage base path is fresh.
127
+ path.parent.mkdir(parents=True, exist_ok=True)
128
+
129
+ # Write PID to a temp file in the same directory so rename stays
130
+ # on the same filesystem.
131
+ fd, tmp = tempfile.mkstemp(dir=str(path.parent), prefix=".lock_")
132
+ try:
133
+ os.write(fd, str(os.getpid()).encode())
134
+ os.close(fd)
135
+ fd = -1 # mark as closed
136
+ # Use os.link (hard link) to atomically claim the lock path.
137
+ # If the target already exists, this raises FileExistsError.
138
+ try:
139
+ os.link(tmp, str(path))
140
+ except FileExistsError:
141
+ raise
142
+ except OSError:
143
+ # Fallback for filesystems that don't support hard links
144
+ # (e.g. some Windows or network mounts): use O_CREAT|O_EXCL
145
+ # which is atomic on all POSIX and Windows filesystems.
146
+ try:
147
+ excl_fd = os.open(str(path), os.O_CREAT | os.O_EXCL | os.O_WRONLY)
148
+ except FileExistsError:
149
+ raise
150
+ try:
151
+ os.write(excl_fd, str(os.getpid()).encode())
152
+ finally:
153
+ os.close(excl_fd)
154
+ return
155
+ finally:
156
+ if fd >= 0:
157
+ os.close(fd)
158
+ # Always clean up the temp file (link created a second entry)
159
+ try:
160
+ os.unlink(tmp)
161
+ except FileNotFoundError:
162
+ pass
163
+
164
+
165
+ class FileLock:
166
+ """A cross-platform file lock using lock file existence.
167
+
168
+ Can be used as a synchronous context manager or with the async
169
+ aacquire/release pair. The lock file stores the owning process's
170
+ PID so that stale locks from crashed processes are automatically
171
+ recovered.
172
+
173
+ Args:
174
+ path: Path to the lock file.
175
+ timeout: Maximum seconds to wait for lock acquisition.
176
+ Use -1 to wait indefinitely. Defaults to -1.
177
+ poll_interval: Seconds between lock attempts.
178
+ Defaults to 0.1.
179
+ """
180
+
181
+ def __init__(
182
+ self,
183
+ path: str | Path,
184
+ timeout: float = -1,
185
+ poll_interval: float = 0.1,
186
+ ) -> None:
187
+ self._path = Path(path)
188
+ self._timeout = timeout
189
+ self._poll_interval = poll_interval
190
+ self._locked = False
191
+
192
+ def acquire(self) -> None:
193
+ """Acquire the file lock, blocking until available or timeout."""
194
+ start = time.monotonic()
195
+ while True:
196
+ try:
197
+ _write_lock(self._path)
198
+ self._locked = True
199
+ return
200
+ except FileExistsError:
201
+ _remove_stale_lock(self._path)
202
+ elapsed = time.monotonic() - start
203
+ if self._timeout >= 0 and elapsed >= self._timeout:
204
+ raise TimeoutError(
205
+ f"Failed to acquire lock on {str(self._path)!r}"
206
+ f" within {self._timeout}s"
207
+ )
208
+ time.sleep(self._poll_interval)
209
+
210
+ async def aacquire(self) -> None:
211
+ """Acquire the file lock without blocking the event loop."""
212
+ start = time.monotonic()
213
+ while True:
214
+ try:
215
+ _write_lock(self._path)
216
+ self._locked = True
217
+ return
218
+ except FileExistsError:
219
+ _remove_stale_lock(self._path)
220
+ elapsed = time.monotonic() - start
221
+ if self._timeout >= 0 and elapsed >= self._timeout:
222
+ raise TimeoutError(
223
+ f"Failed to acquire lock on {str(self._path)!r}"
224
+ f" within {self._timeout}s"
225
+ )
226
+ await asyncio.sleep(self._poll_interval)
227
+
228
+ def release(self) -> None:
229
+ """Release the file lock."""
230
+ if self._locked:
231
+ self._path.unlink(missing_ok=True)
232
+ self._locked = False
233
+
234
+ def __enter__(self) -> "FileLock":
235
+ self.acquire()
236
+ return self
237
+
238
+ def __exit__(self, *args: object) -> None:
239
+ self.release()
240
+
241
+ def __del__(self) -> None:
242
+ self.release()
@@ -23,6 +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 (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
27
  | BundleExecutionStarter | _starter_bundle.py | Executes serialized bundle in SpawnProcess |
27
28
 
28
29
  ## Key Contracts
@@ -40,7 +41,7 @@ Thin facade over single-responsibility extracted classes. New behavior belongs i
40
41
  - `_flow_run_process_map` dict -- replaced by ProcessManager
41
42
  - `_kill_process()` -- replaced by ProcessManager.kill()
42
43
  - `_run_on_crashed_hooks()` / `_run_on_cancellation_hooks()` -- replaced by HookRunner
43
- - `execute_flow_run()` -- deprecated (Mar 2026); use `FlowRunExecutorContext` + `EngineCommandStarter`
44
+ - `execute_flow_run()` -- deprecated (Mar 2026); use `FlowRunExecutorContext` + `WorkspaceResolvingEngineCommandStarter`
44
45
  - `execute_bundle()` -- deprecated (Mar 2026); use `execute_bundle()` from `prefect._experimental.bundles.execute`
45
46
  - `reschedule_current_flow_runs()` -- deprecated (Mar 2026); SIGTERM rescheduling is now handled inline by the CLI execute path
46
47
 
@@ -123,6 +124,20 @@ This matters because `get_directory` typically calls `shutil.copytree(..., dirs_
123
124
 
124
125
  These validations exist to prevent git argument injection. Do not bypass them when constructing `GitRepository` programmatically.
125
126
 
127
+ ## GitRepository Concurrent Pull Protection
128
+
129
+ `GitRepository.pull_code()` serializes concurrent calls via a `FileLock` (`prefect.locking._filelock`). The lock file sits adjacent to the destination: `destination.parent / (destination.name + ".lock")`. Stale locks from crashed processes are recovered automatically via PID check. Tests that broadly monkeypatch `pathlib.Path.exists` must account for this lock file being created next to the destination.
130
+
131
+ ## Workspace Resolver Subprocess
132
+
133
+ `_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`.
134
+
135
+ **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.
136
+
137
+ **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.
138
+
139
+ **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.
140
+
126
141
  ## Reference
127
142
 
128
143
  Full refactor design and rationale: plans/completed/2026-02-18-runner-refactor.md