prefect 3.6.13.dev2__py3-none-any.whl → 3.6.14.dev1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. prefect/_build_info.py +3 -3
  2. prefect/_internal/compatibility/blocks.py +18 -0
  3. prefect/client/schemas/filters.py +24 -0
  4. prefect/flow_engine.py +192 -10
  5. prefect/flows.py +61 -2
  6. prefect/results.py +262 -21
  7. prefect/runner/runner.py +29 -82
  8. prefect/runner/storage.py +3 -2
  9. prefect/server/schemas/filters.py +45 -0
  10. prefect/server/ui-v2/assets/{artifact-card-C8JEQRHl.js → artifact-card-DkgEVahF.js} +2 -2
  11. prefect/server/ui-v2/assets/{artifact-card-C8JEQRHl.js.map → artifact-card-DkgEVahF.js.map} +1 -1
  12. prefect/server/ui-v2/assets/{artifact._id-67V8kTg9.js → artifact._id-C7yJhkKY.js} +2 -2
  13. prefect/server/ui-v2/assets/{artifact._id-67V8kTg9.js.map → artifact._id-C7yJhkKY.js.map} +1 -1
  14. prefect/server/ui-v2/assets/{automation-wizard-DuxZ47Nn.js → automation-wizard-BLI4sqs9.js} +2 -2
  15. prefect/server/ui-v2/assets/{automation-wizard-DuxZ47Nn.js.map → automation-wizard-BLI4sqs9.js.map} +1 -1
  16. prefect/server/ui-v2/assets/{automation._id-D8S8r4Ji.js → automation._id-OLes3du9.js} +2 -2
  17. prefect/server/ui-v2/assets/{automation._id-D8S8r4Ji.js.map → automation._id-OLes3du9.js.map} +1 -1
  18. prefect/server/ui-v2/assets/{automation_._id.edit-C1fOM0Hx.js → automation_._id.edit-QrSzkDDB.js} +2 -2
  19. prefect/server/ui-v2/assets/{automation_._id.edit-C1fOM0Hx.js.map → automation_._id.edit-QrSzkDDB.js.map} +1 -1
  20. prefect/server/ui-v2/assets/{automations-header-DrijTNGi.js → automations-header-BoJc9HK8.js} +2 -2
  21. prefect/server/ui-v2/assets/{automations-header-DrijTNGi.js.map → automations-header-BoJc9HK8.js.map} +1 -1
  22. prefect/server/ui-v2/assets/{base-job-template-form-section-BDkqOkpe.js → base-job-template-form-section-Br6s0jNS.js} +2 -2
  23. prefect/server/ui-v2/assets/{base-job-template-form-section-BDkqOkpe.js.map → base-job-template-form-section-Br6s0jNS.js.map} +1 -1
  24. prefect/server/ui-v2/assets/{block-type-details-CrFHWH5D.js → block-type-details-BSbBP-Nm.js} +2 -2
  25. prefect/server/ui-v2/assets/{block-type-details-CrFHWH5D.js.map → block-type-details-BSbBP-Nm.js.map} +1 -1
  26. prefect/server/ui-v2/assets/block-type-logo-DNFERTyH.js +2 -0
  27. prefect/server/ui-v2/assets/{block-type-logo-WQNm0PzP.js.map → block-type-logo-DNFERTyH.js.map} +1 -1
  28. prefect/server/ui-v2/assets/{block._id-C3gN1Ae8.js → block._id-DO6Hulrv.js} +2 -2
  29. prefect/server/ui-v2/assets/{block._id-C3gN1Ae8.js.map → block._id-DO6Hulrv.js.map} +1 -1
  30. prefect/server/ui-v2/assets/{block_._id.edit-DzPuSvat.js → block_._id.edit-BWF0TQvv.js} +2 -2
  31. prefect/server/ui-v2/assets/{block_._id.edit-DzPuSvat.js.map → block_._id.edit-BWF0TQvv.js.map} +1 -1
  32. prefect/server/ui-v2/assets/{catalog-T-7MqsyE.js → catalog-BlaqZP0r.js} +2 -2
  33. prefect/server/ui-v2/assets/{catalog-T-7MqsyE.js.map → catalog-BlaqZP0r.js.map} +1 -1
  34. prefect/server/ui-v2/assets/{catalog_._slug-DMOI61fc.js → catalog_._slug-BZWiMtjq.js} +2 -2
  35. prefect/server/ui-v2/assets/{catalog_._slug-DMOI61fc.js.map → catalog_._slug-BZWiMtjq.js.map} +1 -1
  36. prefect/server/ui-v2/assets/{catalog_._slug_.create-l9bGUPi-.js → catalog_._slug_.create-oHffbeMs.js} +2 -2
  37. prefect/server/ui-v2/assets/{catalog_._slug_.create-l9bGUPi-.js.map → catalog_._slug_.create-oHffbeMs.js.map} +1 -1
  38. prefect/server/ui-v2/assets/{collapsible-DM-Ze5-Y.js → collapsible-D45P93xU.js} +2 -2
  39. prefect/server/ui-v2/assets/{collapsible-DM-Ze5-Y.js.map → collapsible-D45P93xU.js.map} +1 -1
  40. prefect/server/ui-v2/assets/{concurrency-limit._id-BHEt9viF.js → concurrency-limit._id-B6oyPVya.js} +2 -2
  41. prefect/server/ui-v2/assets/{concurrency-limit._id-BHEt9viF.js.map → concurrency-limit._id-B6oyPVya.js.map} +1 -1
  42. prefect/server/ui-v2/assets/{create-BMxUOyN5.js → create-CcYMd6w6.js} +2 -2
  43. prefect/server/ui-v2/assets/{create-BMxUOyN5.js.map → create-CcYMd6w6.js.map} +1 -1
  44. prefect/server/ui-v2/assets/{create-Cq-EAHVk.js → create-DK1WvDhf.js} +2 -2
  45. prefect/server/ui-v2/assets/{create-Cq-EAHVk.js.map → create-DK1WvDhf.js.map} +1 -1
  46. prefect/server/ui-v2/assets/{data-table-Bw8TZx9D.js → data-table-B_iyrrTm.js} +2 -2
  47. prefect/server/ui-v2/assets/{data-table-Bw8TZx9D.js.map → data-table-B_iyrrTm.js.map} +1 -1
  48. prefect/server/ui-v2/assets/{delete-confirmation-dialog-CTdWZlGM.js → delete-confirmation-dialog-7GKqeKy1.js} +2 -2
  49. prefect/server/ui-v2/assets/{delete-confirmation-dialog-CTdWZlGM.js.map → delete-confirmation-dialog-7GKqeKy1.js.map} +1 -1
  50. prefect/server/ui-v2/assets/{deployment-action-header-BObYqmI_.js → deployment-action-header-DrvnfE9Y.js} +2 -2
  51. prefect/server/ui-v2/assets/{deployment-action-header-BObYqmI_.js.map → deployment-action-header-DrvnfE9Y.js.map} +1 -1
  52. prefect/server/ui-v2/assets/{deployment-form-CntyhRrK.js → deployment-form-DsAij22s.js} +3 -3
  53. prefect/server/ui-v2/assets/{deployment-form-CntyhRrK.js.map → deployment-form-DsAij22s.js.map} +1 -1
  54. prefect/server/ui-v2/assets/{deployment-links-DBUSCaxB.js → deployment-links-BwqfKWQX.js} +2 -2
  55. prefect/server/ui-v2/assets/{deployment-links-DBUSCaxB.js.map → deployment-links-BwqfKWQX.js.map} +1 -1
  56. prefect/server/ui-v2/assets/{deployment._id-BXanVFA8.js → deployment._id-E5e5s6bO.js} +2 -2
  57. prefect/server/ui-v2/assets/{deployment._id-BXanVFA8.js.map → deployment._id-E5e5s6bO.js.map} +1 -1
  58. prefect/server/ui-v2/assets/{deployment._id-Q5cvHMX9.js → deployment._id-U6KrtWw0.js} +2 -2
  59. prefect/server/ui-v2/assets/{deployment._id-Q5cvHMX9.js.map → deployment._id-U6KrtWw0.js.map} +1 -1
  60. prefect/server/ui-v2/assets/deployment_._id.duplicate-C_kNyCA9.js +2 -0
  61. prefect/server/ui-v2/assets/{deployment_._id.duplicate-DB-4hHHc.js.map → deployment_._id.duplicate-C_kNyCA9.js.map} +1 -1
  62. prefect/server/ui-v2/assets/deployment_._id.edit-BP8pfTOR.js +2 -0
  63. prefect/server/ui-v2/assets/{deployment_._id.edit-CWf1RIGy.js.map → deployment_._id.edit-BP8pfTOR.js.map} +1 -1
  64. prefect/server/ui-v2/assets/{deployment_._id.run-CoHGXFoM.js → deployment_._id.run-Di3-4Mtk.js} +2 -2
  65. prefect/server/ui-v2/assets/{deployment_._id.run-CoHGXFoM.js.map → deployment_._id.run-Di3-4Mtk.js.map} +1 -1
  66. prefect/server/ui-v2/assets/{dropdown-menu-CT-s-V7d.js → dropdown-menu-iS8iJMpx.js} +2 -2
  67. prefect/server/ui-v2/assets/{dropdown-menu-CT-s-V7d.js.map → dropdown-menu-iS8iJMpx.js.map} +1 -1
  68. prefect/server/ui-v2/assets/{event._eventDate._eventId-BITo_GYL.js → event._eventDate._eventId-CG15qDSZ.js} +2 -2
  69. prefect/server/ui-v2/assets/{event._eventDate._eventId-BITo_GYL.js.map → event._eventDate._eventId-CG15qDSZ.js.map} +1 -1
  70. prefect/server/ui-v2/assets/flow-run-graph-B1vF1w0Z.js +2 -0
  71. prefect/server/ui-v2/assets/flow-run-graph-B1vF1w0Z.js.map +1 -0
  72. prefect/server/ui-v2/assets/flow-run._id-BHY61H6u.js +4 -0
  73. prefect/server/ui-v2/assets/flow-run._id-BHY61H6u.js.map +1 -0
  74. prefect/server/ui-v2/assets/{flow-run._id-BtSgRDtA.js → flow-run._id-D_eAHZ5z.js} +2 -2
  75. prefect/server/ui-v2/assets/{flow-run._id-BtSgRDtA.js.map → flow-run._id-D_eAHZ5z.js.map} +1 -1
  76. prefect/server/ui-v2/assets/{flow-run._id-Bbm9OpDi.js → flow-run._id-wco0Q19f.js} +2 -2
  77. prefect/server/ui-v2/assets/{flow-run._id-Bbm9OpDi.js.map → flow-run._id-wco0Q19f.js.map} +1 -1
  78. prefect/server/ui-v2/assets/{flow-runs-pagination-LrU9Aio8.js → flow-runs-pagination-DzGHOht3.js} +2 -2
  79. prefect/server/ui-v2/assets/{flow-runs-pagination-LrU9Aio8.js.map → flow-runs-pagination-DzGHOht3.js.map} +1 -1
  80. prefect/server/ui-v2/assets/{flow._id-BJBRokk4.js → flow._id-Dn2so3rK.js} +2 -2
  81. prefect/server/ui-v2/assets/{flow._id-BJBRokk4.js.map → flow._id-Dn2so3rK.js.map} +1 -1
  82. prefect/server/ui-v2/assets/{form-CVSlEnl8.js → form-rC8pxeRl.js} +2 -2
  83. prefect/server/ui-v2/assets/{form-CVSlEnl8.js.map → form-rC8pxeRl.js.map} +1 -1
  84. prefect/server/ui-v2/assets/{header-4plZZheZ.js → header-C0zV3WDn.js} +2 -2
  85. prefect/server/ui-v2/assets/{header-4plZZheZ.js.map → header-C0zV3WDn.js.map} +1 -1
  86. prefect/server/ui-v2/assets/{header-D3uM8_xM.js → header-C6ko3O7G.js} +2 -2
  87. prefect/server/ui-v2/assets/{header-D3uM8_xM.js.map → header-C6ko3O7G.js.map} +1 -1
  88. prefect/server/ui-v2/assets/{header-9rXZ4r39.js → header-CuAwmJ64.js} +2 -2
  89. prefect/server/ui-v2/assets/{header-9rXZ4r39.js.map → header-CuAwmJ64.js.map} +1 -1
  90. prefect/server/ui-v2/assets/{index-6OsEYhIi.js → index-0g8aAM30.js} +2 -2
  91. prefect/server/ui-v2/assets/{index-6OsEYhIi.js.map → index-0g8aAM30.js.map} +1 -1
  92. prefect/server/ui-v2/assets/{index-BeoNC2tJ.js → index-BIqzfifB.js} +2 -2
  93. prefect/server/ui-v2/assets/{index-BeoNC2tJ.js.map → index-BIqzfifB.js.map} +1 -1
  94. prefect/server/ui-v2/assets/{index-ChIrfjIW.js → index-BKbBu9gL.js} +2 -2
  95. prefect/server/ui-v2/assets/{index-ChIrfjIW.js.map → index-BKbBu9gL.js.map} +1 -1
  96. prefect/server/ui-v2/assets/{index-h9-QgNjZ.js → index-BYQ1P2TC.js} +2 -2
  97. prefect/server/ui-v2/assets/{index-h9-QgNjZ.js.map → index-BYQ1P2TC.js.map} +1 -1
  98. prefect/server/ui-v2/assets/{index-DODEq1Pi.js → index-BdgomKuA.js} +2 -2
  99. prefect/server/ui-v2/assets/{index-DODEq1Pi.js.map → index-BdgomKuA.js.map} +1 -1
  100. prefect/server/ui-v2/assets/{index-DqCPbST9.js → index-Benf9xn3.js} +2 -2
  101. prefect/server/ui-v2/assets/{index-DqCPbST9.js.map → index-Benf9xn3.js.map} +1 -1
  102. prefect/server/ui-v2/assets/{index-B7xsJ-QH.js → index-BjsWjEUO.js} +2 -2
  103. prefect/server/ui-v2/assets/{index-B7xsJ-QH.js.map → index-BjsWjEUO.js.map} +1 -1
  104. prefect/server/ui-v2/assets/{index-DicK6p3K.js → index-C3D0Re7U.js} +2 -2
  105. prefect/server/ui-v2/assets/{index-DicK6p3K.js.map → index-C3D0Re7U.js.map} +1 -1
  106. prefect/server/ui-v2/assets/{index-BlpD74iH.js → index-CCs20W5W.js} +2 -2
  107. prefect/server/ui-v2/assets/{index-BlpD74iH.js.map → index-CCs20W5W.js.map} +1 -1
  108. prefect/server/ui-v2/assets/{index-udb79rgq.js → index-CEStyUb-.js} +2 -2
  109. prefect/server/ui-v2/assets/{index-udb79rgq.js.map → index-CEStyUb-.js.map} +1 -1
  110. prefect/server/ui-v2/assets/{index-tBdv6kBF.js → index-CYpFLd7y.js} +2 -2
  111. prefect/server/ui-v2/assets/{index-tBdv6kBF.js.map → index-CYpFLd7y.js.map} +1 -1
  112. prefect/server/ui-v2/assets/{index-CDyLkbVG.js → index-CcVSC2pV.js} +2 -2
  113. prefect/server/ui-v2/assets/{index-CDyLkbVG.js.map → index-CcVSC2pV.js.map} +1 -1
  114. prefect/server/ui-v2/assets/index-Cd7pM9pk.js +17 -0
  115. prefect/server/ui-v2/assets/index-Cd7pM9pk.js.map +1 -0
  116. prefect/server/ui-v2/assets/{index-DJyKqsFO.js → index-CotXErTe.js} +2 -2
  117. prefect/server/ui-v2/assets/{index-DJyKqsFO.js.map → index-CotXErTe.js.map} +1 -1
  118. prefect/server/ui-v2/assets/{index-DxPoKag8.js → index-D8fZaZa7.js} +2 -2
  119. prefect/server/ui-v2/assets/{index-DxPoKag8.js.map → index-D8fZaZa7.js.map} +1 -1
  120. prefect/server/ui-v2/assets/{index-D6GJ4go1.js → index-DB2qeheX.js} +2 -2
  121. prefect/server/ui-v2/assets/{index-D6GJ4go1.js.map → index-DB2qeheX.js.map} +1 -1
  122. prefect/server/ui-v2/assets/{index-CzCSgCK-.js → index-DvKYj8ko.js} +2 -2
  123. prefect/server/ui-v2/assets/{index-CzCSgCK-.js.map → index-DvKYj8ko.js.map} +1 -1
  124. prefect/server/ui-v2/assets/{index-BfJLUM7N.js → index-DwkedbVy.js} +2 -2
  125. prefect/server/ui-v2/assets/{index-BfJLUM7N.js.map → index-DwkedbVy.js.map} +1 -1
  126. prefect/server/ui-v2/assets/index-b9WBW430.css +1 -0
  127. prefect/server/ui-v2/assets/{index-CDwJvjUM.js → index-fhrsIceD.js} +2 -2
  128. prefect/server/ui-v2/assets/{index-CDwJvjUM.js.map → index-fhrsIceD.js.map} +1 -1
  129. prefect/server/ui-v2/assets/{index-D5v9S-lB.js → index-k2161reF.js} +2 -2
  130. prefect/server/ui-v2/assets/{index-D5v9S-lB.js.map → index-k2161reF.js.map} +1 -1
  131. prefect/server/ui-v2/assets/{index-Bj0OOguP.js → index-pE_31vXF.js} +2 -2
  132. prefect/server/ui-v2/assets/{index-Bj0OOguP.js.map → index-pE_31vXF.js.map} +1 -1
  133. prefect/server/ui-v2/assets/{json-input-Dt1icmrn.js → json-input-C9dkBSdc.js} +2 -2
  134. prefect/server/ui-v2/assets/{json-input-Dt1icmrn.js.map → json-input-C9dkBSdc.js.map} +1 -1
  135. prefect/server/ui-v2/assets/{key._key-Cyh5MBX_.js → key._key-BBVH44_R.js} +2 -2
  136. prefect/server/ui-v2/assets/{key._key-Cyh5MBX_.js.map → key._key-BBVH44_R.js.map} +1 -1
  137. prefect/server/ui-v2/assets/{lazy-markdown-BwIwKFRF.js → lazy-markdown-BoMKGRXo.js} +2 -2
  138. prefect/server/ui-v2/assets/{lazy-markdown-BwIwKFRF.js.map → lazy-markdown-BoMKGRXo.js.map} +1 -1
  139. prefect/server/ui-v2/assets/{login-DKXFVSwk.js → login-BmmIDesJ.js} +2 -2
  140. prefect/server/ui-v2/assets/{login-DKXFVSwk.js.map → login-BmmIDesJ.js.map} +1 -1
  141. prefect/server/ui-v2/assets/{markdown-input-Dp0mBlkV.js → markdown-input-C6P8cYT1.js} +2 -2
  142. prefect/server/ui-v2/assets/{markdown-input-Dp0mBlkV.js.map → markdown-input-C6P8cYT1.js.map} +1 -1
  143. prefect/server/ui-v2/assets/{python-example-snippet-BYwPjHI5.js → python-example-snippet-DPumgTpL.js} +3 -3
  144. prefect/server/ui-v2/assets/{python-example-snippet-BYwPjHI5.js.map → python-example-snippet-DPumgTpL.js.map} +1 -1
  145. prefect/server/ui-v2/assets/{python-input-y26XMqXw.js → python-input-DX4uV8MF.js} +2 -2
  146. prefect/server/ui-v2/assets/{python-input-y26XMqXw.js.map → python-input-DX4uV8MF.js.map} +1 -1
  147. prefect/server/ui-v2/assets/{radio-group-D0van45v.js → radio-group-DeNK-Ob0.js} +2 -2
  148. prefect/server/ui-v2/assets/{radio-group-D0van45v.js.map → radio-group-DeNK-Ob0.js.map} +1 -1
  149. prefect/server/ui-v2/assets/{route-error-state-CGGpuCGN.js → route-error-state-C9CbByMx.js} +2 -2
  150. prefect/server/ui-v2/assets/{route-error-state-CGGpuCGN.js.map → route-error-state-C9CbByMx.js.map} +1 -1
  151. prefect/server/ui-v2/assets/{schema-form-2tg5SXM4.js → schema-form-B45xnsnK.js} +2 -2
  152. prefect/server/ui-v2/assets/{schema-form-2tg5SXM4.js.map → schema-form-B45xnsnK.js.map} +1 -1
  153. prefect/server/ui-v2/assets/{schema-form-input-string-format-datetime-CZt6AJ4z.js → schema-form-input-string-format-datetime-BJj81bu-.js} +4 -4
  154. prefect/server/ui-v2/assets/{schema-form-input-string-format-datetime-CZt6AJ4z.js.map → schema-form-input-string-format-datetime-BJj81bu-.js.map} +1 -1
  155. prefect/server/ui-v2/assets/{settings-DDUadk_N.js → settings-CbkeWqQ9.js} +2 -2
  156. prefect/server/ui-v2/assets/{settings-DDUadk_N.js.map → settings-CbkeWqQ9.js.map} +1 -1
  157. prefect/server/ui-v2/assets/{sort-filter-D9p3cPx9.js → sort-filter-DM7SvBB0.js} +2 -2
  158. prefect/server/ui-v2/assets/{sort-filter-D9p3cPx9.js.map → sort-filter-DM7SvBB0.js.map} +1 -1
  159. prefect/server/ui-v2/assets/{table-vo9Do8sA.js → table-CEPo6xb_.js} +2 -2
  160. prefect/server/ui-v2/assets/{table-vo9Do8sA.js.map → table-CEPo6xb_.js.map} +1 -1
  161. prefect/server/ui-v2/assets/{tags-input-Ci2JQ-k3.js → tags-input-DJiZSVHp.js} +2 -2
  162. prefect/server/ui-v2/assets/{tags-input-Ci2JQ-k3.js.map → tags-input-DJiZSVHp.js.map} +1 -1
  163. prefect/server/ui-v2/assets/{task-run-concurrency-limits-reset-dialog-CJzPc2gw.js → task-run-concurrency-limits-reset-dialog-vJEkvqWp.js} +2 -2
  164. prefect/server/ui-v2/assets/{task-run-concurrency-limits-reset-dialog-CJzPc2gw.js.map → task-run-concurrency-limits-reset-dialog-vJEkvqWp.js.map} +1 -1
  165. prefect/server/ui-v2/assets/{task-run._id-D8QKG5UZ.js → task-run._id-BCnDnXrL.js} +2 -2
  166. prefect/server/ui-v2/assets/{task-run._id-D8QKG5UZ.js.map → task-run._id-BCnDnXrL.js.map} +1 -1
  167. prefect/server/ui-v2/assets/{task-run._id-CjevSs79.js → task-run._id-ByJw1K82.js} +2 -2
  168. prefect/server/ui-v2/assets/{task-run._id-CjevSs79.js.map → task-run._id-ByJw1K82.js.map} +1 -1
  169. prefect/server/ui-v2/assets/{task-runs-pagination-CifoSGct.js → task-runs-pagination-DbjB6XnY.js} +2 -2
  170. prefect/server/ui-v2/assets/{task-runs-pagination-CifoSGct.js.map → task-runs-pagination-DbjB6XnY.js.map} +1 -1
  171. prefect/server/ui-v2/assets/{textarea-BAtfAxtV.js → textarea-BX8KbLGx.js} +2 -2
  172. prefect/server/ui-v2/assets/{textarea-BAtfAxtV.js.map → textarea-BX8KbLGx.js.map} +1 -1
  173. prefect/server/ui-v2/assets/{timezone-select-QlQTZSsF.js → timezone-select-TBj2n6Ox.js} +2 -2
  174. prefect/server/ui-v2/assets/{timezone-select-QlQTZSsF.js.map → timezone-select-TBj2n6Ox.js.map} +1 -1
  175. prefect/server/ui-v2/assets/{toggle-group-BJN1vjEh.js → toggle-group-D7mfSUim.js} +2 -2
  176. prefect/server/ui-v2/assets/{toggle-group-BJN1vjEh.js.map → toggle-group-D7mfSUim.js.map} +1 -1
  177. prefect/server/ui-v2/assets/{use-delete-automation-confirmation-dialog-eOWJYPkD.js → use-delete-automation-confirmation-dialog-BpBSjz60.js} +2 -2
  178. prefect/server/ui-v2/assets/{use-delete-automation-confirmation-dialog-eOWJYPkD.js.map → use-delete-automation-confirmation-dialog-BpBSjz60.js.map} +1 -1
  179. prefect/server/ui-v2/assets/{use-delete-block-document-confirmation-dialog-BTwSeHRM.js → use-delete-block-document-confirmation-dialog-BjKsNw6b.js} +2 -2
  180. prefect/server/ui-v2/assets/{use-delete-block-document-confirmation-dialog-BTwSeHRM.js.map → use-delete-block-document-confirmation-dialog-BjKsNw6b.js.map} +1 -1
  181. prefect/server/ui-v2/assets/{use-flow-runs-selected-rows-BL_Gv9CC.js → use-flow-runs-selected-rows-B_BlBMic.js} +2 -2
  182. prefect/server/ui-v2/assets/{use-flow-runs-selected-rows-BL_Gv9CC.js.map → use-flow-runs-selected-rows-B_BlBMic.js.map} +1 -1
  183. prefect/server/ui-v2/assets/{use-get-artifacts-flow-task-runs-TSCoomjQ.js → use-get-artifacts-flow-task-runs-BfE433bC.js} +2 -2
  184. prefect/server/ui-v2/assets/{use-get-artifacts-flow-task-runs-TSCoomjQ.js.map → use-get-artifacts-flow-task-runs-BfE433bC.js.map} +1 -1
  185. prefect/server/ui-v2/assets/{use-quick-run-BMnCkwSv.js → use-quick-run-qrtcF-DD.js} +2 -2
  186. prefect/server/ui-v2/assets/{use-quick-run-BMnCkwSv.js.map → use-quick-run-qrtcF-DD.js.map} +1 -1
  187. prefect/server/ui-v2/assets/{use-stepper-C1wm66U2.js → use-stepper-CVy1_GBw.js} +2 -2
  188. prefect/server/ui-v2/assets/{use-stepper-C1wm66U2.js.map → use-stepper-CVy1_GBw.js.map} +1 -1
  189. prefect/server/ui-v2/assets/{utilities-DxRXxFOF.js → utilities-D5-00wjP.js} +2 -2
  190. prefect/server/ui-v2/assets/{utilities-DxRXxFOF.js.map → utilities-D5-00wjP.js.map} +1 -1
  191. prefect/server/ui-v2/assets/{vendor-graphs-Diy0Lo-N.js → vendor-graphs-R8z6S3Jg.js} +2 -2
  192. prefect/server/ui-v2/assets/{vendor-graphs-Diy0Lo-N.js.map → vendor-graphs-R8z6S3Jg.js.map} +1 -1
  193. prefect/server/ui-v2/assets/{work-pool-filter-PudrkZYj.js → work-pool-filter-D8MkTbSW.js} +2 -2
  194. prefect/server/ui-v2/assets/{work-pool-filter-PudrkZYj.js.map → work-pool-filter-D8MkTbSW.js.map} +1 -1
  195. prefect/server/ui-v2/assets/{work-pool-queue-toggle-BAOrV_0R.js → work-pool-queue-toggle-CbI7Gfu5.js} +2 -2
  196. prefect/server/ui-v2/assets/{work-pool-queue-toggle-BAOrV_0R.js.map → work-pool-queue-toggle-CbI7Gfu5.js.map} +1 -1
  197. prefect/server/ui-v2/assets/{work-pool._workPoolName-BOM3849e.js → work-pool._workPoolName-CCzzgVV2.js} +2 -2
  198. prefect/server/ui-v2/assets/{work-pool._workPoolName-BOM3849e.js.map → work-pool._workPoolName-CCzzgVV2.js.map} +1 -1
  199. prefect/server/ui-v2/assets/{work-pool_._workPoolName.edit-CIhcG6yr.js → work-pool_._workPoolName.edit-BAgiuU_j.js} +2 -2
  200. prefect/server/ui-v2/assets/{work-pool_._workPoolName.edit-CIhcG6yr.js.map → work-pool_._workPoolName.edit-BAgiuU_j.js.map} +1 -1
  201. prefect/server/ui-v2/assets/{work-pool_._workPoolName.queue._workQueueName-CjoM77tu.js → work-pool_._workPoolName.queue._workQueueName-BUawWJEy.js} +2 -2
  202. prefect/server/ui-v2/assets/{work-pool_._workPoolName.queue._workQueueName-CjoM77tu.js.map → work-pool_._workPoolName.queue._workQueueName-BUawWJEy.js.map} +1 -1
  203. prefect/server/ui-v2/assets/{work-queue-icon-text-CP4yX3uM.js → work-queue-icon-text-D_G_UCJX.js} +2 -2
  204. prefect/server/ui-v2/assets/{work-queue-icon-text-CP4yX3uM.js.map → work-queue-icon-text-D_G_UCJX.js.map} +1 -1
  205. prefect/server/ui-v2/index.html +2 -2
  206. prefect/settings/models/flows.py +14 -1
  207. prefect/settings/models/runner.py +16 -6
  208. prefect/task_engine.py +1 -3
  209. prefect/task_worker.py +1 -1
  210. prefect/tasks.py +2 -2
  211. prefect/testing/fixtures.py +23 -5
  212. {prefect-3.6.13.dev2.dist-info → prefect-3.6.14.dev1.dist-info}/METADATA +1 -1
  213. {prefect-3.6.13.dev2.dist-info → prefect-3.6.14.dev1.dist-info}/RECORD +216 -216
  214. prefect/server/ui-v2/assets/block-type-logo-WQNm0PzP.js +0 -2
  215. prefect/server/ui-v2/assets/deployment_._id.duplicate-DB-4hHHc.js +0 -2
  216. prefect/server/ui-v2/assets/deployment_._id.edit-CWf1RIGy.js +0 -2
  217. prefect/server/ui-v2/assets/flow-run-graph-DxIl6fzW.js +0 -2
  218. prefect/server/ui-v2/assets/flow-run-graph-DxIl6fzW.js.map +0 -1
  219. prefect/server/ui-v2/assets/flow-run._id-DJuMECRh.js +0 -4
  220. prefect/server/ui-v2/assets/flow-run._id-DJuMECRh.js.map +0 -1
  221. prefect/server/ui-v2/assets/index-BvSl3DKP.js +0 -17
  222. prefect/server/ui-v2/assets/index-BvSl3DKP.js.map +0 -1
  223. prefect/server/ui-v2/assets/index-NY089eTx.css +0 -1
  224. {prefect-3.6.13.dev2.dist-info → prefect-3.6.14.dev1.dist-info}/WHEEL +0 -0
  225. {prefect-3.6.13.dev2.dist-info → prefect-3.6.14.dev1.dist-info}/entry_points.txt +0 -0
  226. {prefect-3.6.13.dev2.dist-info → prefect-3.6.14.dev1.dist-info}/licenses/LICENSE +0 -0
