prefect-client 3.2.5__tar.gz → 3.2.7__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 (325) hide show
  1. {prefect_client-3.2.5 → prefect_client-3.2.7}/PKG-INFO +1 -1
  2. prefect_client-3.2.7/src/prefect/_build_info.py +5 -0
  3. prefect_client-3.2.7/src/prefect/_experimental/bundles.py +143 -0
  4. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/__init__.py +21 -2
  5. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/engine.py +63 -29
  6. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/events/schemas/automations.py +1 -1
  7. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/flow_engine.py +2 -32
  8. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/flows.py +8 -2
  9. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/logging/configuration.py +3 -1
  10. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/runner/runner.py +142 -10
  11. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/server.py +9 -2
  12. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/base.py +18 -3
  13. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/root.py +5 -1
  14. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/server/api.py +7 -1
  15. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/server/database.py +14 -0
  16. prefect_client-3.2.5/src/prefect/_build_info.py +0 -5
  17. {prefect_client-3.2.5 → prefect_client-3.2.7}/.gitignore +0 -0
  18. {prefect_client-3.2.5 → prefect_client-3.2.7}/LICENSE +0 -0
  19. {prefect_client-3.2.5 → prefect_client-3.2.7}/README.md +0 -0
  20. {prefect_client-3.2.5 → prefect_client-3.2.7}/pyproject.toml +0 -0
  21. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/.prefectignore +0 -0
  22. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/__init__.py +0 -0
  23. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/__main__.py +0 -0
  24. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_experimental/__init__.py +0 -0
  25. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_experimental/lineage.py +0 -0
  26. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_experimental/sla/__init__.py +0 -0
  27. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_experimental/sla/client.py +0 -0
  28. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_experimental/sla/objects.py +0 -0
  29. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/__init__.py +0 -0
  30. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/_logging.py +0 -0
  31. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/compatibility/__init__.py +0 -0
  32. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/compatibility/async_dispatch.py +0 -0
  33. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/compatibility/deprecated.py +0 -0
  34. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/compatibility/migration.py +0 -0
  35. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/concurrency/__init__.py +0 -0
  36. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/concurrency/api.py +0 -0
  37. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/concurrency/calls.py +0 -0
  38. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/concurrency/cancellation.py +0 -0
  39. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/concurrency/event_loop.py +0 -0
  40. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/concurrency/inspection.py +0 -0
  41. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/concurrency/primitives.py +0 -0
  42. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/concurrency/services.py +0 -0
  43. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/concurrency/threads.py +0 -0
  44. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/concurrency/waiters.py +0 -0
  45. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/integrations.py +0 -0
  46. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/pydantic/__init__.py +0 -0
  47. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/pydantic/annotations/__init__.py +0 -0
  48. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/pydantic/annotations/pendulum.py +0 -0
  49. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/pydantic/schemas.py +0 -0
  50. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/pydantic/v1_schema.py +0 -0
  51. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/pydantic/v2_schema.py +0 -0
  52. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/pydantic/v2_validated_func.py +0 -0
  53. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/pytz.py +0 -0
  54. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/retries.py +0 -0
  55. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/schemas/__init__.py +0 -0
  56. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/schemas/bases.py +0 -0
  57. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/schemas/fields.py +0 -0
  58. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/schemas/serializers.py +0 -0
  59. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_internal/schemas/validators.py +0 -0
  60. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_result_records.py +0 -0
  61. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_vendor/croniter/__init__.py +0 -0
  62. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/_vendor/croniter/croniter.py +0 -0
  63. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/agent.py +0 -0
  64. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/artifacts.py +0 -0
  65. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/automations.py +0 -0
  66. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/blocks/__init__.py +0 -0
  67. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/blocks/abstract.py +0 -0
  68. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/blocks/core.py +0 -0
  69. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/blocks/fields.py +0 -0
  70. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/blocks/notifications.py +0 -0
  71. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/blocks/redis.py +0 -0
  72. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/blocks/system.py +0 -0
  73. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/blocks/webhook.py +0 -0
  74. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/cache_policies.py +0 -0
  75. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/__init__.py +0 -0
  76. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/base.py +0 -0
  77. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/cloud.py +0 -0
  78. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/collections.py +0 -0
  79. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/constants.py +0 -0
  80. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_artifacts/__init__.py +0 -0
  81. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_artifacts/client.py +0 -0
  82. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_automations/__init__.py +0 -0
  83. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_automations/client.py +0 -0
  84. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_blocks_documents/__init__.py +0 -0
  85. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_blocks_documents/client.py +0 -0
  86. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_blocks_schemas/__init__.py +0 -0
  87. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_blocks_schemas/client.py +0 -0
  88. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_blocks_types/__init__.py +0 -0
  89. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_blocks_types/client.py +0 -0
  90. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_concurrency_limits/__init__.py +0 -0
  91. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_concurrency_limits/client.py +0 -0
  92. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_deployments/__init__.py +0 -0
  93. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_deployments/client.py +0 -0
  94. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_flow_runs/__init__.py +0 -0
  95. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_flow_runs/client.py +0 -0
  96. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_flows/__init__.py +0 -0
  97. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_flows/client.py +0 -0
  98. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_logs/__init__.py +0 -0
  99. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_logs/client.py +0 -0
  100. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_variables/__init__.py +0 -0
  101. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_variables/client.py +0 -0
  102. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_work_pools/__init__.py +0 -0
  103. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/_work_pools/client.py +0 -0
  104. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/base.py +0 -0
  105. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/orchestration/routes.py +0 -0
  106. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/schemas/__init__.py +0 -0
  107. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/schemas/actions.py +0 -0
  108. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/schemas/filters.py +0 -0
  109. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/schemas/objects.py +0 -0
  110. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/schemas/responses.py +0 -0
  111. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/schemas/schedules.py +0 -0
  112. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/schemas/sorting.py +0 -0
  113. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/subscriptions.py +0 -0
  114. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/types/__init__.py +0 -0
  115. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/types/flexible_schedule_list.py +0 -0
  116. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/client/utilities.py +0 -0
  117. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/concurrency/__init__.py +0 -0
  118. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/concurrency/_asyncio.py +0 -0
  119. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/concurrency/_events.py +0 -0
  120. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/concurrency/asyncio.py +0 -0
  121. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/concurrency/context.py +0 -0
  122. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/concurrency/services.py +0 -0
  123. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/concurrency/sync.py +0 -0
  124. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/concurrency/v1/__init__.py +0 -0
  125. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/concurrency/v1/_asyncio.py +0 -0
  126. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/concurrency/v1/_events.py +0 -0
  127. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/concurrency/v1/asyncio.py +0 -0
  128. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/concurrency/v1/context.py +0 -0
  129. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/concurrency/v1/services.py +0 -0
  130. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/concurrency/v1/sync.py +0 -0
  131. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/context.py +0 -0
  132. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/deployments/__init__.py +0 -0
  133. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/deployments/base.py +0 -0
  134. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/deployments/deployments.py +0 -0
  135. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/deployments/flow_runs.py +0 -0
  136. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/deployments/runner.py +0 -0
  137. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/deployments/schedules.py +0 -0
  138. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/deployments/steps/__init__.py +0 -0
  139. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/deployments/steps/core.py +0 -0
  140. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/deployments/steps/pull.py +0 -0
  141. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/deployments/steps/utility.py +0 -0
  142. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/docker/__init__.py +0 -0
  143. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/docker/docker_image.py +0 -0
  144. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/events/__init__.py +0 -0
  145. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/events/actions.py +0 -0
  146. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/events/cli/__init__.py +0 -0
  147. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/events/cli/automations.py +0 -0
  148. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/events/clients.py +0 -0
  149. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/events/filters.py +0 -0
  150. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/events/related.py +0 -0
  151. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/events/schemas/__init__.py +0 -0
  152. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/events/schemas/deployment_triggers.py +0 -0
  153. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/events/schemas/events.py +0 -0
  154. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/events/schemas/labelling.py +0 -0
  155. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/events/utilities.py +0 -0
  156. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/events/worker.py +0 -0
  157. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/exceptions.py +0 -0
  158. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/filesystems.py +0 -0
  159. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/flow_runs.py +0 -0
  160. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/futures.py +0 -0
  161. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/infrastructure/__init__.py +0 -0
  162. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/infrastructure/base.py +0 -0
  163. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/infrastructure/provisioners/__init__.py +0 -0
  164. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/infrastructure/provisioners/cloud_run.py +0 -0
  165. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/infrastructure/provisioners/coiled.py +0 -0
  166. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/infrastructure/provisioners/container_instance.py +0 -0
  167. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/infrastructure/provisioners/ecs.py +0 -0
  168. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/infrastructure/provisioners/modal.py +0 -0
  169. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/input/__init__.py +0 -0
  170. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/input/actions.py +0 -0
  171. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/input/run_input.py +0 -0
  172. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/locking/__init__.py +0 -0
  173. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/locking/filesystem.py +0 -0
  174. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/locking/memory.py +0 -0
  175. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/locking/protocol.py +0 -0
  176. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/logging/__init__.py +0 -0
  177. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/logging/filters.py +0 -0
  178. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/logging/formatters.py +0 -0
  179. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/logging/handlers.py +0 -0
  180. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/logging/highlighters.py +0 -0
  181. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/logging/loggers.py +0 -0
  182. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/logging/logging.yml +0 -0
  183. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/main.py +0 -0
  184. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/plugins.py +0 -0
  185. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/py.typed +0 -0
  186. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/results.py +0 -0
  187. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/runner/__init__.py +0 -0
  188. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/runner/server.py +0 -0
  189. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/runner/storage.py +0 -0
  190. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/runner/submit.py +0 -0
  191. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/runner/utils.py +0 -0
  192. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/runtime/__init__.py +0 -0
  193. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/runtime/deployment.py +0 -0
  194. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/runtime/flow_run.py +0 -0
  195. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/runtime/task_run.py +0 -0
  196. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/schedules.py +0 -0
  197. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/serializers.py +0 -0
  198. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/__init__.py +0 -0
  199. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/admin.py +0 -0
  200. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/artifacts.py +0 -0
  201. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/automations.py +0 -0
  202. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/block_capabilities.py +0 -0
  203. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/block_documents.py +0 -0
  204. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/block_schemas.py +0 -0
  205. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/block_types.py +0 -0
  206. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/clients.py +0 -0
  207. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/collections.py +0 -0
  208. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/collections_data/views/aggregate-worker-metadata.json +0 -0
  209. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/concurrency_limits.py +0 -0
  210. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/concurrency_limits_v2.py +0 -0
  211. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/csrf_token.py +0 -0
  212. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/dependencies.py +0 -0
  213. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/deployments.py +0 -0
  214. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/events.py +0 -0
  215. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/flow_run_notification_policies.py +0 -0
  216. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/flow_run_states.py +0 -0
  217. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/flow_runs.py +0 -0
  218. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/flows.py +0 -0
  219. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/logs.py +0 -0
  220. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/middleware.py +0 -0
  221. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/root.py +0 -0
  222. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/run_history.py +0 -0
  223. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/saved_searches.py +0 -0
  224. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/static/prefect-logo-mark-gradient.png +0 -0
  225. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/task_run_states.py +0 -0
  226. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/task_runs.py +0 -0
  227. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/task_workers.py +0 -0
  228. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/templates.py +0 -0
  229. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/ui/__init__.py +0 -0
  230. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/ui/flow_runs.py +0 -0
  231. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/ui/flows.py +0 -0
  232. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/ui/schemas.py +0 -0
  233. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/ui/task_runs.py +0 -0
  234. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/validation.py +0 -0
  235. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/variables.py +0 -0
  236. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/work_queues.py +0 -0
  237. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/server/api/workers.py +0 -0
  238. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/__init__.py +0 -0
  239. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/constants.py +0 -0
  240. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/context.py +0 -0
  241. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/legacy.py +0 -0
  242. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/__init__.py +0 -0
  243. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/api.py +0 -0
  244. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/cli.py +0 -0
  245. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/client.py +0 -0
  246. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/cloud.py +0 -0
  247. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/deployments.py +0 -0
  248. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/experiments.py +0 -0
  249. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/flows.py +0 -0
  250. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/internal.py +0 -0
  251. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/logging.py +0 -0
  252. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/results.py +0 -0
  253. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/runner.py +0 -0
  254. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/server/__init__.py +0 -0
  255. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/server/deployments.py +0 -0
  256. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/server/ephemeral.py +0 -0
  257. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/server/events.py +0 -0
  258. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/server/flow_run_graph.py +0 -0
  259. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/server/root.py +0 -0
  260. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/server/services.py +0 -0
  261. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/server/tasks.py +0 -0
  262. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/server/ui.py +0 -0
  263. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/tasks.py +0 -0
  264. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/testing.py +0 -0
  265. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/models/worker.py +0 -0
  266. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/profiles.py +0 -0
  267. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/profiles.toml +0 -0
  268. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/settings/sources.py +0 -0
  269. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/states.py +0 -0
  270. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/task_engine.py +0 -0
  271. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/task_runners.py +0 -0
  272. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/task_runs.py +0 -0
  273. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/task_worker.py +0 -0
  274. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/tasks.py +0 -0
  275. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/telemetry/__init__.py +0 -0
  276. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/telemetry/bootstrap.py +0 -0
  277. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/telemetry/instrumentation.py +0 -0
  278. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/telemetry/logging.py +0 -0
  279. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/telemetry/processors.py +0 -0
  280. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/telemetry/run_telemetry.py +0 -0
  281. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/telemetry/services.py +0 -0
  282. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/transactions.py +0 -0
  283. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/types/__init__.py +0 -0
  284. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/types/_datetime.py +0 -0
  285. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/types/entrypoint.py +0 -0
  286. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/__init__.py +0 -0
  287. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/_deprecated.py +0 -0
  288. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/_engine.py +0 -0
  289. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/_git.py +0 -0
  290. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/annotations.py +0 -0
  291. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/asyncutils.py +0 -0
  292. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/callables.py +0 -0
  293. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/collections.py +0 -0
  294. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/compat.py +0 -0
  295. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/context.py +0 -0
  296. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/dispatch.py +0 -0
  297. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/dockerutils.py +0 -0
  298. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/engine.py +0 -0
  299. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/filesystem.py +0 -0
  300. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/generics.py +0 -0
  301. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/hashing.py +0 -0
  302. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/importtools.py +0 -0
  303. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/math.py +0 -0
  304. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/names.py +0 -0
  305. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/processutils.py +0 -0
  306. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/pydantic.py +0 -0
  307. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/render_swagger.py +0 -0
  308. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/schema_tools/__init__.py +0 -0
  309. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/schema_tools/hydration.py +0 -0
  310. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/schema_tools/validation.py +0 -0
  311. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/services.py +0 -0
  312. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/slugify.py +0 -0
  313. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/templating.py +0 -0
  314. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/text.py +0 -0
  315. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/timeout.py +0 -0
  316. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/urls.py +0 -0
  317. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/utilities/visualization.py +0 -0
  318. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/variables.py +0 -0
  319. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/workers/__init__.py +0 -0
  320. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/workers/base.py +0 -0
  321. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/workers/block.py +0 -0
  322. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/workers/cloud.py +0 -0
  323. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/workers/process.py +0 -0
  324. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/workers/server.py +0 -0
  325. {prefect_client-3.2.5 → prefect_client-3.2.7}/src/prefect/workers/utilities.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: prefect-client