prefect/_build_info.py CHANGED
@@ -1,5 +1,5 @@
1
1
  # Generated by versioningit
2
- __version__ = "3.6.13.dev2"
3
- __build_date__ = "2026-01-22 08:12:37.989944+00:00"
4
- __git_commit__ = "3216a18c97baecb25fe70d3d46a93eb56ebd2adc"
2
+ __version__ = "3.6.14.dev1"
3
+ __build_date__ = "2026-01-23 08:12:06.479550+00:00"
4
+ __git_commit__ = "61276aac1e484a94f570b66a73d5dd6b3eeee5ea"
5
5
  __dirty__ = False
@@ -4,6 +4,24 @@ from typing import Any, Union
4
4
  from prefect.filesystems import NullFileSystem, WritableFileSystem
5
5
 
6
6
 
7
+ def call_explicitly_sync_block_method(
8
+ block: Union[WritableFileSystem, NullFileSystem],
9
+ method: str,
10
+ args: tuple[Any, ...],
11
+ kwargs: dict[str, Any],
12
+ ) -> Any:
13
+ """
14
+ Call a block method synchronously.
15
+
16
+ TODO: remove this once we have explicit sync/async methods on all storage blocks
17
+
18
+ see https://github.com/PrefectHQ/prefect/issues/15008
19
+ """
20
+ # Pass _sync=True to ensure we get synchronous execution even when called
21
+ # from an async context (e.g., within a sync flow running in an async test)
22
+ return getattr(block, method)(*args, _sync=True, **kwargs)
23
+
24
+
7
25
  async def call_explicitly_async_block_method(
8
26
  block: Union[WritableFileSystem, NullFileSystem],
9
27
  method: str,
@@ -281,6 +281,27 @@ class FlowRunFilterIdempotencyKey(PrefectBaseModel):
281
281
  )
282
282
 
283
283
 
284
+ class FlowRunFilterCreatedBy(PrefectBaseModel, OperatorMixin):
285
+ """Filter by `FlowRun.created_by`."""
286
+
287
+ id_: Optional[List[UUID]] = Field(
288
+ default=None,
289
+ description="A list of creator IDs to include",
290
+ )
291
+ type_: Optional[List[str]] = Field(
292
+ default=None,
293
+ description=(
294
+ "A list of creator types to include. For example, 'DEPLOYMENT' for "
295
+ "scheduled runs or 'AUTOMATION' for runs triggered by automations."
296
+ ),
297
+ examples=[["DEPLOYMENT", "AUTOMATION"]],
298
+ )
299
+ is_null_: Optional[bool] = Field(
300
+ default=None,
301
+ description="If true, only include flow runs without a creator",
302
+ )
303
+
304
+
284
305
  class FlowRunFilter(PrefectBaseModel, OperatorMixin):
285
306
  """Filter flow runs. Only flow runs matching all criteria will be returned"""
286
307
 
@@ -324,6 +345,9 @@ class FlowRunFilter(PrefectBaseModel, OperatorMixin):
324
345
  idempotency_key: Optional[FlowRunFilterIdempotencyKey] = Field(
325
346
  default=None, description="Filter criteria for `FlowRun.idempotency_key`"
326
347
  )