3
- Version: 3.2.5
3
+ Version: 3.2.7
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,5 @@
1
+ # Generated by versioningit
2
+ __version__ = "3.2.7"
3
+ __build_date__ = "2025-02-21 19:38:38.599741+00:00"
4
+ __git_commit__ = "d4d9001e40eb378ec68a97f7e3bab07d89c7557c"
5
+ __dirty__ = False
@@ -0,0 +1,143 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import base64
5
+ import gzip
6
+ import multiprocessing
7
+ import multiprocessing.context
8
+ import os
9
+ from typing import Any, TypedDict
10
+
11
+ import cloudpickle
12
+
13
+ from prefect.client.schemas.objects import FlowRun
14
+ from prefect.context import SettingsContext, get_settings_context, serialize_context
15
+ from prefect.engine import handle_engine_signals
16
+ from prefect.flow_engine import run_flow
17
+ from prefect.flows import Flow
18
+ from prefect.settings.context import get_current_settings
19
+ from prefect.settings.models.root import Settings
20
+
21
+
22
+ class SerializedBundle(TypedDict):
23
+ """
24
+ A serialized bundle is a serialized function, context, and flow run that can be
25
+ easily transported for later execution.
26
+ """
27
+
28
+ function: str
29
+ context: str
30
+ flow_run: dict[str, Any]
31
+
32
+
33
+ def _serialize_bundle_object(obj: Any) -> str:
34
+ """
35
+ Serializes an object to a string.
36
+ """
37
+ return base64.b64encode(gzip.compress(cloudpickle.dumps(obj))).decode()
38
+
39
+
40
+ def _deserialize_bundle_object(serialized_obj: str) -> Any:
41
+ """
42
+ Deserializes an object from a string.
43
+ """
44
+ return cloudpickle.loads(gzip.decompress(base64.b64decode(serialized_obj)))
45
+
46
+
47
+ def create_bundle_for_flow_run(
48
+ flow: Flow[Any, Any],
49
+ flow_run: FlowRun,
50
+ context: dict[str, Any] | None = None,
51
+ ) -> SerializedBundle:
52
+ """
53
+ Creates a bundle for a flow run.
54
+
55
+ Args:
56
+ flow: The flow to bundle.
57
+ flow_run: The flow run to bundle.
58
+ context: The context to use when running the flow.
59
+
60
+ Returns:
61
+ A serialized bundle.
62
+ """
63
+ context = context or serialize_context()
64
+
65
+ return {
66
+ "function": _serialize_bundle_object(flow),
67
+ "context": _serialize_bundle_object(context),
68
+ "flow_run": flow_run.model_dump(mode="json"),
69
+ }
70
+
71
+
72
+ def extract_flow_from_bundle(bundle: SerializedBundle) -> Flow[Any, Any]:
73
+ """
74
+ Extracts a flow from a bundle.
75
+ """
76
+ return _deserialize_bundle_object(bundle["function"])
77
+
78
+
79
+ def _extract_and_run_flow(
80
+ bundle: SerializedBundle, env: dict[str, Any] | None = None
81
+ ) -> None:
82
+ """
83
+ Extracts a flow from a bundle and runs it.
84
+
85
+ Designed to be run in a subprocess.
86
+
87
+ Args:
88
+ bundle: The bundle to extract and run.
89
+ env: The environment to use when running the flow.
90
+ """
91
+
92
+ os.environ.update(env or {})
93
+ # TODO: make this a thing we can pass directly to the engine
94
+ os.environ["PREFECT__ENABLE_CANCELLATION_AND_CRASHED_HOOKS"] = "false"
95
+ settings_context = get_settings_context()
96
+
97
+ flow = _deserialize_bundle_object(bundle["function"])
98
+ context = _deserialize_bundle_object(bundle["context"])
99
+ flow_run = FlowRun.model_validate(bundle["flow_run"])
100
+
101
+ with SettingsContext(
102
+ profile=settings_context.profile,
103
+ settings=Settings(),
104
+ ):
105
+ with handle_engine_signals(flow_run.id):
106
+ maybe_coro = run_flow(
107
+ flow=flow,
108
+ flow_run=flow_run,
109
+ context=context,
110
+ )
111
+ if asyncio.iscoroutine(maybe_coro):
112
+ # This is running in a brand new process, so there won't be an existing
113
+ # event loop.
114
+ asyncio.run(maybe_coro)
115
+
116
+
117
+ def execute_bundle_in_subprocess(
118
+ bundle: SerializedBundle,
119
+ ) -> multiprocessing.context.SpawnProcess:
120
+ """
121
+ Executes a bundle in a subprocess.
122
+
123
+ Args:
124
+ bundle: The bundle to execute.
125
+
126
+ Returns:
127
+ A multiprocessing.context.SpawnProcess.
128
+ """
129
+
130
+ ctx = multiprocessing.get_context("spawn")
131
+
132
+ process = ctx.Process(
133
+ target=_extract_and_run_flow,
134
+ kwargs={
135
+ "bundle": bundle,
136
+ "env": get_current_settings().to_environment_variables(exclude_unset=True)
137
+ | os.environ,
138
+ },
139
+ )
140
+
141
+ process.start()
142
+
143
+ return process
@@ -81,6 +81,7 @@ from prefect.client.orchestration._blocks_types.client import (
81
81
 
82
82
  import prefect
83
83
  import prefect.exceptions
84
+ from prefect.logging.loggers import get_run_logger
84
85
  import prefect.settings
85
86
  import prefect.states
86
87
  from prefect.client.constants import SERVER_API_VERSION
@@ -1182,8 +1183,17 @@ class PrefectClient(
1182
1183
  if api_version.major != client_version.major:
1183
1184
  raise RuntimeError(
1184
1185
  f"Found incompatible versions: client: {client_version}, server: {api_version}. "
1185
- f"Major versions must match."
1186
+ "Major versions must match."
1186
1187
  )
1188
+ if api_version < client_version:
1189
+ warning_message = (
1190
+ "Your Prefect server is running an older version of Prefect than your client which may result in unexpected behavior. "
1191
+ f"Please upgrade your Prefect server from version {api_version} to version {client_version} or higher."
1192
+ )
1193
+ try:
1194
+ get_run_logger().warning(warning_message)
1195
+ except prefect.context.MissingContextError:
1196
+ self.logger.warning(warning_message)
1187
1197
 
1188
1198
  async def __aenter__(self) -> Self:
1189
1199
  """
@@ -1523,8 +1533,17 @@ class SyncPrefectClient(
1523
1533
  if api_version.major != client_version.major:
1524
1534
  raise RuntimeError(
1525
1535
  f"Found incompatible versions: client: {client_version}, server: {api_version}. "
1526
- f"Major versions must match."
1536
+ "Major versions must match."
1527
1537
  )
1538
+ if api_version < client_version:
1539
+ warning_message = (
1540
+ "Your Prefect server is running an older version of Prefect than your client which may result in unexpected behavior. "
1541
+ f"Please upgrade your Prefect server from version {api_version} to version {client_version} or higher."
1542
+ )
1543
+ try:
1544
+ get_run_logger().warning(warning_message)
1545
+ except prefect.context.MissingContextError:
1546
+ self.logger.warning(warning_message)
1528
1547
 
1529
1548
  def set_task_run_name(self, task_run_id: UUID, name: str) -> httpx.Response:
1530
1549
  task_run_data = TaskRunUpdate(name=name)
@@ -1,5 +1,8 @@
1
+ from __future__ import annotations
2
+
1
3
  import os
2
4
  import sys
5
+ from contextlib import contextmanager
3
6
  from typing import TYPE_CHECKING, Any, Callable
4
7
  from uuid import UUID
5
8
 
@@ -18,13 +21,71 @@ from prefect.utilities.asyncutils import (
18
21
  if TYPE_CHECKING:
19
22
  import logging
20
23
 
21
- from prefect.flow_engine import FlowRun
24
+ from prefect.client.schemas.objects import FlowRun
22
25
  from prefect.flows import Flow
23
26
  from prefect.logging.loggers import LoggingAdapter
24
27
 
25
28
  engine_logger: "logging.Logger" = get_logger("engine")
26
29
 
27
30
 
31
+ @contextmanager
32
+ def handle_engine_signals(flow_run_id: UUID | None = None):
33
+ """
34
+ Handle signals from the orchestrator to abort or pause the flow run or otherwise
35
+ handle unexpected exceptions.
36
+
37
+ This context manager will handle exiting the process depending on the signal received.
38
+
39
+ Args:
40
+ flow_run_id: The ID of the flow run to handle signals for.
41
+
42
+ Example:
43
+ ```python
44
+ from prefect import flow
45
+ from prefect.engine import handle_engine_signals
46
+ from prefect.flow_engine import run_flow
47
+
48
+ @flow
49
+ def my_flow():
50
+ print("Hello, world!")
51
+
52
+ with handle_engine_signals():
53
+ run_flow(my_flow)
54
+ ```
55
+ """
56
+ try:
57
+ yield
58
+ except Abort:
59
+ if flow_run_id:
60
+ msg = f"Execution of flow run '{flow_run_id}' aborted by orchestrator."
61
+ else:
62
+ msg = "Execution aborted by orchestrator."
63
+ engine_logger.info(msg)
64
+ exit(0)
65
+ except Pause:
66
+ if flow_run_id:
67
+ msg = f"Execution of flow run '{flow_run_id}' is paused."
68
+ else:
69
+ msg = "Execution is paused."
70
+ engine_logger.info(msg)
71
+ exit(0)
72
+ except Exception:
73
+ if flow_run_id:
74
+ msg = f"Execution of flow run '{flow_run_id}' exited with unexpected exception"
75
+ else:
76
+ msg = "Execution exited with unexpected exception"
77
+ engine_logger.error(msg, exc_info=True)
78
+ exit(1)
79
+ except BaseException:
80
+ if flow_run_id:
81
+ msg = f"Execution of flow run '{flow_run_id}' interrupted by base exception"
82
+ else:
83
+ msg = "Execution interrupted by base exception"
84
+ engine_logger.error(msg, exc_info=True)
85
+ # Let the exit code be determined by the base exception type
86
+ raise
87
+
88
+
28
89
  if __name__ == "__main__":
29
90
  try:
30
91
  flow_run_id: UUID = UUID(
@@ -36,7 +97,7 @@ if __name__ == "__main__":
36
97
  )
37
98
  exit(1)
38
99
 
39
- try:
100
+ with handle_engine_signals(flow_run_id):
40
101
  from prefect.flow_engine import (
41
102
  flow_run_logger,
42
103
  load_flow,
@@ -62,32 +123,5 @@ if __name__ == "__main__":
62
123
  else:
63
124
  run_flow(flow, flow_run=flow_run, error_logger=run_logger)
64
125
 
65
- except Abort:
66
- engine_logger.info(
67
- f"Engine execution of flow run '{flow_run_id}' aborted by orchestrator."
68
- )
69
- exit(0)
70
- except Pause:
71
- engine_logger.info(f"Engine execution of flow run '{flow_run_id}' is paused.")
72
- exit(0)
73
- except Exception:
74
- engine_logger.error(
75
- (
76
- f"Engine execution of flow run '{flow_run_id}' exited with unexpected "
77
- "exception"
78
- ),
79
- exc_info=True,
80
- )
81
- exit(1)
82
- except BaseException:
83
- engine_logger.error(
84
- (
85
- f"Engine execution of flow run '{flow_run_id}' interrupted by base "
86
- "exception"
87
- ),
88
- exc_info=True,
89
- )
90
- # Let the exit code be determined by the base exception type
91
- raise
92
126
 
93
127
  __getattr__: Callable[[str], Any] = getattr_migration(__name__)
@@ -84,7 +84,7 @@ class Trigger(PrefectBaseModel, abc.ABC, extra="ignore"): # type: ignore[call-a
84
84
  getattr(self, "name", None)
85
85
  or f"Automation for deployment {self._deployment_id}"
86
86
  ),
87
- description="",
87
+ description=getattr(self, "description", ""),
88
88
  enabled=getattr(self, "enabled", True),
89
89
  trigger=trigger,
90
90
  actions=self.actions(),
@@ -47,6 +47,7 @@ from prefect.context import (
47
47
  hydrated_context,
48
48
  serialize_context,
49
49
  )
50
+ from prefect.engine import handle_engine_signals
50
51
  from prefect.exceptions import (
51
52
  Abort,
52
53
  MissingFlowError,
@@ -1592,8 +1593,6 @@ def run_flow_in_subprocess(
1592
1593
  """
1593
1594
  Wrapper function to update environment variables and settings before running the flow.
1594
1595
  """
1595
- engine_logger = logging.getLogger("prefect.engine")
1596
-
1597
1596
  os.environ.update(env or {})
1598
1597
  settings_context = get_settings_context()
1599
1598
  # Create a new settings context with a new settings object to pick up the updated
@@ -1602,41 +1601,12 @@ def run_flow_in_subprocess(
1602
1601
  profile=settings_context.profile,
1603
1602
  settings=Settings(),
1604
1603
  ):
1605
- try:
1604
+ with handle_engine_signals(getattr(flow_run, "id", None)):
1606
1605
  maybe_coro = run_flow(*args, **kwargs)
1607
1606
  if asyncio.iscoroutine(maybe_coro):
1608
1607
  # This is running in a brand new process, so there won't be an existing
1609
1608
  # event loop.
1610
1609
  asyncio.run(maybe_coro)
1611
- except Abort:
1612
- if flow_run:
1613
- msg = f"Execution of flow run '{flow_run.id}' aborted by orchestrator."
1614
- else:
1615
- msg = "Execution aborted by orchestrator."
1616
- engine_logger.info(msg)
1617
- exit(0)
1618
- except Pause:
1619
- if flow_run:
1620
- msg = f"Execution of flow run '{flow_run.id}' is paused."
1621
- else:
1622
- msg = "Execution is paused."
1623
- engine_logger.info(msg)
1624
- exit(0)
1625
- except Exception:
1626
- if flow_run:
1627
- msg = f"Execution of flow run '{flow_run.id}' exited with unexpected exception"
1628
- else:
1629
- msg = "Execution exited with unexpected exception"
1630
- engine_logger.error(msg, exc_info=True)
1631
- exit(1)
1632
- except BaseException:
1633
- if flow_run:
1634
- msg = f"Execution of flow run '{flow_run.id}' interrupted by base exception"
1635
- else:
1636
- msg = "Execution interrupted by base exception"
1637
- engine_logger.error(msg, exc_info=True)
1638
- # Let the exit code be determined by the base exception type
1639
- raise
1640
1610
 
1641
1611
  ctx = multiprocessing.get_context("spawn")
1642
1612
 
@@ -2350,9 +2350,15 @@ async def load_flow_from_flow_run(
2350
2350
  f"Running {len(deployment.pull_steps)} deployment pull step(s)"
2351
2351
  )
2352
2352
 
2353
- from prefect.deployments.steps.core import run_steps
2353
+ from prefect.deployments.steps.core import StepExecutionError, run_steps
2354
+
2355
+ try:
2356
+ output = await run_steps(deployment.pull_steps)
2357
+ except StepExecutionError as e:
2358
+ e = e.__cause__ or e
2359
+ run_logger.error(str(e))
2360
+ raise
2354
2361
 
2355
- output = await run_steps(deployment.pull_steps)
2356
2362
  if output.get("directory"):
2357
2363
  run_logger.debug(f"Changing working directory to {output['directory']!r}")
2358
2364
  os.chdir(output["directory"])
@@ -38,7 +38,9 @@ def load_logging_config(path: Path) -> dict[str, Any]:
38
38
  warnings.filterwarnings("ignore", category=DeprecationWarning)
39
39
  config = yaml.safe_load(
40
40
  # Substitute settings into the template in format $SETTING / ${SETTING}
41
- template.substitute(current_settings.to_environment_variables())
41
+ template.substitute(
42
+ current_settings.to_environment_variables(include_aliases=True)
43
+ )
42
44
  )
43
45
 
44
46
  # Load overrides from the environment
@@ -64,9 +64,15 @@ from uuid import UUID, uuid4
64
64
 
65
65
  import anyio
66
66
  import anyio.abc
67
+ import anyio.to_thread
67
68
  from cachetools import LRUCache
68
69
  from typing_extensions import Self
69
70
 
71
+ from prefect._experimental.bundles import (
72
+ SerializedBundle,
73
+ execute_bundle_in_subprocess,
74
+ extract_flow_from_bundle,
75
+ )
70
76
  from prefect._internal.concurrency.api import (
71
77
  create_call,
72
78
  from_async,
@@ -135,7 +141,7 @@ __all__ = ["Runner"]
135
141
 
136
142
 
137
143
  class ProcessMapEntry(TypedDict):
138
- flow_run: FlowRun
144
+ flow_run: "FlowRun"
139
145
  pid: int
140
146
 
141
147
 
@@ -221,6 +227,7 @@ class Runner:
221
227
  self._scheduled_task_scopes: set[anyio.abc.CancelScope] = set()
222
228
  self._deployment_ids: set[UUID] = set()
223
229
  self._flow_run_process_map: dict[UUID, ProcessMapEntry] = dict()
230
+ self._flow_run_bundle_map: dict[UUID, SerializedBundle] = dict()
224
231
 
225
232
  self._tmp_dir: Path = (
226
233
  Path(tempfile.gettempdir()) / "runner_storage" / str(uuid4())
@@ -508,7 +515,7 @@ class Runner:
508
515
  return asyncio.run_coroutine_threadsafe(func(*args, **kwargs), self._loop)
509
516
 
510
517
  async def cancel_all(self) -> None:
511
- runs_to_cancel: list[FlowRun] = []
518
+ runs_to_cancel: list["FlowRun"] = []
512
519
 
513
520
  # done to avoid dictionary size changing during iteration
514
521
  for info in self._flow_run_process_map.values():
@@ -602,7 +609,120 @@ class Runner:
602
609
  )
603
610
  )
604
611
 
605
- def _get_flow_run_logger(self, flow_run: "FlowRun | FlowRun") -> PrefectLogAdapter:
612
+ async def execute_bundle(self, bundle: SerializedBundle) -> None:
613
+ """
614
+ Executes a bundle in a subprocess.
615
+ """
616
+ from prefect.client.schemas.objects import FlowRun
617
+
618
+ self.pause_on_shutdown = False
619
+ context = self if not self.started else asyncnullcontext()
620
+
621
+ flow_run = FlowRun.model_validate(bundle["flow_run"])
622
+
623
+ async with context:
624
+ if not self._acquire_limit_slot(flow_run.id):
625
+ return
626
+
627
+ process = execute_bundle_in_subprocess(bundle)
628
+
629
+ if process.pid is None:
630
+ # This shouldn't happen because `execute_bundle_in_subprocess` starts the process
631
+ # but we'll handle it gracefully anyway
632
+ msg = "Failed to start process for flow execution. No PID returned."
633
+ await self._propose_crashed_state(flow_run, msg)
634
+ raise RuntimeError(msg)
635
+
636
+ self._flow_run_process_map[flow_run.id] = ProcessMapEntry(
637
+ pid=process.pid, flow_run=flow_run
638
+ )
639
+ self._flow_run_bundle_map[flow_run.id] = bundle
640
+
641
+ tasks: list[asyncio.Task[None]] = []
642
+ tasks.append(
643
+ asyncio.create_task(
644
+ critical_service_loop(
645
+ workload=self._check_for_cancelled_flow_runs,
646
+ interval=self.query_seconds,
647
+ jitter_range=0.3,
648
+ )
649
+ )
650
+ )
651
+ if self.heartbeat_seconds is not None:
652
+ tasks.append(
653
+ asyncio.create_task(
654
+ critical_service_loop(
655
+ workload=self._emit_flow_run_heartbeats,
656
+ interval=self.heartbeat_seconds,
657
+ jitter_range=0.1,
658
+ )
659
+ )
660
+ )
661
+
662
+ await anyio.to_thread.run_sync(process.join)
663
+
664
+ for task in tasks:
665
+ task.cancel()
666
+
667
+ await asyncio.gather(*tasks, return_exceptions=True)
668
+
669
+ self._flow_run_process_map.pop(flow_run.id)
670
+
671
+ flow_run_logger = self._get_flow_run_logger(flow_run)
672
+ if process.exitcode is None:
673
+ raise RuntimeError("Process has no exit code")
674
+
675
+ if process.exitcode:
676
+ help_message = None
677
+ level = logging.ERROR
678
+ if process.exitcode == -9:
679
+ level = logging.INFO
680
+ help_message = (
681
+ "This indicates that the process exited due to a SIGKILL signal. "
682
+ "Typically, this is either caused by manual cancellation or "
683
+ "high memory usage causing the operating system to "
684
+ "terminate the process."
685
+ )
686
+ if process.exitcode == -15:
687
+ level = logging.INFO
688
+ help_message = (
689
+ "This indicates that the process exited due to a SIGTERM signal. "
690
+ "Typically, this is caused by manual cancellation."
691
+ )
692
+ elif process.exitcode == 247:
693
+ help_message = (
694
+ "This indicates that the process was terminated due to high "
695
+ "memory usage."
696
+ )
697
+ elif (
698
+ sys.platform == "win32"
699
+ and process.returncode == STATUS_CONTROL_C_EXIT
700
+ ):
701
+ level = logging.INFO
702
+ help_message = (
703
+ "Process was terminated due to a Ctrl+C or Ctrl+Break signal. "
704
+ "Typically, this is caused by manual cancellation."
705
+ )
706
+
707
+ flow_run_logger.log(
708
+ level,
709
+ f"Process for flow run {flow_run.name!r} exited with status code:"
710
+ f" {process.exitcode}"
711
+ + (f"; {help_message}" if help_message else ""),
712
+ )
713
+ terminal_state = await self._propose_crashed_state(
714
+ flow_run, help_message or "Process exited with non-zero exit code"
715
+ )
716
+ if terminal_state:
717
+ await self._run_on_crashed_hooks(
718
+ flow_run=flow_run, state=terminal_state
719
+ )
720
+ else:
721
+ flow_run_logger.info(
722
+ f"Process for flow run {flow_run.name!r} exited cleanly."
723
+ )
724
+
725
+ def _get_flow_run_logger(self, flow_run: "FlowRun") -> PrefectLogAdapter:
606
726
  return flow_run_logger(flow_run=flow_run).getChild(
607
727
  "runner",
608
728
  extra={
@@ -1308,8 +1428,11 @@ class Runner:
1308
1428
  exc_info=True,
1309
1429
  )
1310
1430
 
1311
- async def _propose_crashed_state(self, flow_run: "FlowRun", message: str) -> None:
1431
+ async def _propose_crashed_state(
1432
+ self, flow_run: "FlowRun", message: str
1433
+ ) -> State[Any] | None:
1312
1434
  run_logger = self._get_flow_run_logger(flow_run)
1435
+ state = None
1313
1436
  try:
1314
1437
  state = await propose_state(
1315
1438
  self._client,
@@ -1326,6 +1449,7 @@ class Runner:
1326
1449
  run_logger.info(
1327
1450
  f"Reported flow run '{flow_run.id}' as crashed: {message}"
1328
1451
  )
1452
+ return state
1329
1453
 
1330
1454
  async def _mark_flow_run_as_cancelled(
1331
1455
  self, flow_run: "FlowRun", state_updates: Optional[dict[str, Any]] = None
@@ -1391,9 +1515,14 @@ class Runner:
1391
1515
  """
1392
1516
  if state.is_cancelling():
1393
1517
  try:
1394
- flow = await load_flow_from_flow_run(
1395
- flow_run, storage_base_path=str(self._tmp_dir)
1396
- )
1518
+ if flow_run.id in self._flow_run_bundle_map:
1519
+ flow = extract_flow_from_bundle(
1520
+ self._flow_run_bundle_map[flow_run.id]
1521
+ )
1522
+ else:
1523
+ flow = await load_flow_from_flow_run(
1524
+ flow_run, storage_base_path=str(self._tmp_dir)
1525
+ )
1397
1526
  hooks = flow.on_cancellation_hooks or []
1398
1527
 
1399
1528
  await _run_hooks(hooks, flow_run, flow, state)
@@ -1412,9 +1541,12 @@ class Runner:
1412
1541
  Run the hooks for a flow.
1413
1542
  """
1414
1543
  if state.is_crashed():
1415
- flow = await load_flow_from_flow_run(
1416
- flow_run, storage_base_path=str(self._tmp_dir)
1417
- )
1544
+ if flow_run.id in self._flow_run_bundle_map:
1545
+ flow = extract_flow_from_bundle(self._flow_run_bundle_map[flow_run.id])
1546
+ else:
1547
+ flow = await load_flow_from_flow_run(
1548
+ flow_run, storage_base_path=str(self._tmp_dir)
1549
+ )
1418
1550
  hooks = flow.on_crashed_hooks or []
1419
1551
 
1420
1552
  await _run_hooks(hooks, flow_run, flow, state)
@@ -55,6 +55,7 @@ from prefect.settings import (
55
55
  PREFECT_DEBUG_MODE,
56
56
  PREFECT_MEMO_STORE_PATH,
57
57
  PREFECT_MEMOIZE_BLOCK_AUTO_REGISTRATION,
58
+ PREFECT_SERVER_API_BASE_PATH,
58
59
  PREFECT_SERVER_EPHEMERAL_STARTUP_TIMEOUT_SECONDS,
59
60
  PREFECT_UI_SERVE_BASE,
60
61
  get_current_settings,
@@ -356,7 +357,10 @@ def create_api_app(
356
357
  header_token = request.headers.get("Authorization")
357
358
 
358
359
  # used for probes in k8s and such
359
- if request.url.path in ["/api/health", "/api/ready"]:
360
+ if (
361
+ request.url.path.endswith(("health", "ready"))
362
+ and request.method.upper() == "GET"
363
+ ):
360
364
  return await call_next(request)
361
365
  try:
362
366
  if header_token is None:
@@ -691,7 +695,10 @@ def create_app(
691
695
  name="static",
692
696
  )
693
697
  app.api_app = api_app
694
- app.mount("/api", app=api_app, name="api")
698
+ if PREFECT_SERVER_API_BASE_PATH:
699
+ app.mount(PREFECT_SERVER_API_BASE_PATH.value(), app=api_app, name="api")
700
+ else:
701
+ app.mount("/api", app=api_app, name="api")
695
702
  app.mount("/", app=ui_app, name="ui")
696
703
 
697
704
  def openapi():