348
+ created_by: Optional[FlowRunFilterCreatedBy] = Field(
349
+ default=None, description="Filter criteria for `FlowRun.created_by`"
350
+ )
327
351
 
328
352
 
329
353
  class TaskRunFilterFlowRunId(PrefectBaseModel):
prefect/flow_engine.py CHANGED
@@ -5,6 +5,7 @@ import logging
5
5
  import multiprocessing
6
6
  import multiprocessing.context
7
7
  import os
8
+ import threading
8
9
  import time
9
10
  from contextlib import (
10
11
  AsyncExitStack,
@@ -36,7 +37,7 @@ from anyio import CancelScope
36
37
  from opentelemetry import propagate, trace
37
38
  from typing_extensions import ParamSpec
38
39
 
39
- from prefect import Task
40
+ from prefect import Task, __version__
40
41
  from prefect.client.orchestration import PrefectClient, SyncPrefectClient, get_client
41
42
  from prefect.client.schemas import FlowRun, TaskRun
42
43
  from prefect.client.schemas.filters import FlowRunFilter
@@ -60,6 +61,8 @@ from prefect.context import (
60
61
  serialize_context,
61
62
  )
62
63
  from prefect.engine import handle_engine_signals
64
+ from prefect.events.related import RelatedResource, tags_as_related_resources
65
+ from prefect.events.utilities import emit_event
63
66
  from prefect.exceptions import (
64
67
  Abort,
65
68
  MissingFlowError,
@@ -161,6 +164,129 @@ def load_flow_and_flow_run(flow_run_id: UUID) -> tuple[FlowRun, Flow[..., Any]]:
161
164
  return flow_run, flow
162
165
 
163
166
 
167
+ @contextmanager
168
+ def send_heartbeats_sync(
169
+ engine: "FlowRunEngine[Any, Any]",
170
+ ) -> Generator[None, None, None]:
171
+ """Context manager that maintains heartbeats for a sync flow run.
172
+
173
+ Heartbeats are emitted at regular intervals while the flow is running.
174
+ The loop checks the flow run state before each heartbeat and stops
175
+ if the run reaches a terminal state.
176
+
177
+ Args:
178
+ engine: The FlowRunEngine instance to emit heartbeats for.
179
+
180
+ Yields:
181
+ None
182
+ """
183
+ heartbeat_seconds = engine.heartbeat_seconds
184
+ if heartbeat_seconds is None:
185
+ yield
186
+ return
187
+
188
+ stop_event = threading.Event()
189
+
190
+ def heartbeat_loop() -> None:
191
+ while not stop_event.is_set():
192
+ # Check state before emitting - don't emit if final
193
+ if (
194
+ engine.flow_run
195
+ and engine.flow_run.state
196
+ and engine.flow_run.state.is_final()
197
+ ):
198
+ engine.logger.debug("Flow run in terminal state, stopping heartbeat")
199
+ return
200
+
201
+ try:
202
+ engine._emit_flow_run_heartbeat()
203
+ except Exception:
204
+ engine.logger.debug("Failed to emit heartbeat", exc_info=True)
205
+
206
+ # Sleep in increments to allow quick shutdown
207
+ for _ in range(heartbeat_seconds):
208
+ if stop_event.is_set():
209
+ return
210
+ time.sleep(1)
211
+
212
+ thread = threading.Thread(target=heartbeat_loop, daemon=True)
213
+ thread.start()
214
+ engine.logger.debug("Started flow run heartbeat context")
215
+
216
+ try:
217
+ yield
218
+ finally:
219
+ stop_event.set()
220
+ thread.join(timeout=2)
221
+ engine.logger.debug("Stopped flow run heartbeat context")
222
+
223
+
224
+ @asynccontextmanager
225
+ async def send_heartbeats_async(
226
+ engine: "AsyncFlowRunEngine[Any, Any]",
227
+ ) -> AsyncGenerator[None, None]:
228
+ """Async context manager that maintains heartbeats for an async flow run.
229
+
230
+ Heartbeats are emitted at regular intervals while the flow is running.
231
+ The loop checks the flow run state before each heartbeat and stops
232
+ if the run reaches a terminal state.
233
+
234
+ Args:
235
+ engine: The AsyncFlowRunEngine instance to emit heartbeats for.
236
+
237
+ Yields:
238
+ None
239
+ """
240
+ heartbeat_seconds = engine.heartbeat_seconds
241
+ if heartbeat_seconds is None:
242
+ yield
243
+ return
244
+
245
+ stop_flag = False
246
+
247
+ async def heartbeat_loop() -> None:
248
+ nonlocal stop_flag
249
+ try:
250
+ while not stop_flag:
251
+ # Check state before emitting - don't emit if final
252
+ if (
253
+ engine.flow_run
254
+ and engine.flow_run.state
255
+ and engine.flow_run.state.is_final()
256
+ ):
257
+ engine.logger.debug(
258
+ "Flow run in terminal state, stopping heartbeat"
259
+ )
260
+ return
261
+
262
+ try:
263
+ engine._emit_flow_run_heartbeat()
264
+ except Exception:
265
+ engine.logger.debug("Failed to emit heartbeat", exc_info=True)
266
+
267
+ # Sleep in increments to allow quick shutdown (parity with sync version)
268
+ for _ in range(heartbeat_seconds):
269
+ if stop_flag:
270
+ return
271
+ await asyncio.sleep(1)
272
+ except asyncio.CancelledError:
273
+ engine.logger.debug("Heartbeat loop cancelled")
274
+
275
+ task = asyncio.create_task(heartbeat_loop())
276
+ engine.logger.debug("Started flow run heartbeat context")
277
+
278
+ try:
279
+ yield
280
+ finally:
281
+ stop_flag = True
282
+ task.cancel()
283
+ try:
284
+ await task
285
+ except asyncio.CancelledError:
286
+ pass
287
+ engine.logger.debug("Stopped flow run heartbeat context")
288
+
289
+
164
290
  @dataclass
165
291
  class BaseFlowRunEngine(Generic[P, R]):
166
292
  flow: Union[Flow[P, R], Flow[P, Coroutine[Any, Any, R]]]
@@ -200,10 +326,59 @@ class BaseFlowRunEngine(Generic[P, R]):
200
326
  return False # TODO: handle this differently?
201
327
  return getattr(self, "flow_run").state.is_pending()
202
328
 
329
+ @property
330
+ def heartbeat_seconds(self) -> Optional[int]:
331
+ """Get the heartbeat interval from settings."""
332
+ return get_current_settings().flows.heartbeat_frequency
333
+
203
334
  def cancel_all_tasks(self) -> None:
204
335
  if hasattr(self.flow.task_runner, "cancel_all"):
205
336
  self.flow.task_runner.cancel_all() # type: ignore
206
337
 
338
+ def _emit_flow_run_heartbeat(self) -> None:
339
+ """Emit a heartbeat event for the current flow run."""
340
+ if not self.flow_run:
341
+ return
342
+
343
+ related: list[RelatedResource] = []
344
+ tags: list[str] = list(self.flow_run.tags or [])
345
+
346
+ # Add flow as related resource using flow_id for consistency with other events
347
+ if self.flow_run.flow_id:
348
+ related.append(
349
+ RelatedResource.model_validate(
350
+ {
351
+ "prefect.resource.id": f"prefect.flow.{self.flow_run.flow_id}",
352
+ "prefect.resource.role": "flow",
353
+ "prefect.resource.name": self.flow.name if self.flow else "",
354
+ }
355
+ )
356
+ )
357
+
358
+ # Add deployment as related resource if available
359
+ # Note: deployment name is not available on flow_run without an API call
360
+ if self.flow_run.deployment_id:
361
+ related.append(
362
+ RelatedResource.model_validate(
363
+ {
364
+ "prefect.resource.id": f"prefect.deployment.{self.flow_run.deployment_id}",
365
+ "prefect.resource.role": "deployment",
366
+ }
367
+ )
368
+ )
369
+
370
+ related += tags_as_related_resources(set(tags))
371
+
372
+ emit_event(
373
+ event="prefect.flow-run.heartbeat",
374
+ resource={
375
+ "prefect.resource.id": f"prefect.flow-run.{self.flow_run.id}",
376
+ "prefect.resource.name": self.flow_run.name or "",
377
+ "prefect.version": __version__,
378
+ },
379
+ related=related,
380
+ )
381
+
207
382
  def _update_otel_labels(
208
383
  self, span: trace.Span, client: Union[SyncPrefectClient, PrefectClient]
209
384
  ):
@@ -343,6 +518,7 @@ class FlowRunEngine(BaseFlowRunEngine[P, R]):
343
518
 
344
519
  self._telemetry.update_state(state)
345
520
  self.call_hooks(state)
521
+
346
522
  return state
347
523
 
348
524
  def result(self, raise_on_failure: bool = True) -> "Union[R, State, None]":
@@ -791,10 +967,11 @@ class FlowRunEngine(BaseFlowRunEngine[P, R]):
791
967
  seconds=self.flow.timeout_seconds,
792
968
  timeout_exc_type=FlowRunTimeoutError,
793
969
  ):
794
- self.logger.debug(
795
- f"Executing flow {self.flow.name!r} for flow run {self.flow_run.name!r}..."
796
- )
797
- yield self
970
+ with send_heartbeats_sync(self):
971
+ self.logger.debug(
972
+ f"Executing flow {self.flow.name!r} for flow run {self.flow_run.name!r}..."
973
+ )
974
+ yield self
798
975
  except TimeoutError as exc:
799
976
  self.handle_timeout(exc)
800
977
  except Exception as exc:
@@ -930,6 +1107,7 @@ class AsyncFlowRunEngine(BaseFlowRunEngine[P, R]):
930
1107
 
931
1108
  self._telemetry.update_state(state)
932
1109
  await self.call_hooks(state)
1110
+
933
1111
  return state
934
1112
 
935
1113
  async def result(self, raise_on_failure: bool = True) -> "Union[R, State, None]":
@@ -1381,10 +1559,11 @@ class AsyncFlowRunEngine(BaseFlowRunEngine[P, R]):
1381
1559
  seconds=self.flow.timeout_seconds,
1382
1560
  timeout_exc_type=FlowRunTimeoutError,
1383
1561
  ):
1384
- self.logger.debug(
1385
- f"Executing flow {self.flow.name!r} for flow run {self.flow_run.name!r}..."
1386
- )
1387
- yield self
1562
+ async with send_heartbeats_async(self):
1563
+ self.logger.debug(
1564
+ f"Executing flow {self.flow.name!r} for flow run {self.flow_run.name!r}..."
1565
+ )
1566
+ yield self
1388
1567
  except TimeoutError as exc:
1389
1568
  await self.handle_timeout(exc)
1390
1569
  except Exception as exc:
@@ -1614,6 +1793,7 @@ def run_flow_in_subprocess(
1614
1793
  parameters: dict[str, Any] | None = None,
1615
1794
  wait_for: Iterable[PrefectFuture[Any]] | None = None,
1616
1795
  context: dict[str, Any] | None = None,
1796
+ env: dict[str, str] | None = None,
1617
1797
  ) -> multiprocessing.context.SpawnProcess:
1618
1798
  """
1619
1799
  Run a flow in a subprocess.
@@ -1630,6 +1810,7 @@ def run_flow_in_subprocess(
1630
1810
  the current context will be used. A serialized context should be provided if
1631
1811
  this function is called in a separate memory space from the parent run (e.g.
1632
1812
  in a subprocess or on another machine).
1813
+ env: Additional environment variables to set in the subprocess.
1633
1814
 
1634
1815
  Returns:
1635
1816
  A multiprocessing.context.SpawnProcess representing the process that is running the flow.
@@ -1672,7 +1853,8 @@ def run_flow_in_subprocess(
1672
1853
  | {
1673
1854
  # TODO: make this a thing we can pass into the engine
1674
1855
  "PREFECT__ENABLE_CANCELLATION_AND_CRASHED_HOOKS": "false",
1675
- },
1856
+ }
1857
+ | (env or {}),
1676
1858
  flow=flow,
1677
1859
  flow_run=flow_run,
1678
1860
  parameters=parameters,
prefect/flows.py CHANGED
@@ -1717,8 +1717,7 @@ class Flow(Generic[P, R]):
1717
1717
  return_type=return_type,
1718
1718
  )
1719
1719
 
1720
- @sync_compatible
1721
- async def visualize(self, *args: "P.args", **kwargs: "P.kwargs"):
1720
+ async def avisualize(self, *args: "P.args", **kwargs: "P.kwargs") -> None:
1722
1721
  """
1723
1722
  Generates a graphviz object representing the current flow. In IPython notebooks,
1724
1723
  it's rendered inline, otherwise in a new window as a PNG.
@@ -1776,6 +1775,66 @@ class Flow(Generic[P, R]):
1776
1775
  new_exception.__traceback__ = e.__traceback__
1777
1776
  raise new_exception
1778
1777
 
1778
+ @async_dispatch(avisualize)
1779
+ def visualize(self, *args: "P.args", **kwargs: "P.kwargs") -> None:
1780
+ """
1781
+ Generates a graphviz object representing the current flow. In IPython notebooks,
1782
+ it's rendered inline, otherwise in a new window as a PNG.
1783
+
1784
+ Raises:
1785
+ - ImportError: If `graphviz` isn't installed.
1786
+ - GraphvizExecutableNotFoundError: If the `dot` executable isn't found.
1787
+ - FlowVisualizationError: If the flow can't be visualized for any other reason.
1788
+ """
1789
+ from prefect.utilities.visualization import (
1790
+ FlowVisualizationError,
1791
+ GraphvizExecutableNotFoundError,
1792
+ GraphvizImportError,
1793
+ TaskVizTracker,
1794
+ VisualizationUnsupportedError,
1795
+ build_task_dependencies,
1796
+ visualize_task_dependencies,
1797
+ )
1798
+
1799
+ if not PREFECT_TESTING_UNIT_TEST_MODE:
1800
+ warnings.warn(
1801
+ "`flow.visualize()` will execute code inside of your flow that is not"
1802
+ " decorated with `@task` or `@flow`."
1803
+ )
1804
+
1805
+ try:
1806
+ with TaskVizTracker() as tracker:
1807
+ if self.isasync:
1808
+ # Run async flow via event loop
1809
+ run_coro_as_sync(self.fn(*args, **kwargs))
1810
+ else:
1811
+ self.fn(*args, **kwargs)
1812
+
1813
+ graph = build_task_dependencies(tracker)
1814
+
1815
+ visualize_task_dependencies(graph, self.name)
1816
+
1817
+ except GraphvizImportError:
1818
+ raise
1819
+ except GraphvizExecutableNotFoundError:
1820
+ raise
1821
+ except VisualizationUnsupportedError:
1822
+ raise
1823
+ except FlowVisualizationError:
1824
+ raise
1825
+ except Exception as e:
1826
+ msg = (
1827
+ "It's possible you are trying to visualize a flow that contains "
1828
+ "code that directly interacts with the result of a task"
1829
+ " inside of the flow. \nTry passing a `viz_return_value` "
1830
+ "to the task decorator, e.g. `@task(viz_return_value=[1, 2, 3]).`"
1831
+ )
1832
+
1833
+ new_exception = type(e)(str(e) + "\n" + msg)
1834
+ # Copy traceback information from the original exception
1835
+ new_exception.__traceback__ = e.__traceback__
1836
+ raise new_exception
1837
+
1779
1838
 
1780
1839
  class FlowDecorator:
1781
1840
  @overload