prefect 3.6.14.dev7__py3-none-any.whl → 3.6.16.dev2__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 (262) hide show
  1. prefect/__init__.py +20 -0
  2. prefect/_build_info.py +3 -3
  3. prefect/_internal/analytics/__init__.py +80 -0
  4. prefect/_internal/analytics/_config.py +2 -0
  5. prefect/_internal/analytics/ci_detection.py +39 -0
  6. prefect/_internal/analytics/client.py +132 -0
  7. prefect/_internal/analytics/device_id.py +55 -0
  8. prefect/_internal/analytics/emit.py +90 -0
  9. prefect/_internal/analytics/enabled.py +33 -0
  10. prefect/_internal/analytics/events.py +14 -0
  11. prefect/_internal/analytics/milestones.py +177 -0
  12. prefect/_internal/analytics/notice.py +60 -0
  13. prefect/_internal/analytics/service.py +238 -0
  14. prefect/analytics/__init__.py +67 -0
  15. prefect/deployments/runner.py +20 -0
  16. prefect/events/clients.py +40 -21
  17. prefect/flow_engine.py +16 -0
  18. prefect/flows.py +8 -0
  19. prefect/server/api/concurrency_limits_v2.py +5 -3
  20. prefect/server/ui-v2/assets/{artifact-card-9Cw_dMVb.js → artifact-card-BclosG8t.js} +2 -2
  21. prefect/server/ui-v2/assets/{artifact-card-9Cw_dMVb.js.map → artifact-card-BclosG8t.js.map} +1 -1
  22. prefect/server/ui-v2/assets/artifact._id-C0r4BJr2.js +2 -0
  23. prefect/server/ui-v2/assets/artifact._id-C0r4BJr2.js.map +1 -0
  24. prefect/server/ui-v2/assets/{automation-wizard-D7nVgckT.js → automation-wizard-Bmgt6nn8.js} +2 -2
  25. prefect/server/ui-v2/assets/{automation-wizard-D7nVgckT.js.map → automation-wizard-Bmgt6nn8.js.map} +1 -1
  26. prefect/server/ui-v2/assets/automation._id-Ccke3KJz.js +2 -0
  27. prefect/server/ui-v2/assets/{automation._id-BhEFaDc6.js.map → automation._id-Ccke3KJz.js.map} +1 -1
  28. prefect/server/ui-v2/assets/{automation_._id.edit-CffnUlbj.js → automation_._id.edit-BlKPUTVf.js} +2 -2
  29. prefect/server/ui-v2/assets/{automation_._id.edit-CffnUlbj.js.map → automation_._id.edit-BlKPUTVf.js.map} +1 -1
  30. prefect/server/ui-v2/assets/{automations-header-qb94agIp.js → automations-header-Df2zw3SC.js} +2 -2
  31. prefect/server/ui-v2/assets/{automations-header-qb94agIp.js.map → automations-header-Df2zw3SC.js.map} +1 -1
  32. prefect/server/ui-v2/assets/{base-job-template-form-section-DdDSFAJa.js → base-job-template-form-section-oZD6U-RW.js} +2 -2
  33. prefect/server/ui-v2/assets/{base-job-template-form-section-DdDSFAJa.js.map → base-job-template-form-section-oZD6U-RW.js.map} +1 -1
  34. prefect/server/ui-v2/assets/{block-type-details-2rIqbqoZ.js → block-type-details-CYrdaLot.js} +2 -2
  35. prefect/server/ui-v2/assets/{block-type-details-2rIqbqoZ.js.map → block-type-details-CYrdaLot.js.map} +1 -1
  36. prefect/server/ui-v2/assets/block-type-logo-CyAWq7mC.js +2 -0
  37. prefect/server/ui-v2/assets/block-type-logo-CyAWq7mC.js.map +1 -0
  38. prefect/server/ui-v2/assets/{block._id-OeCbdPeL.js → block._id-CBgHrpTP.js} +2 -2
  39. prefect/server/ui-v2/assets/{block._id-OeCbdPeL.js.map → block._id-CBgHrpTP.js.map} +1 -1
  40. prefect/server/ui-v2/assets/{block_._id.edit-CD22VllN.js → block_._id.edit-CW-kdi4O.js} +2 -2
  41. prefect/server/ui-v2/assets/{block_._id.edit-CD22VllN.js.map → block_._id.edit-CW-kdi4O.js.map} +1 -1
  42. prefect/server/ui-v2/assets/{catalog-Dj7lYV7b.js → catalog-Brh0kn1I.js} +2 -2
  43. prefect/server/ui-v2/assets/{catalog-Dj7lYV7b.js.map → catalog-Brh0kn1I.js.map} +1 -1
  44. prefect/server/ui-v2/assets/catalog_._slug-MCgzguIZ.js +2 -0
  45. prefect/server/ui-v2/assets/{catalog_._slug-NLgWS8vG.js.map → catalog_._slug-MCgzguIZ.js.map} +1 -1
  46. prefect/server/ui-v2/assets/{catalog_._slug_.create-D0vc1Piy.js → catalog_._slug_.create-DBaeHi9Q.js} +2 -2
  47. prefect/server/ui-v2/assets/{catalog_._slug_.create-D0vc1Piy.js.map → catalog_._slug_.create-DBaeHi9Q.js.map} +1 -1
  48. prefect/server/ui-v2/assets/{collapsible-Dgk2Qvjj.js → collapsible-B_NJS0uJ.js} +2 -2
  49. prefect/server/ui-v2/assets/{collapsible-Dgk2Qvjj.js.map → collapsible-B_NJS0uJ.js.map} +1 -1
  50. prefect/server/ui-v2/assets/{concurrency-limit._id-BZiyM0NT.js → concurrency-limit._id-qzNUQzQa.js} +2 -2
  51. prefect/server/ui-v2/assets/{concurrency-limit._id-BZiyM0NT.js.map → concurrency-limit._id-qzNUQzQa.js.map} +1 -1
  52. prefect/server/ui-v2/assets/create-BwXG6EIb.js +2 -0
  53. prefect/server/ui-v2/assets/{create-1j1-8yhV.js.map → create-BwXG6EIb.js.map} +1 -1
  54. prefect/server/ui-v2/assets/{create-H21iiYVl.js → create-MoiIE9Ms.js} +2 -2
  55. prefect/server/ui-v2/assets/{create-H21iiYVl.js.map → create-MoiIE9Ms.js.map} +1 -1
  56. prefect/server/ui-v2/assets/data-table-CPkppyg6.js +2 -0
  57. prefect/server/ui-v2/assets/data-table-CPkppyg6.js.map +1 -0
  58. prefect/server/ui-v2/assets/delete-confirmation-dialog-CwDK_2QS.js +2 -0
  59. prefect/server/ui-v2/assets/{delete-confirmation-dialog-B9-8JHV7.js.map → delete-confirmation-dialog-CwDK_2QS.js.map} +1 -1
  60. prefect/server/ui-v2/assets/{deployment-action-header-DlD2GSJB.js → deployment-action-header-Vp9YsCJO.js} +2 -2
  61. prefect/server/ui-v2/assets/{deployment-action-header-DlD2GSJB.js.map → deployment-action-header-Vp9YsCJO.js.map} +1 -1
  62. prefect/server/ui-v2/assets/{deployment-form-CFcOIeIi.js → deployment-form-CJcg_6DJ.js} +3 -3
  63. prefect/server/ui-v2/assets/{deployment-form-CFcOIeIi.js.map → deployment-form-CJcg_6DJ.js.map} +1 -1
  64. prefect/server/ui-v2/assets/{deployment-links-DN2Oa0r1.js → deployment-links-CIkJIuHh.js} +2 -2
  65. prefect/server/ui-v2/assets/{deployment-links-DN2Oa0r1.js.map → deployment-links-CIkJIuHh.js.map} +1 -1
  66. prefect/server/ui-v2/assets/deployment._id-C6XrGMp_.js +2 -0
  67. prefect/server/ui-v2/assets/{deployment._id-C8NPwIIQ.js.map → deployment._id-C6XrGMp_.js.map} +1 -1
  68. prefect/server/ui-v2/assets/{deployment._id-DsVQUPNp.js → deployment._id-CWgTYmTG.js} +2 -2
  69. prefect/server/ui-v2/assets/{deployment._id-DsVQUPNp.js.map → deployment._id-CWgTYmTG.js.map} +1 -1
  70. prefect/server/ui-v2/assets/deployment_._id.duplicate-Bg0s0ZJn.js +2 -0
  71. prefect/server/ui-v2/assets/{deployment_._id.duplicate-4uYFgdPg.js.map → deployment_._id.duplicate-Bg0s0ZJn.js.map} +1 -1
  72. prefect/server/ui-v2/assets/deployment_._id.edit-CnoB0UeG.js +2 -0
  73. prefect/server/ui-v2/assets/{deployment_._id.edit-Z859_W76.js.map → deployment_._id.edit-CnoB0UeG.js.map} +1 -1
  74. prefect/server/ui-v2/assets/{deployment_._id.run-MW5q2SRM.js → deployment_._id.run-BqPK6rTB.js} +2 -2
  75. prefect/server/ui-v2/assets/{deployment_._id.run-MW5q2SRM.js.map → deployment_._id.run-BqPK6rTB.js.map} +1 -1
  76. prefect/server/ui-v2/assets/{dropdown-menu-DF4QR3Cp.js → dropdown-menu-D7Gwbd15.js} +2 -2
  77. prefect/server/ui-v2/assets/{dropdown-menu-DF4QR3Cp.js.map → dropdown-menu-D7Gwbd15.js.map} +1 -1
  78. prefect/server/ui-v2/assets/{event-resource-display-DR3zL_k_.js → event-resource-display-CDRgVKd4.js} +2 -2
  79. prefect/server/ui-v2/assets/{event-resource-display-DR3zL_k_.js.map → event-resource-display-CDRgVKd4.js.map} +1 -1
  80. prefect/server/ui-v2/assets/event._eventDate._eventId-C73GMDkK.js +2 -0
  81. prefect/server/ui-v2/assets/{event._eventDate._eventId-DfU7SalU.js.map → event._eventDate._eventId-C73GMDkK.js.map} +1 -1
  82. prefect/server/ui-v2/assets/flow-run-graph-ckiE3mA9.js +2 -0
  83. prefect/server/ui-v2/assets/{flow-run-graph-Bf9t75GK.js.map → flow-run-graph-ckiE3mA9.js.map} +1 -1
  84. prefect/server/ui-v2/assets/{flow-run._id-RL0qeSLl.js → flow-run._id-BukrNCAq.js} +2 -2
  85. prefect/server/ui-v2/assets/{flow-run._id-RL0qeSLl.js.map → flow-run._id-BukrNCAq.js.map} +1 -1
  86. prefect/server/ui-v2/assets/{flow-run._id-DTsj_xO3.js → flow-run._id-CtI5VZ2M.js} +2 -2
  87. prefect/server/ui-v2/assets/{flow-run._id-DTsj_xO3.js.map → flow-run._id-CtI5VZ2M.js.map} +1 -1
  88. prefect/server/ui-v2/assets/flow-run._id-s1UJuakA.js +4 -0
  89. prefect/server/ui-v2/assets/flow-run._id-s1UJuakA.js.map +1 -0
  90. prefect/server/ui-v2/assets/{flow-runs-pagination-Bfelp8UO.js → flow-runs-pagination-SLbYtvaR.js} +2 -2
  91. prefect/server/ui-v2/assets/{flow-runs-pagination-Bfelp8UO.js.map → flow-runs-pagination-SLbYtvaR.js.map} +1 -1
  92. prefect/server/ui-v2/assets/flow._id-CZ5P0v4N.js +2 -0
  93. prefect/server/ui-v2/assets/{flow._id-DuQ5AUjj.js.map → flow._id-CZ5P0v4N.js.map} +1 -1
  94. prefect/server/ui-v2/assets/{form-DHWphysD.js → form-mws4law8.js} +2 -2
  95. prefect/server/ui-v2/assets/{form-DHWphysD.js.map → form-mws4law8.js.map} +1 -1
  96. prefect/server/ui-v2/assets/{header-BK_NuSng.js → header-Bes1LmY7.js} +2 -2
  97. prefect/server/ui-v2/assets/{header-BK_NuSng.js.map → header-Bes1LmY7.js.map} +1 -1
  98. prefect/server/ui-v2/assets/{header-nu-ZKuen.js → header-Bj_zBR-a.js} +2 -2
  99. prefect/server/ui-v2/assets/{header-nu-ZKuen.js.map → header-Bj_zBR-a.js.map} +1 -1
  100. prefect/server/ui-v2/assets/{header-B9SuuoZx.js → header-CPxTHSvz.js} +2 -2
  101. prefect/server/ui-v2/assets/{header-B9SuuoZx.js.map → header-CPxTHSvz.js.map} +1 -1
  102. prefect/server/ui-v2/assets/{index-_0OOjqn5.js → index-B8vo2Lrg.js} +5 -5
  103. prefect/server/ui-v2/assets/{index-_0OOjqn5.js.map → index-B8vo2Lrg.js.map} +1 -1
  104. prefect/server/ui-v2/assets/{index-DsK1RlS9.js → index-BBeh-3Nh.js} +2 -2
  105. prefect/server/ui-v2/assets/{index-DsK1RlS9.js.map → index-BBeh-3Nh.js.map} +1 -1
  106. prefect/server/ui-v2/assets/index-BLnEvHia.js +2 -0
  107. prefect/server/ui-v2/assets/{index-Dl_iSX0z.js.map → index-BLnEvHia.js.map} +1 -1
  108. prefect/server/ui-v2/assets/index-BpKoubXu.js +2 -0
  109. prefect/server/ui-v2/assets/index-BpKoubXu.js.map +1 -0
  110. prefect/server/ui-v2/assets/index-By6YGqR3.js +2 -0
  111. prefect/server/ui-v2/assets/index-By6YGqR3.js.map +1 -0
  112. prefect/server/ui-v2/assets/index-CEi3BlKI.js +2 -0
  113. prefect/server/ui-v2/assets/index-CEi3BlKI.js.map +1 -0
  114. prefect/server/ui-v2/assets/{index-BPXdHXTb.js → index-CS-zxv7Z.js} +2 -2
  115. prefect/server/ui-v2/assets/{index-BPXdHXTb.js.map → index-CS-zxv7Z.js.map} +1 -1
  116. prefect/server/ui-v2/assets/{index-CPFMHkRh.js → index-CToHKh4q.js} +2 -2
  117. prefect/server/ui-v2/assets/{index-CPFMHkRh.js.map → index-CToHKh4q.js.map} +1 -1
  118. prefect/server/ui-v2/assets/{index-DSBmxhwG.js → index-CUVvZndW.js} +2 -2
  119. prefect/server/ui-v2/assets/{index-DSBmxhwG.js.map → index-CUVvZndW.js.map} +1 -1
  120. prefect/server/ui-v2/assets/{index-mj9GNKt7.js → index-CYVn-I3i.js} +2 -2
  121. prefect/server/ui-v2/assets/{index-mj9GNKt7.js.map → index-CYVn-I3i.js.map} +1 -1
  122. prefect/server/ui-v2/assets/{index-DFS5GNpT.js → index-Cun0JN4t.js} +2 -2
  123. prefect/server/ui-v2/assets/{index-DFS5GNpT.js.map → index-Cun0JN4t.js.map} +1 -1
  124. prefect/server/ui-v2/assets/{index-DcMpyvW7.js → index-D6ynV6U7.js} +2 -2
  125. prefect/server/ui-v2/assets/{index-DcMpyvW7.js.map → index-D6ynV6U7.js.map} +1 -1
  126. prefect/server/ui-v2/assets/{index-DVsNA4UN.js → index-DdNUJLRW.js} +2 -2
  127. prefect/server/ui-v2/assets/{index-DVsNA4UN.js.map → index-DdNUJLRW.js.map} +1 -1
  128. prefect/server/ui-v2/assets/{index-vRbn9rG4.js → index-DlHOXQhu.js} +2 -2
  129. prefect/server/ui-v2/assets/{index-vRbn9rG4.js.map → index-DlHOXQhu.js.map} +1 -1
  130. prefect/server/ui-v2/assets/{index-Cj5ihRiw.js → index-DyVw8YE8.js} +2 -2
  131. prefect/server/ui-v2/assets/{index-Cj5ihRiw.js.map → index-DyVw8YE8.js.map} +1 -1
  132. prefect/server/ui-v2/assets/{index-DNuhJlQK.js → index-DzRz7D2P.js} +2 -2
  133. prefect/server/ui-v2/assets/{index-DNuhJlQK.js.map → index-DzRz7D2P.js.map} +1 -1
  134. prefect/server/ui-v2/assets/{index-DtrQRjt_.js → index-DzUcVNZg.js} +2 -2
  135. prefect/server/ui-v2/assets/{index-DtrQRjt_.js.map → index-DzUcVNZg.js.map} +1 -1
  136. prefect/server/ui-v2/assets/{index-BCR-yD58.js → index-IBvMMs6S.js} +2 -2
  137. prefect/server/ui-v2/assets/{index-BCR-yD58.js.map → index-IBvMMs6S.js.map} +1 -1
  138. prefect/server/ui-v2/assets/index-_kpA__te.js +2 -0
  139. prefect/server/ui-v2/assets/{index-DWGx9irM.js.map → index-_kpA__te.js.map} +1 -1
  140. prefect/server/ui-v2/assets/index-m9O-nIOl.css +1 -0
  141. prefect/server/ui-v2/assets/{index-C0MMjoUe.js → index-wOvyf10b.js} +2 -2
  142. prefect/server/ui-v2/assets/{index-C0MMjoUe.js.map → index-wOvyf10b.js.map} +1 -1
  143. prefect/server/ui-v2/assets/{json-input-CMZiW5M2.js → json-input-Ce-HlRqa.js} +2 -2
  144. prefect/server/ui-v2/assets/{json-input-CMZiW5M2.js.map → json-input-Ce-HlRqa.js.map} +1 -1
  145. prefect/server/ui-v2/assets/key-value-XHEZOtZX.js +2 -0
  146. prefect/server/ui-v2/assets/key-value-XHEZOtZX.js.map +1 -0
  147. prefect/server/ui-v2/assets/{key._key-CdonPtNh.js → key._key-LpsMf3zD.js} +2 -2
  148. prefect/server/ui-v2/assets/{key._key-CdonPtNh.js.map → key._key-LpsMf3zD.js.map} +1 -1
  149. prefect/server/ui-v2/assets/{lazy-markdown-CKcd9ksG.js → lazy-markdown-1Hz0xzca.js} +2 -2
  150. prefect/server/ui-v2/assets/{lazy-markdown-CKcd9ksG.js.map → lazy-markdown-1Hz0xzca.js.map} +1 -1
  151. prefect/server/ui-v2/assets/{login-Dnd-tV90.js → login-D5uepl9L.js} +2 -2
  152. prefect/server/ui-v2/assets/{login-Dnd-tV90.js.map → login-D5uepl9L.js.map} +1 -1
  153. prefect/server/ui-v2/assets/{markdown-input-D6rfyTa_.js → markdown-input-CG6M9zD0.js} +2 -2
  154. prefect/server/ui-v2/assets/{markdown-input-D6rfyTa_.js.map → markdown-input-CG6M9zD0.js.map} +1 -1
  155. prefect/server/ui-v2/assets/python-example-snippet-DRHcUlCX.js +3 -0
  156. prefect/server/ui-v2/assets/{python-example-snippet-eWuRXCxE.js.map → python-example-snippet-DRHcUlCX.js.map} +1 -1
  157. prefect/server/ui-v2/assets/{python-input-itfwkkBT.js → python-input-BsUS8fw1.js} +2 -2
  158. prefect/server/ui-v2/assets/{python-input-itfwkkBT.js.map → python-input-BsUS8fw1.js.map} +1 -1
  159. prefect/server/ui-v2/assets/{radio-group-DeN-_krn.js → radio-group-BUsmwdrt.js} +2 -2
  160. prefect/server/ui-v2/assets/{radio-group-DeN-_krn.js.map → radio-group-BUsmwdrt.js.map} +1 -1
  161. prefect/server/ui-v2/assets/{route-error-state-tYzhKCqH.js → route-error-state-BFBpiIhD.js} +2 -2
  162. prefect/server/ui-v2/assets/{route-error-state-tYzhKCqH.js.map → route-error-state-BFBpiIhD.js.map} +1 -1
  163. prefect/server/ui-v2/assets/{schema-form-DDUzvjpL.js → schema-form-BwTmkvJk.js} +2 -2
  164. prefect/server/ui-v2/assets/{schema-form-DDUzvjpL.js.map → schema-form-BwTmkvJk.js.map} +1 -1
  165. prefect/server/ui-v2/assets/{schema-form-input-string-format-datetime-DrpJmvST.js → schema-form-input-string-format-datetime-nrb3g-JJ.js} +4 -4
  166. prefect/server/ui-v2/assets/{schema-form-input-string-format-datetime-DrpJmvST.js.map → schema-form-input-string-format-datetime-nrb3g-JJ.js.map} +1 -1
  167. prefect/server/ui-v2/assets/{settings-OdrJDFrk.js → settings-CUBtK5aW.js} +2 -2
  168. prefect/server/ui-v2/assets/{settings-OdrJDFrk.js.map → settings-CUBtK5aW.js.map} +1 -1
  169. prefect/server/ui-v2/assets/{sort-filter-DaBGDmua.js → sort-filter-Cv8zAXMp.js} +2 -2
  170. prefect/server/ui-v2/assets/{sort-filter-DaBGDmua.js.map → sort-filter-Cv8zAXMp.js.map} +1 -1
  171. prefect/server/ui-v2/assets/{table-4GUC4YOD.js → table-BBNGfPra.js} +2 -2
  172. prefect/server/ui-v2/assets/{table-4GUC4YOD.js.map → table-BBNGfPra.js.map} +1 -1
  173. prefect/server/ui-v2/assets/{tags-input-BvH9UY8h.js → tags-input-DHrnkwjQ.js} +2 -2
  174. prefect/server/ui-v2/assets/{tags-input-BvH9UY8h.js.map → tags-input-DHrnkwjQ.js.map} +1 -1
  175. prefect/server/ui-v2/assets/task-run-concurrency-limits-reset-dialog-Z8-yFZ2_.js +2 -0
  176. prefect/server/ui-v2/assets/{task-run-concurrency-limits-reset-dialog-CLZz3kwW.js.map → task-run-concurrency-limits-reset-dialog-Z8-yFZ2_.js.map} +1 -1
  177. prefect/server/ui-v2/assets/{task-run._id-DgXFfCuq.js → task-run._id-BY58gqs2.js} +2 -2
  178. prefect/server/ui-v2/assets/{task-run._id-DgXFfCuq.js.map → task-run._id-BY58gqs2.js.map} +1 -1
  179. prefect/server/ui-v2/assets/{task-run._id-DHHzTQ9d.js → task-run._id-u73Jxfqw.js} +3 -3
  180. prefect/server/ui-v2/assets/{task-run._id-DHHzTQ9d.js.map → task-run._id-u73Jxfqw.js.map} +1 -1
  181. prefect/server/ui-v2/assets/task-runs-pagination-DUy3147A.js +2 -0
  182. prefect/server/ui-v2/assets/{task-runs-pagination-fR9zqj38.js.map → task-runs-pagination-DUy3147A.js.map} +1 -1
  183. prefect/server/ui-v2/assets/{textarea-DL9UCBaB.js → textarea-DUhh6-kq.js} +2 -2
  184. prefect/server/ui-v2/assets/{textarea-DL9UCBaB.js.map → textarea-DUhh6-kq.js.map} +1 -1
  185. prefect/server/ui-v2/assets/timezone-select-D4Q6VBtD.js +2 -0
  186. prefect/server/ui-v2/assets/{timezone-select-qBEoPcyO.js.map → timezone-select-D4Q6VBtD.js.map} +1 -1
  187. prefect/server/ui-v2/assets/{toggle-group-Cf-ZSSDP.js → toggle-group-7WUJn2Tx.js} +2 -2
  188. prefect/server/ui-v2/assets/{toggle-group-Cf-ZSSDP.js.map → toggle-group-7WUJn2Tx.js.map} +1 -1
  189. prefect/server/ui-v2/assets/use-delete-automation-confirmation-dialog-D4AD5Ndf.js +2 -0
  190. prefect/server/ui-v2/assets/{use-delete-automation-confirmation-dialog-DRX9Kvie.js.map → use-delete-automation-confirmation-dialog-D4AD5Ndf.js.map} +1 -1
  191. prefect/server/ui-v2/assets/{use-delete-block-document-confirmation-dialog-CogrfdiO.js → use-delete-block-document-confirmation-dialog-DnwWEGUY.js} +2 -2
  192. prefect/server/ui-v2/assets/{use-delete-block-document-confirmation-dialog-CogrfdiO.js.map → use-delete-block-document-confirmation-dialog-DnwWEGUY.js.map} +1 -1
  193. prefect/server/ui-v2/assets/{use-flow-runs-selected-rows-CdMKKvm5.js → use-flow-runs-selected-rows-C-tehPRB.js} +2 -2
  194. prefect/server/ui-v2/assets/{use-flow-runs-selected-rows-CdMKKvm5.js.map → use-flow-runs-selected-rows-C-tehPRB.js.map} +1 -1
  195. prefect/server/ui-v2/assets/{use-get-artifacts-flow-task-runs-Be1qg-IF.js → use-get-artifacts-flow-task-runs-DRWRrmrb.js} +2 -2
  196. prefect/server/ui-v2/assets/{use-get-artifacts-flow-task-runs-Be1qg-IF.js.map → use-get-artifacts-flow-task-runs-DRWRrmrb.js.map} +1 -1
  197. prefect/server/ui-v2/assets/{use-quick-run-DXDfXpvs.js → use-quick-run-B4Xj-YQQ.js} +2 -2
  198. prefect/server/ui-v2/assets/{use-quick-run-DXDfXpvs.js.map → use-quick-run-B4Xj-YQQ.js.map} +1 -1
  199. prefect/server/ui-v2/assets/use-state-favicon-au2TZdMV.js +2 -0
  200. prefect/server/ui-v2/assets/{use-state-favicon-Dhkg1tqx.js.map → use-state-favicon-au2TZdMV.js.map} +1 -1
  201. prefect/server/ui-v2/assets/{use-stepper-jTTsXpho.js → use-stepper-DyIb3vlq.js} +2 -2
  202. prefect/server/ui-v2/assets/{use-stepper-jTTsXpho.js.map → use-stepper-DyIb3vlq.js.map} +1 -1
  203. prefect/server/ui-v2/assets/{utilities-CgJi7g2F.js → utilities-D9Y2wo66.js} +2 -2
  204. prefect/server/ui-v2/assets/{utilities-CgJi7g2F.js.map → utilities-D9Y2wo66.js.map} +1 -1
  205. prefect/server/ui-v2/assets/vendor-recharts-BvvJP9Po.js +34 -0
  206. prefect/server/ui-v2/assets/vendor-recharts-BvvJP9Po.js.map +1 -0
  207. prefect/server/ui-v2/assets/{work-pool-filter-DLkRAAHz.js → work-pool-filter-CSOATj2D.js} +2 -2
  208. prefect/server/ui-v2/assets/{work-pool-filter-DLkRAAHz.js.map → work-pool-filter-CSOATj2D.js.map} +1 -1
  209. prefect/server/ui-v2/assets/work-pool-queue-toggle-Dh7B1zMo.js +2 -0
  210. prefect/server/ui-v2/assets/{work-pool-queue-toggle-BFodtXQe.js.map → work-pool-queue-toggle-Dh7B1zMo.js.map} +1 -1
  211. prefect/server/ui-v2/assets/work-pool._workPoolName-B_NFWXKS.js +2 -0
  212. prefect/server/ui-v2/assets/{work-pool._workPoolName-Bjh_bO5G.js.map → work-pool._workPoolName-B_NFWXKS.js.map} +1 -1
  213. prefect/server/ui-v2/assets/{work-pool_._workPoolName.edit-B-gnp5dc.js → work-pool_._workPoolName.edit-Cyzn8g-S.js} +2 -2
  214. prefect/server/ui-v2/assets/{work-pool_._workPoolName.edit-B-gnp5dc.js.map → work-pool_._workPoolName.edit-Cyzn8g-S.js.map} +1 -1
  215. prefect/server/ui-v2/assets/{work-pool_._workPoolName.queue._workQueueName-C7aVwLhH.js → work-pool_._workPoolName.queue._workQueueName-DQzqQWPT.js} +2 -2
  216. prefect/server/ui-v2/assets/{work-pool_._workPoolName.queue._workQueueName-C7aVwLhH.js.map → work-pool_._workPoolName.queue._workQueueName-DQzqQWPT.js.map} +1 -1
  217. prefect/server/ui-v2/assets/{work-queue-icon-text-BK_qfkJJ.js → work-queue-icon-text-BOpcJ8YU.js} +2 -2
  218. prefect/server/ui-v2/assets/{work-queue-icon-text-BK_qfkJJ.js.map → work-queue-icon-text-BOpcJ8YU.js.map} +1 -1
  219. prefect/server/ui-v2/index.html +3 -3
  220. prefect/testing/fixtures.py +14 -13
  221. {prefect-3.6.14.dev7.dist-info → prefect-3.6.16.dev2.dist-info}/METADATA +3 -2
  222. {prefect-3.6.14.dev7.dist-info → prefect-3.6.16.dev2.dist-info}/RECORD +225 -211
  223. prefect/server/ui-v2/assets/artifact._id-zuZ8P2RD.js +0 -2
  224. prefect/server/ui-v2/assets/artifact._id-zuZ8P2RD.js.map +0 -1
  225. prefect/server/ui-v2/assets/automation._id-BhEFaDc6.js +0 -2
  226. prefect/server/ui-v2/assets/block-type-logo-DV1pSkV0.js +0 -2
  227. prefect/server/ui-v2/assets/block-type-logo-DV1pSkV0.js.map +0 -1
  228. prefect/server/ui-v2/assets/catalog_._slug-NLgWS8vG.js +0 -2
  229. prefect/server/ui-v2/assets/create-1j1-8yhV.js +0 -2
  230. prefect/server/ui-v2/assets/data-table-DHlbTUL7.js +0 -2
  231. prefect/server/ui-v2/assets/data-table-DHlbTUL7.js.map +0 -1
  232. prefect/server/ui-v2/assets/delete-confirmation-dialog-B9-8JHV7.js +0 -2
  233. prefect/server/ui-v2/assets/deployment._id-C8NPwIIQ.js +0 -2
  234. prefect/server/ui-v2/assets/deployment_._id.duplicate-4uYFgdPg.js +0 -2
  235. prefect/server/ui-v2/assets/deployment_._id.edit-Z859_W76.js +0 -2
  236. prefect/server/ui-v2/assets/event._eventDate._eventId-DfU7SalU.js +0 -2
  237. prefect/server/ui-v2/assets/flow-run-graph-Bf9t75GK.js +0 -2
  238. prefect/server/ui-v2/assets/flow-run._id-33WKPXsZ.js +0 -4
  239. prefect/server/ui-v2/assets/flow-run._id-33WKPXsZ.js.map +0 -1
  240. prefect/server/ui-v2/assets/flow._id-DuQ5AUjj.js +0 -2
  241. prefect/server/ui-v2/assets/index-BqwU5GSv.js +0 -2
  242. prefect/server/ui-v2/assets/index-BqwU5GSv.js.map +0 -1
  243. prefect/server/ui-v2/assets/index-Br7MUvka.css +0 -1
  244. prefect/server/ui-v2/assets/index-CYjH7t93.js +0 -2
  245. prefect/server/ui-v2/assets/index-CYjH7t93.js.map +0 -1
  246. prefect/server/ui-v2/assets/index-CqUa3fbN.js +0 -2
  247. prefect/server/ui-v2/assets/index-CqUa3fbN.js.map +0 -1
  248. prefect/server/ui-v2/assets/index-DWGx9irM.js +0 -2
  249. prefect/server/ui-v2/assets/index-Dl_iSX0z.js +0 -2
  250. prefect/server/ui-v2/assets/python-example-snippet-eWuRXCxE.js +0 -3
  251. prefect/server/ui-v2/assets/task-run-concurrency-limits-reset-dialog-CLZz3kwW.js +0 -2
  252. prefect/server/ui-v2/assets/task-runs-pagination-fR9zqj38.js +0 -2
  253. prefect/server/ui-v2/assets/timezone-select-qBEoPcyO.js +0 -2
  254. prefect/server/ui-v2/assets/use-delete-automation-confirmation-dialog-DRX9Kvie.js +0 -2
  255. prefect/server/ui-v2/assets/use-state-favicon-Dhkg1tqx.js +0 -2
  256. prefect/server/ui-v2/assets/vendor-recharts-BAN776s_.js +0 -34
  257. prefect/server/ui-v2/assets/vendor-recharts-BAN776s_.js.map +0 -1
  258. prefect/server/ui-v2/assets/work-pool-queue-toggle-BFodtXQe.js +0 -2
  259. prefect/server/ui-v2/assets/work-pool._workPoolName-Bjh_bO5G.js +0 -2
  260. {prefect-3.6.14.dev7.dist-info → prefect-3.6.16.dev2.dist-info}/WHEEL +0 -0
  261. {prefect-3.6.14.dev7.dist-info → prefect-3.6.16.dev2.dist-info}/entry_points.txt +0 -0
  262. {prefect-3.6.14.dev7.dist-info → prefect-3.6.16.dev2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,60 @@
1
+ """
2
+ First-run telemetry notice for SDK telemetry.
3
+
4
+ Displays a notice to users the first time telemetry is enabled,
5
+ but only in interactive terminal sessions.
6
+ """
7
+
8
+ import sys
9
+ from pathlib import Path
10
+
11
+ from prefect._internal.analytics.emit import _is_interactive_terminal
12
+ from prefect.settings import get_current_settings
13
+
14
+ NOTICE_TEXT = """
15
+ Prefect collects anonymous usage data to improve the product.
16
+ To opt out: set PREFECT_SERVER_ANALYTICS_ENABLED=false on the server, or DO_NOT_TRACK=1 in the client.
17
+ Learn more: https://docs.prefect.io/concepts/telemetry
18
+ """
19
+
20
+
21
+ def _get_notice_marker_path() -> Path:
22
+ """Get the path to the notice marker file."""
23
+ settings = get_current_settings()
24
+ return settings.home / ".sdk_telemetry" / "notice_shown"
25
+
26
+
27
+ def _has_shown_notice() -> bool:
28
+ """Check if the notice has been shown before."""
29
+ return _get_notice_marker_path().exists()
30
+
31
+
32
+ def _mark_notice_shown() -> None:
33
+ """Mark that the notice has been shown."""
34
+ marker_path = _get_notice_marker_path()
35
+ try:
36
+ marker_path.parent.mkdir(parents=True, exist_ok=True)
37
+ marker_path.touch()
38
+ except Exception:
39
+ pass
40
+
41
+
42
+ def maybe_show_telemetry_notice() -> None:
43
+ """
44
+ Show the telemetry notice if appropriate.
45
+
46
+ The notice is shown only:
47
+ - The first time telemetry is enabled
48
+ - In an interactive terminal (TTY)
49
+ """
50
+ # Only show in interactive terminals
51
+ if not _is_interactive_terminal():
52
+ return
53
+
54
+ # Only show once
55
+ if _has_shown_notice():
56
+ return
57
+
58
+ # Show notice and mark as shown
59
+ print(NOTICE_TEXT, file=sys.stderr)
60
+ _mark_notice_shown()
@@ -0,0 +1,238 @@
1
+ """
2
+ Background analytics service for non-blocking event processing.
3
+
4
+ This module provides a singleton service that receives analytics events via a queue
5
+ and processes them in a background thread. The server analytics check is performed
6
+ once per process, off the main thread.
7
+ """
8
+
9
+ import atexit
10
+ import os
11
+ import queue
12
+ import threading
13
+ from dataclasses import dataclass
14
+ from typing import Any, ClassVar
15
+
16
+ from prefect._internal.analytics.ci_detection import is_ci_environment
17
+ from prefect._internal.analytics.client import track_event
18
+
19
+
20
+ @dataclass
21
+ class AnalyticsEvent:
22
+ """An analytics event to be processed by the background service."""
23
+
24
+ event_name: str
25
+ device_id: str
26
+ extra_properties: dict[str, Any] | None = None
27
+
28
+
29
+ class AnalyticsService:
30
+ """
31
+ Background service for processing analytics events.
32
+
33
+ This service:
34
+ - Receives events via enqueue() which returns immediately (non-blocking)
35
+ - Processes events in a background daemon thread
36
+ - Performs the server analytics check once per process (with 5s timeout)
37
+ - Caches the server check result in memory
38
+
39
+ The service is lazily started when the first event is queued.
40
+ """
41
+
42
+ _instance: ClassVar["AnalyticsService | None"] = None
43
+ _lock: ClassVar[threading.Lock] = threading.Lock()
44
+
45
+ def __init__(self) -> None:
46
+ self._queue: queue.Queue[AnalyticsEvent | None] = queue.Queue()
47
+ self._thread: threading.Thread | None = None
48
+ self._started = False
49
+ self._analytics_enabled: bool | None = None
50
+ self._analytics_checked = threading.Event()
51
+ self._shutdown_requested = False
52
+ self._instance_lock = threading.Lock()
53
+
54
+ @classmethod
55
+ def instance(cls) -> "AnalyticsService":
56
+ """Get or create the singleton instance."""
57
+ if cls._instance is None:
58
+ with cls._lock:
59
+ if cls._instance is None:
60
+ cls._instance = cls()
61
+ atexit.register(cls._instance.shutdown)
62
+ return cls._instance
63
+
64
+ @classmethod
65
+ def reset(cls) -> None:
66
+ """Reset the singleton instance. Used for testing and fork safety."""
67
+ with cls._lock:
68
+ if cls._instance is not None:
69
+ cls._instance._shutdown_requested = True
70
+ # Put None to wake up the thread if it's waiting
71
+ try:
72
+ cls._instance._queue.put_nowait(None)
73
+ except queue.Full:
74
+ pass
75
+ cls._instance = None
76
+
77
+ def enqueue(self, event: AnalyticsEvent) -> None:
78
+ """
79
+ Queue an event for processing. Returns immediately (non-blocking).
80
+
81
+ Quick local checks (DO_NOT_TRACK, CI) are performed here to avoid
82
+ queuing events that will never be sent.
83
+ """
84
+ # Quick local checks - these don't require network calls
85
+ if not self._quick_enabled_check():
86
+ return
87
+
88
+ # Start the background thread on first event
89
+ self._ensure_started()
90
+
91
+ # Queue the event (non-blocking)
92
+ try:
93
+ self._queue.put_nowait(event)
94
+ except queue.Full:
95
+ pass # Drop event silently if queue is full
96
+
97
+ def _quick_enabled_check(self) -> bool:
98
+ """
99
+ Quick non-blocking check of local telemetry settings.
100
+
101
+ Returns False if DO_NOT_TRACK is set or we're in a CI environment.
102
+ """
103
+ do_not_track = os.environ.get("DO_NOT_TRACK", "").lower()
104
+ if do_not_track in ("1", "true", "yes"):
105
+ return False
106
+
107
+ if is_ci_environment():
108
+ return False
109
+
110
+ return True
111
+
112
+ def _ensure_started(self) -> None:
113
+ """Start the background thread if not already running."""
114
+ with self._instance_lock:
115
+ if not self._started:
116
+ self._started = True
117
+ self._thread = threading.Thread(
118
+ target=self._run,
119
+ name="prefect-analytics",
120
+ daemon=True,
121
+ )
122
+ self._thread.start()
123
+
124
+ def _run(self) -> None:
125
+ """Background thread main loop."""
126
+ try:
127
+ # Check server analytics setting (5s timeout, off main thread)
128
+ self._analytics_enabled = self._check_server_analytics()
129
+ self._analytics_checked.set()
130
+
131
+ if not self._analytics_enabled:
132
+ # Drain the queue and exit - analytics are disabled
133
+ self._drain_queue()
134
+ return
135
+
136
+ # Process events in a loop
137
+ while not self._shutdown_requested:
138
+ try:
139
+ event = self._queue.get(timeout=1.0)
140
+ if event is None:
141
+ # Shutdown signal or spurious wakeup
142
+ if self._shutdown_requested:
143
+ break
144
+ continue
145
+
146
+ self._process_event(event)
147
+ self._queue.task_done()
148
+ except queue.Empty:
149
+ continue
150
+ except Exception:
151
+ pass # Silently ignore processing errors
152
+
153
+ except Exception:
154
+ self._analytics_checked.set()
155
+
156
+ def _check_server_analytics(self) -> bool:
157
+ """
158
+ Check if the server has analytics enabled.
159
+
160
+ When no API URL is configured, reads the local setting directly.
161
+ When an API URL is set, queries the remote server using the Prefect client.
162
+ """
163
+ from prefect.settings.context import get_current_settings
164
+
165
+ settings = get_current_settings()
166
+ api_url = settings.api.url
167
+ if not api_url:
168
+ return settings.server.analytics_enabled
169
+
170
+ try:
171
+ from prefect.client.orchestration import get_client
172
+
173
+ with get_client(sync_client=True) as client:
174
+ response = client.request("GET", "/admin/settings")
175
+ response.raise_for_status()
176
+ server_settings = response.json()
177
+ return server_settings.get("server", {}).get("analytics_enabled", False)
178
+ except Exception:
179
+ return False
180
+
181
+ def _drain_queue(self) -> None:
182
+ """Drain all events from the queue without processing them."""
183
+ while True:
184
+ try:
185
+ self._queue.get_nowait()
186
+ self._queue.task_done()
187
+ except queue.Empty:
188
+ break
189
+
190
+ def _process_event(self, event: AnalyticsEvent) -> None:
191
+ """Process a single analytics event."""
192
+ try:
193
+ track_event(
194
+ event_name=event.event_name,
195
+ device_id=event.device_id,
196
+ extra_properties=event.extra_properties,
197
+ )
198
+ except Exception:
199
+ pass # Silently ignore tracking errors
200
+
201
+ def shutdown(self, timeout: float = 2.0) -> None:
202
+ """
203
+ Shutdown the service, flushing pending events.
204
+
205
+ Args:
206
+ timeout: Maximum time to wait for pending events to be processed.
207
+ """
208
+ self._shutdown_requested = True
209
+
210
+ # Put None to wake up the thread if it's waiting
211
+ try:
212
+ self._queue.put_nowait(None)
213
+ except queue.Full:
214
+ pass
215
+
216
+ if self._thread is not None and self._thread.is_alive():
217
+ self._thread.join(timeout=timeout)
218
+
219
+ def wait_for_analytics_check(self, timeout: float | None = None) -> bool | None:
220
+ """
221
+ Wait for the server analytics check to complete.
222
+
223
+ Used primarily for testing. Returns the analytics enabled state,
224
+ or None if the check hasn't completed within the timeout.
225
+ """
226
+ if self._analytics_checked.wait(timeout=timeout):
227
+ return self._analytics_enabled
228
+ return None
229
+
230
+
231
+ def _reset_after_fork() -> None:
232
+ """Reset the service after a fork to avoid sharing state with parent."""
233
+ AnalyticsService.reset()
234
+
235
+
236
+ # Register fork handler if available (Unix systems)
237
+ if hasattr(os, "register_at_fork"):
238
+ os.register_at_fork(after_in_child=_reset_after_fork)
@@ -0,0 +1,67 @@
1
+ """
2
+ Public analytics API for Prefect integration libraries.
3
+
4
+ To opt out of telemetry:
5
+ # On the server:
6
+ export PREFECT_SERVER_ANALYTICS_ENABLED=false
7
+ # Or on the client:
8
+ export DO_NOT_TRACK=1
9
+ """
10
+
11
+ from typing import Any
12
+
13
+ from prefect._internal.analytics import (
14
+ emit_integration_event as _emit_integration_event,
15
+ )
16
+ from prefect._internal.analytics import is_telemetry_enabled as _is_telemetry_enabled
17
+
18
+
19
+ def emit_integration_event(
20
+ integration: str,
21
+ event_name: str,
22
+ extra_properties: dict[str, Any] | None = None,
23
+ ) -> bool:
24
+ """
25
+ Emit a telemetry event from an integration library.
26
+
27
+ This is the public API for integration libraries (e.g., prefect-aws,
28
+ prefect-gcp) to emit telemetry events. Events are automatically
29
+ namespaced with the integration name.
30
+
31
+ Args:
32
+ integration: The integration name (e.g., "prefect-aws", "prefect-gcp")
33
+ event_name: The event name (e.g., "s3_block_created")
34
+ extra_properties: Additional event properties
35
+
36
+ Returns:
37
+ True if the event was tracked, False otherwise
38
+
39
+ Example:
40
+ >>> from prefect.analytics import emit_integration_event
41
+ >>> emit_integration_event(
42
+ ... integration="prefect-aws",
43
+ ... event_name="s3_block_created",
44
+ ... extra_properties={"bucket_region": "us-east-1"}
45
+ ... )
46
+ """
47
+ return _emit_integration_event(integration, event_name, extra_properties)
48
+
49
+
50
+ def is_telemetry_enabled() -> bool:
51
+ """
52
+ Check if telemetry is enabled based on local settings.
53
+
54
+ This performs a quick, non-blocking check of local telemetry settings.
55
+ Server-side analytics settings are checked asynchronously in the background.
56
+
57
+ Telemetry is disabled if:
58
+ - DO_NOT_TRACK environment variable is set (client-side)
59
+ - Running in a CI environment
60
+
61
+ Returns:
62
+ True if local telemetry checks pass, False otherwise
63
+ """
64
+ return _is_telemetry_enabled()
65
+
66
+
67
+ __all__ = ["emit_integration_event", "is_telemetry_enabled"]
@@ -441,6 +441,16 @@ class RunnerDeployment(BaseModel):
441
441
  if self._sla or self._sla == []:
442
442
  await self._create_slas(deployment_id, client)
443
443
 
444
+ # Track deployment milestones for analytics
445
+ try:
446
+ from prefect._internal.analytics import try_mark_milestone
447
+
448
+ try_mark_milestone("first_deployment_created")
449
+ if self.schedules:
450
+ try_mark_milestone("first_schedule_created")
451
+ except Exception:
452
+ pass
453
+
444
454
  return deployment_id
445
455
 
446
456
  def _create_sync(
@@ -528,6 +538,16 @@ class RunnerDeployment(BaseModel):
528
538
  if self._sla or self._sla == []:
529
539
  self._create_slas_sync(deployment_id, client)
530
540
 
541
+ # Track deployment milestones for analytics
542
+ try:
543
+ from prefect._internal.analytics import try_mark_milestone
544
+
545
+ try_mark_milestone("first_deployment_created")
546
+ if self.schedules:
547
+ try_mark_milestone("first_schedule_created")
548
+ except Exception:
549
+ pass
550
+
531
551
  return deployment_id
532
552
 
533
553
  async def _update(
prefect/events/clients.py CHANGED
@@ -355,6 +355,38 @@ class PrefectEventsClient(EventsClient):
355
355
  exc_info=PREFECT_DEBUG_MODE.value(),
356
356
  )
357
357
 
358
+ async def _auth_handshake(self) -> None:
359
+ """Perform the auth handshake over the websocket connection.
360
+
361
+ This is used when connecting with the "prefect" subprotocol to
362
+ self-hosted servers. Subclasses that authenticate differently
363
+ (e.g. via HTTP headers for Prefect Cloud) can override this
364
+ to be a no-op.
365
+ """
366
+ assert self._websocket
367
+
368
+ logger.debug("Authenticating...")
369
+ await self._websocket.send(
370
+ orjson.dumps({"type": "auth", "token": self._auth_token}).decode()
371
+ )
372
+
373
+ try:
374
+ message: Dict[str, Any] = orjson.loads(await self._websocket.recv())
375
+ logger.debug("Auth result: %s", message)
376
+ assert message["type"] == "auth_success", message.get("reason", "")
377
+ except AssertionError as e:
378
+ raise Exception(
379
+ "Unable to authenticate to the event stream. Please ensure the "
380
+ "provided auth_token you are using is valid for this environment. "
381
+ f"Reason: {e.args[0]}"
382
+ )
383
+ except ConnectionClosedError as e:
384
+ reason = getattr(e.rcvd, "reason", None)
385
+ msg = "Unable to authenticate to the event stream. Please ensure the "
386
+ msg += "provided auth_token you are using is valid for this environment. "
387
+ msg += f"Reason: {reason}" if reason else ""
388
+ raise Exception(msg) from e
389
+
358
390
  async def _reconnect(self) -> None:
359
391
  logger.debug("Reconnecting websocket connection.")
360
392
 
@@ -382,27 +414,7 @@ class PrefectEventsClient(EventsClient):
382
414
  )
383
415
  raise
384
416
 
385
- logger.debug("Authenticating...")
386
- await self._websocket.send(
387
- orjson.dumps({"type": "auth", "token": self._auth_token}).decode()
388
- )
389
-
390
- try:
391
- message: Dict[str, Any] = orjson.loads(await self._websocket.recv())
392
- logger.debug("Auth result: %s", message)
393
- assert message["type"] == "auth_success", message.get("reason", "")
394
- except AssertionError as e:
395
- raise Exception(
396
- "Unable to authenticate to the event stream. Please ensure the "
397
- "provided auth_token you are using is valid for this environment. "
398
- f"Reason: {e.args[0]}"
399
- )
400
- except ConnectionClosedError as e:
401
- reason = getattr(e.rcvd, "reason", None)
402
- msg = "Unable to authenticate to the event stream. Please ensure the "
403
- msg += "provided auth_token you are using is valid for this environment. "
404
- msg += f"Reason: {reason}" if reason else ""
405
- raise Exception(msg) from e
417
+ await self._auth_handshake()
406
418
 
407
419
  events_to_resend = self._unconfirmed_events
408
420
  logger.debug("Resending %s unconfirmed events.", len(events_to_resend))
@@ -548,11 +560,18 @@ class PrefectCloudEventsClient(PrefectEventsClient):
548
560
  reconnection_attempts=reconnection_attempts,
549
561
  checkpoint_every=checkpoint_every,
550
562
  )
563
+ # Cloud authenticates via the Authorization header at the HTTP level,
564
+ # not via the "prefect" subprotocol auth handshake used by self-hosted servers.
551
565
  self._connect = websocket_connect(
552
566
  self._events_socket_url,
553
567
  additional_headers={"Authorization": f"bearer {api_key}"},
554
568
  )
555
569
 
570
+ async def _auth_handshake(self) -> None:
571
+ # Cloud does not use the "prefect" subprotocol auth handshake;
572
+ # authentication is handled by the Authorization HTTP header.
573
+ pass
574
+
556
575
 
557
576
  SEEN_EVENTS_SIZE = 500_000
558
577
  SEEN_EVENTS_TTL = 120
prefect/flow_engine.py CHANGED
@@ -565,6 +565,14 @@ class FlowRunEngine(BaseFlowRunEngine[P, R]):
565
565
  link_state_to_flow_run_result(terminal_state, resolved_result)
566
566
  self._telemetry.end_span_on_success()
567
567
 
568
+ # Track first flow run milestone for analytics
569
+ try:
570
+ from prefect._internal.analytics import try_mark_milestone
571
+
572
+ try_mark_milestone("first_flow_run")
573
+ except Exception:
574
+ pass
575
+
568
576
  return result
569
577
 
570
578
  def handle_exception(
@@ -1150,6 +1158,14 @@ class AsyncFlowRunEngine(BaseFlowRunEngine[P, R]):
1150
1158
 
1151
1159
  self._telemetry.end_span_on_success()
1152
1160
 
1161
+ # Track first flow run milestone for analytics
1162
+ try:
1163
+ from prefect._internal.analytics import try_mark_milestone
1164
+
1165
+ try_mark_milestone("first_flow_run")
1166
+ except Exception:
1167
+ pass
1168
+
1153
1169
  return result
1154
1170
 
1155
1171
  async def handle_exception(
prefect/flows.py CHANGED
@@ -402,6 +402,14 @@ class Flow(Generic[P, R]):
402
402
 
403
403
  self._entrypoint = f"{module}:{getattr(fn, '__qualname__', fn.__name__)}"
404
404
 
405
+ # Track first flow defined milestone for analytics
406
+ try:
407
+ from prefect._internal.analytics import try_mark_milestone
408
+
409
+ try_mark_milestone("first_flow_defined")
410
+ except Exception:
411
+ pass
412
+
405
413
  @property
406
414
  def ismethod(self) -> bool:
407
415
  return hasattr(self.fn, "__prefect_self__")
@@ -262,12 +262,14 @@ async def _generate_concurrency_locked_response(
262
262
  else settings.server.concurrency.maximum_concurrency_slot_wait_seconds
263
263
  )
264
264
  wait_time_per_slot = min(blocking_limit.avg_slot_occupancy_seconds, max_wait)
265
+ # Cap the total wait time at max_wait to prevent excessive retry delays
266
+ # when denied_slots accumulates from burst traffic
267
+ average_interval = min(wait_time_per_slot * blocking_slots, max_wait)
265
268
  else:
266
269
  wait_time_per_slot = 1.0 / blocking_limit.slot_decay_per_second
270
+ average_interval = wait_time_per_slot * blocking_slots
267
271
 
268
- retry_after = clamped_poisson_interval(
269
- average_interval=wait_time_per_slot * blocking_slots
270
- )
272
+ retry_after = clamped_poisson_interval(average_interval=average_interval)
271
273
 
272
274
  return HTTPException(
273
275
  status_code=status.HTTP_423_LOCKED,
@@ -1,2 +1,2 @@
1
- import{r as o,j as e,L as t}from"./vendor-tanstack-BcZfOOfy.js";import{L as n}from"./lazy-markdown-CKcd9ksG.js";import{aM as i,C as m,m as x,al as r,o as c,aW as d}from"./index-_0OOjqn5.js";const f=({artifact:s,compact:a=!1})=>{const l=o.useMemo(()=>i(new Date(s.created??""),"dateTime"),[s.created]);return e.jsx(t,{to:"/artifacts/key/$key",params:{key:s.key??""},children:e.jsxs(m,{className:"hover:shadow-lg hover:border-blue-700",children:[e.jsx(x,{children:e.jsx(r,{variant:"bodySmall",className:"font-bold text-muted-foreground",children:s.type?.toUpperCase()})}),e.jsxs(c,{children:[e.jsxs("div",{className:d("flex",a?"flex-row justify-between":"flex-col"),children:[e.jsx(r,{variant:a?"h4":"h3",className:"font-bold",children:s.key}),e.jsxs("div",{className:d("flex mt-2",a?"flex-col-reverse items-end":"justify-between"),children:[e.jsx(r,{variant:a?"bodySmall":"xsmall",className:"",fontFamily:"mono",children:l}),e.jsx(r,{variant:"bodySmall",className:"text-muted-foreground",children:"Created"})]})]}),e.jsx("hr",{className:"my-2"}),s.description?e.jsx("div",{className:"text-muted-foreground overflow-hidden truncate",children:e.jsx(n,{children:s.description??""})}):e.jsx(r,{variant:"bodySmall",className:"text-muted-foreground italic",children:"No description"})]})]})})};export{f as A};
2
- //# sourceMappingURL=artifact-card-9Cw_dMVb.js.map
1
+ import{r as o,j as e,L as t}from"./vendor-tanstack-BcZfOOfy.js";import{L as n}from"./lazy-markdown-1Hz0xzca.js";import{aQ as i,C as m,m as x,ap as r,o as c,a_ as d}from"./index-B8vo2Lrg.js";const f=({artifact:s,compact:a=!1})=>{const l=o.useMemo(()=>i(new Date(s.created??""),"dateTime"),[s.created]);return e.jsx(t,{to:"/artifacts/key/$key",params:{key:s.key??""},children:e.jsxs(m,{className:"hover:shadow-lg hover:border-blue-700",children:[e.jsx(x,{children:e.jsx(r,{variant:"bodySmall",className:"font-bold text-muted-foreground",children:s.type?.toUpperCase()})}),e.jsxs(c,{children:[e.jsxs("div",{className:d("flex",a?"flex-row justify-between":"flex-col"),children:[e.jsx(r,{variant:a?"h4":"h3",className:"font-bold",children:s.key}),e.jsxs("div",{className:d("flex mt-2",a?"flex-col-reverse items-end":"justify-between"),children:[e.jsx(r,{variant:a?"bodySmall":"xsmall",className:"",fontFamily:"mono",children:l}),e.jsx(r,{variant:"bodySmall",className:"text-muted-foreground",children:"Created"})]})]}),e.jsx("hr",{className:"my-2"}),s.description?e.jsx("div",{className:"text-muted-foreground overflow-hidden truncate",children:e.jsx(n,{children:s.description??""})}):e.jsx(r,{variant:"bodySmall",className:"text-muted-foreground italic",children:"No description"})]})]})})};export{f as A};
2
+ //# sourceMappingURL=artifact-card-BclosG8t.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"artifact-card-9Cw_dMVb.js","sources":["../../src/components/artifacts/artifact-card.tsx"],"sourcesContent":["import { Link } from \"@tanstack/react-router\";\nimport { useMemo } from \"react\";\nimport type { Artifact } from \"@/api/artifacts\";\nimport { LazyMarkdown } from \"@/components/ui/lazy-markdown\";\nimport { cn } from \"@/utils\";\nimport { formatDate } from \"@/utils/date\";\nimport { Card, CardContent, CardHeader } from \"../ui/card\";\nimport { Typography } from \"../ui/typography\";\n\nexport type ArtifactsCardProps = {\n\tartifact: Artifact;\n\tcompact?: boolean;\n};\n\nexport const ArtifactCard = ({\n\tartifact,\n\tcompact = false,\n}: ArtifactsCardProps) => {\n\tconst createdAtDate = useMemo(() => {\n\t\treturn formatDate(new Date(artifact.created ?? \"\"), \"dateTime\");\n\t}, [artifact.created]);\n\treturn (\n\t\t<Link to=\"/artifacts/key/$key\" params={{ key: artifact.key ?? \"\" }}>\n\t\t\t<Card className=\"hover:shadow-lg hover:border-blue-700\">\n\t\t\t\t<CardHeader>\n\t\t\t\t\t<Typography\n\t\t\t\t\t\tvariant=\"bodySmall\"\n\t\t\t\t\t\tclassName=\"font-bold text-muted-foreground\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{artifact.type?.toUpperCase()}\n\t\t\t\t\t</Typography>\n\t\t\t\t</CardHeader>\n\t\t\t\t<CardContent>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\"flex\",\n\t\t\t\t\t\t\tcompact ? \"flex-row justify-between\" : \"flex-col\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Typography variant={compact ? \"h4\" : \"h3\"} className=\"font-bold\">\n\t\t\t\t\t\t\t{artifact.key}\n\t\t\t\t\t\t</Typography>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"flex mt-2\",\n\t\t\t\t\t\t\t\tcompact ? \"flex-col-reverse items-end\" : \"justify-between\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Typography\n\t\t\t\t\t\t\t\tvariant={compact ? \"bodySmall\" : \"xsmall\"}\n\t\t\t\t\t\t\t\tclassName=\"\"\n\t\t\t\t\t\t\t\tfontFamily=\"mono\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{createdAtDate}\n\t\t\t\t\t\t\t</Typography>\n\t\t\t\t\t\t\t<Typography variant=\"bodySmall\" className=\"text-muted-foreground\">\n\t\t\t\t\t\t\t\tCreated\n\t\t\t\t\t\t\t</Typography>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<hr className=\"my-2\" />\n\t\t\t\t\t{artifact.description ? (\n\t\t\t\t\t\t<div className=\"text-muted-foreground overflow-hidden truncate\">\n\t\t\t\t\t\t\t<LazyMarkdown>{artifact.description ?? \"\"}</LazyMarkdown>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Typography\n\t\t\t\t\t\t\tvariant=\"bodySmall\"\n\t\t\t\t\t\t\tclassName=\"text-muted-foreground italic\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tNo description\n\t\t\t\t\t\t</Typography>\n\t\t\t\t\t)}\n\t\t\t\t</CardContent>\n\t\t\t</Card>\n\t\t</Link>\n\t);\n};\n"],"names":["ArtifactCard","artifact","compact","createdAtDate","useMemo","formatDate","jsx","Link","jsxs","Card","CardHeader","Typography","CardContent","cn","LazyMarkdown"],"mappings":"8LAcO,MAAMA,EAAe,CAAC,CAC5B,SAAAC,EACA,QAAAC,EAAU,EACX,IAA0B,CACzB,MAAMC,EAAgBC,EAAAA,QAAQ,IACtBC,EAAW,IAAI,KAAKJ,EAAS,SAAW,EAAE,EAAG,UAAU,EAC5D,CAACA,EAAS,OAAO,CAAC,EACrB,OACCK,EAAAA,IAACC,EAAA,CAAK,GAAG,sBAAsB,OAAQ,CAAE,IAAKN,EAAS,KAAO,EAAA,EAC7D,SAAAO,EAAAA,KAACC,EAAA,CAAK,UAAU,wCACf,SAAA,CAAAH,MAACI,EAAA,CACA,SAAAJ,EAAAA,IAACK,EAAA,CACA,QAAQ,YACR,UAAU,kCAET,SAAAV,EAAS,MAAM,YAAA,CAAY,CAAA,EAE9B,SACCW,EAAA,CACA,SAAA,CAAAJ,EAAAA,KAAC,MAAA,CACA,UAAWK,EACV,OACAX,EAAU,2BAA6B,UAAA,EAGxC,SAAA,CAAAI,EAAAA,IAACK,EAAA,CAAW,QAAST,EAAU,KAAO,KAAM,UAAU,YACpD,WAAS,GAAA,CACX,EACAM,EAAAA,KAAC,MAAA,CACA,UAAWK,EACV,YACAX,EAAU,6BAA+B,iBAAA,EAG1C,SAAA,CAAAI,EAAAA,IAACK,EAAA,CACA,QAAST,EAAU,YAAc,SACjC,UAAU,GACV,WAAW,OAEV,SAAAC,CAAA,CAAA,QAEDQ,EAAA,CAAW,QAAQ,YAAY,UAAU,wBAAwB,SAAA,SAAA,CAElE,CAAA,CAAA,CAAA,CACD,CAAA,CAAA,EAEDL,EAAAA,IAAC,KAAA,CAAG,UAAU,MAAA,CAAO,EACpBL,EAAS,YACTK,MAAC,MAAA,CAAI,UAAU,iDACd,SAAAA,EAAAA,IAACQ,EAAA,CAAc,SAAAb,EAAS,aAAe,EAAA,CAAG,CAAA,CAC3C,EAEAK,EAAAA,IAACK,EAAA,CACA,QAAQ,YACR,UAAU,+BACV,SAAA,gBAAA,CAAA,CAED,CAAA,CAEF,CAAA,CAAA,CACD,CAAA,CACD,CAEF"}
1
+ {"version":3,"file":"artifact-card-BclosG8t.js","sources":["../../src/components/artifacts/artifact-card.tsx"],"sourcesContent":["import { Link } from \"@tanstack/react-router\";\nimport { useMemo } from \"react\";\nimport type { Artifact } from \"@/api/artifacts\";\nimport { LazyMarkdown } from \"@/components/ui/lazy-markdown\";\nimport { cn } from \"@/utils\";\nimport { formatDate } from \"@/utils/date\";\nimport { Card, CardContent, CardHeader } from \"../ui/card\";\nimport { Typography } from \"../ui/typography\";\n\nexport type ArtifactsCardProps = {\n\tartifact: Artifact;\n\tcompact?: boolean;\n};\n\nexport const ArtifactCard = ({\n\tartifact,\n\tcompact = false,\n}: ArtifactsCardProps) => {\n\tconst createdAtDate = useMemo(() => {\n\t\treturn formatDate(new Date(artifact.created ?? \"\"), \"dateTime\");\n\t}, [artifact.created]);\n\treturn (\n\t\t<Link to=\"/artifacts/key/$key\" params={{ key: artifact.key ?? \"\" }}>\n\t\t\t<Card className=\"hover:shadow-lg hover:border-blue-700\">\n\t\t\t\t<CardHeader>\n\t\t\t\t\t<Typography\n\t\t\t\t\t\tvariant=\"bodySmall\"\n\t\t\t\t\t\tclassName=\"font-bold text-muted-foreground\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{artifact.type?.toUpperCase()}\n\t\t\t\t\t</Typography>\n\t\t\t\t</CardHeader>\n\t\t\t\t<CardContent>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\"flex\",\n\t\t\t\t\t\t\tcompact ? \"flex-row justify-between\" : \"flex-col\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Typography variant={compact ? \"h4\" : \"h3\"} className=\"font-bold\">\n\t\t\t\t\t\t\t{artifact.key}\n\t\t\t\t\t\t</Typography>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"flex mt-2\",\n\t\t\t\t\t\t\t\tcompact ? \"flex-col-reverse items-end\" : \"justify-between\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Typography\n\t\t\t\t\t\t\t\tvariant={compact ? \"bodySmall\" : \"xsmall\"}\n\t\t\t\t\t\t\t\tclassName=\"\"\n\t\t\t\t\t\t\t\tfontFamily=\"mono\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{createdAtDate}\n\t\t\t\t\t\t\t</Typography>\n\t\t\t\t\t\t\t<Typography variant=\"bodySmall\" className=\"text-muted-foreground\">\n\t\t\t\t\t\t\t\tCreated\n\t\t\t\t\t\t\t</Typography>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<hr className=\"my-2\" />\n\t\t\t\t\t{artifact.description ? (\n\t\t\t\t\t\t<div className=\"text-muted-foreground overflow-hidden truncate\">\n\t\t\t\t\t\t\t<LazyMarkdown>{artifact.description ?? \"\"}</LazyMarkdown>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Typography\n\t\t\t\t\t\t\tvariant=\"bodySmall\"\n\t\t\t\t\t\t\tclassName=\"text-muted-foreground italic\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tNo description\n\t\t\t\t\t\t</Typography>\n\t\t\t\t\t)}\n\t\t\t\t</CardContent>\n\t\t\t</Card>\n\t\t</Link>\n\t);\n};\n"],"names":["ArtifactCard","artifact","compact","createdAtDate","useMemo","formatDate","jsx","Link","jsxs","Card","CardHeader","Typography","CardContent","cn","LazyMarkdown"],"mappings":"8LAcO,MAAMA,EAAe,CAAC,CAC5B,SAAAC,EACA,QAAAC,EAAU,EACX,IAA0B,CACzB,MAAMC,EAAgBC,EAAAA,QAAQ,IACtBC,EAAW,IAAI,KAAKJ,EAAS,SAAW,EAAE,EAAG,UAAU,EAC5D,CAACA,EAAS,OAAO,CAAC,EACrB,OACCK,EAAAA,IAACC,EAAA,CAAK,GAAG,sBAAsB,OAAQ,CAAE,IAAKN,EAAS,KAAO,EAAA,EAC7D,SAAAO,EAAAA,KAACC,EAAA,CAAK,UAAU,wCACf,SAAA,CAAAH,MAACI,EAAA,CACA,SAAAJ,EAAAA,IAACK,EAAA,CACA,QAAQ,YACR,UAAU,kCAET,SAAAV,EAAS,MAAM,YAAA,CAAY,CAAA,EAE9B,SACCW,EAAA,CACA,SAAA,CAAAJ,EAAAA,KAAC,MAAA,CACA,UAAWK,EACV,OACAX,EAAU,2BAA6B,UAAA,EAGxC,SAAA,CAAAI,EAAAA,IAACK,EAAA,CAAW,QAAST,EAAU,KAAO,KAAM,UAAU,YACpD,WAAS,GAAA,CACX,EACAM,EAAAA,KAAC,MAAA,CACA,UAAWK,EACV,YACAX,EAAU,6BAA+B,iBAAA,EAG1C,SAAA,CAAAI,EAAAA,IAACK,EAAA,CACA,QAAST,EAAU,YAAc,SACjC,UAAU,GACV,WAAW,OAEV,SAAAC,CAAA,CAAA,QAEDQ,EAAA,CAAW,QAAQ,YAAY,UAAU,wBAAwB,SAAA,SAAA,CAElE,CAAA,CAAA,CAAA,CACD,CAAA,CAAA,EAEDL,EAAAA,IAAC,KAAA,CAAG,UAAU,MAAA,CAAO,EACpBL,EAAS,YACTK,MAAC,MAAA,CAAI,UAAU,iDACd,SAAAA,EAAAA,IAACQ,EAAA,CAAc,SAAAb,EAAS,aAAe,EAAA,CAAG,CAAA,CAC3C,EAEAK,EAAAA,IAACK,EAAA,CACA,QAAQ,YACR,UAAU,+BACV,SAAA,gBAAA,CAAA,CAED,CAAA,CAEF,CAAA,CAAA,CACD,CAAA,CACD,CAEF"}
@@ -0,0 +1,2 @@
1
+ import{j as e,r as n,L as h,s as T}from"./vendor-tanstack-BcZfOOfy.js";import{B as f,g,h as j,bw as p,bF as b,D,ap as x,q as v,I as N,y as L,V as _,aQ as m,av as S,br as k,dC as C,dB as M}from"./index-B8vo2Lrg.js";import{a as A}from"./use-get-artifacts-flow-task-runs-DRWRrmrb.js";import{L as w}from"./lazy-markdown-1Hz0xzca.js";import{u as B,E as F}from"./vendor-codemirror-LnHkUyAP.js";import{T as I,a as $,b as y,c as z,d as E,e as H}from"./table-BBNGfPra.js";import{K as r}from"./key-value-XHEZOtZX.js";import"./vendor-react-Bce9NwRC.js";import"./vendor-radix-BTiKGWfR.js";import"./vendor-recharts-BvvJP9Po.js";import"./vendor-forms-ClCIacbh.js";import"./vendor-date-wwuDAncJ.js";const G=({artifact:s})=>{let a=e.jsx(e.Fragment,{});return s.key?a=e.jsx("div",{className:"flex items-center gap-2",children:e.jsx(f,{children:e.jsxs(g,{children:[e.jsx(j,{children:e.jsx(p,{to:"/artifacts/key/$key",params:{key:s.key},className:"text-xl font-semibold",children:s.key})}),e.jsx(b,{}),e.jsx(j,{className:"text-xl font-semibold",children:s.id})]})})}):a=e.jsx("div",{className:"flex items-center gap-2",children:e.jsx(f,{children:e.jsxs(g,{children:[s.flow_run&&e.jsxs(e.Fragment,{children:[e.jsx(j,{children:e.jsx(p,{to:"/runs/flow-run/$id",params:{id:s.flow_run_id??""},className:"text-xl font-semibold",children:s.flow_run.name})}),e.jsx(b,{})]}),s.task_run&&e.jsxs(e.Fragment,{children:[e.jsx(j,{children:e.jsx(p,{to:"/runs/task-run/$id",params:{id:s.task_run_id??""},className:"text-xl font-semibold",children:s.task_run.name})}),e.jsx(b,{})]}),e.jsx(j,{className:"text-xl font-semibold",children:s.id})]})})}),e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center justify-between",children:[a,e.jsx(D,{id:"artifacts-guide",label:"Documentation"})]}),s.description&&e.jsx("div",{className:"",children:e.jsx(x,{variant:"h2",className:"my-4 font-bold prose lg:prose-xl",children:e.jsx(w,{children:s.description})})}),e.jsx("hr",{})]})},O=({artifact:s})=>{const[a,t]=n.useState(!1),i=()=>{t(u=>!u)},d=n.useRef(null),o={highlightActiveLine:!1,foldGutter:!1,highlightActiveLineGutter:!1},{setContainer:l}=B({container:d.current,extensions:[F.lineWrapping],value:String(s.data),indentWithTab:!1,editable:!0,basicSetup:o});n.useEffect(()=>{d.current&&l(d.current)},[l]);const c=u=>{L.success("Copied to clipboard"),navigator.clipboard.writeText(u)};return e.jsxs("div",{className:"flex flex-col justify-center items-center",children:[e.jsxs(v,{"data-testid":"show-raw-data-button",variant:"outline",onClick:i,className:"my-4",children:[a?"Hide":"Show"," Raw Data"]}),e.jsx("div",{className:"rounded-md border shadow-xs focus-within:outline-hidden focus-within:ring-1 focus-within:ring-ring relative",style:{display:a?"block":"none"},ref:u=>{d.current=u},"data-testid":"raw-data-display",children:e.jsx(v,{onClick:()=>c(s.data),variant:"ghost",size:"icon",className:"absolute top-0 right-0 z-10","aria-label":"copy",children:e.jsx(N,{id:"Copy",className:"size-2"})})})]})},P=({url:s})=>e.jsxs("div",{"data-testid":s,className:"prose mt-2",children:[e.jsx("img",{"data-testid":`image-${s}`,src:s,alt:"artifact-image",className:"w-full"}),e.jsxs(x,{variant:"bodyLarge",children:["Image URL:"," ",e.jsx("a",{className:"text-blue-700 hover:underline",target:"_blank",href:s,rel:"noreferrer",children:s})]})]}),K=({markdown:s})=>e.jsx("div",{"data-testid":"markdown-display",className:"mt-4 prose",children:e.jsx(w,{children:s})}),Q=({progress:s})=>e.jsxs(x,{"data-testid":"progress-display",variant:"bodyLarge",children:["Progress: ",s,"%"]}),U=({tableData:s})=>{const a=JSON.parse(s),t=Object.keys(a[0]),[i,d]=n.useState(""),o=n.useMemo(()=>a.filter(l=>Object.values(l).some(c=>String(c).toLowerCase().includes(i.toLowerCase()))),[i,a]);return e.jsxs("div",{"data-testid":"table-display",className:"mt-4",children:[e.jsx("div",{className:"flex flex-row justify-end items-center mb-2",children:e.jsx("div",{children:e.jsx(_,{placeholder:"Search",value:i,onChange:l=>d(l.target.value)})})}),e.jsx("div",{className:"rounded-md border overflow-hidden",children:e.jsxs(I,{children:[e.jsx($,{className:"bg-muted",children:e.jsx(y,{children:t.map(l=>e.jsx(z,{className:"py-2 text-foreground",children:l},l))})}),e.jsx(E,{children:o.map(l=>e.jsx(y,{children:t.map(c=>e.jsx(H,{children:l[c]},c))},l.id))})]})})]})},V=({artifact:s})=>{const a=n.useMemo(()=>s.created?m(s.created,"dateTime"):null,[s.created]);return e.jsxs("div",{className:"mt-4",children:[e.jsx(x,{variant:"bodyLarge",className:"font-bold",children:"Artifact"}),e.jsxs("div",{className:"mt-3 flex flex-col gap-3",children:[e.jsx(r,{label:"Key",value:e.jsx("span",{className:"font-mono",children:s.key??"None"})}),e.jsx(r,{label:"Type",value:e.jsx("span",{className:"font-mono",children:s.type??"None"})}),e.jsx(r,{label:"Created",value:e.jsx("span",{className:"font-mono",children:a??"None"})})]})]})},W=({flowRun:s})=>{const a=n.useMemo(()=>s.start_time?m(s.start_time,"dateTime"):null,[s.start_time]),t=n.useMemo(()=>s.estimated_run_time?S(Math.ceil(s.estimated_run_time)*1e3):null,[s.estimated_run_time]),i=n.useMemo(()=>s.created?m(s.created,"dateTime"):null,[s.created]),d=n.useMemo(()=>s.updated?m(s.updated,"dateTime"):null,[s.updated]);return e.jsxs("div",{className:"mt-4",children:[e.jsx(x,{variant:"bodyLarge",className:"font-bold",children:"Flow Run"}),e.jsxs("div",{className:"mt-3 flex flex-col gap-3",children:[e.jsx(r,{label:"Start time",value:e.jsxs("span",{className:"font-mono flex items-center",children:[e.jsx(N,{id:"Calendar",className:"inline w-4 mr-2"}),a??"None"]})}),e.jsx(r,{label:"Duration",value:e.jsxs("span",{className:"font-mono flex items-center",children:[e.jsx(N,{id:"Clock",className:"inline w-4 mr-2"}),t??"None"]})}),e.jsx(r,{label:"Created",value:e.jsx("span",{className:"font-mono",children:i??"None"})}),e.jsx(r,{label:"Last Updated",value:e.jsx("span",{className:"font-mono",children:d??"None"})}),e.jsx(r,{label:"Tags",value:s.tags&&s.tags.length>0?e.jsx("div",{className:"flex flex-wrap",children:s.tags.map(o=>e.jsx(k,{tag:o},o))}):e.jsx("span",{className:"font-mono",children:"None"})}),e.jsx(r,{label:"State Message",value:e.jsx("span",{className:"font-mono",children:s.state?.message??"None"})})]})]})},J=({artifact:s})=>{const{flow_run:a,task_run:t}=s;return s.key||a||t?e.jsxs("div",{className:"flex flex-col gap-2",children:[s.key&&e.jsx(r,{label:"Artifact",value:e.jsx(h,{to:"/artifacts/key/$key",params:{key:s.key},className:"text-blue-500 hover:underline",children:s.key})}),a&&e.jsx(r,{label:"Flow Run",value:e.jsx(h,{to:"/runs/flow-run/$id",params:{id:a.id},className:"text-blue-500 hover:underline",children:a.name})}),t&&e.jsx(r,{label:"Task Run",value:e.jsx(h,{to:"/runs/task-run/$id",params:{id:t.id},className:"text-blue-500 hover:underline",children:t.name})}),e.jsx("hr",{className:"mt-2 border-border"})]}):null},q=({taskRun:s})=>{const a=n.useMemo(()=>s.created?m(s.created,"dateTime"):null,[s.created]),t=n.useMemo(()=>s.updated?m(s.updated,"dateTime"):null,[s.updated]);return e.jsxs("div",{className:"mt-4",children:[e.jsx(x,{variant:"bodyLarge",className:"font-bold",children:"Task Run"}),e.jsxs("div",{className:"mt-3 flex flex-col gap-3",children:[e.jsx(r,{label:"Created",value:e.jsx("span",{className:"font-mono",children:a??"None"})}),e.jsx(r,{label:"Last Updated",value:e.jsx("span",{className:"font-mono",children:t??"None"})}),e.jsx(r,{label:"Tags",value:s.tags&&s.tags.length>0?e.jsx("div",{className:"flex flex-wrap",children:s.tags.map(i=>e.jsx(k,{tag:i},i))}):e.jsx("span",{className:"font-mono",children:"None"})})]})]})},X=({artifact:s})=>{const{flow_run:a,task_run:t}=s;return e.jsxs("div",{className:"w-[250px] shrink-0 pt-4",children:[e.jsx(J,{artifact:s}),e.jsx(V,{artifact:s}),(a||t)&&e.jsx("hr",{className:"mt-4 border-border"}),a&&e.jsx(W,{flowRun:a}),a&&t&&e.jsx("hr",{className:"mt-4 border-border"}),t&&e.jsx(q,{taskRun:t})]})},Y=({artifact:s})=>{const a=n.useMemo(()=>{switch(s.type){case"markdown":case"link":return e.jsx(K,{markdown:s.data});case"image":return e.jsx(P,{url:s.data});case"progress":return e.jsx(Q,{progress:s.data});case"table":return e.jsx(U,{tableData:s.data});default:return e.jsx("pre",{children:JSON.stringify(s.data,null,2)})}},[s]);return e.jsxs("div",{children:[e.jsx(G,{artifact:s}),e.jsxs("div",{className:"flex flex-row gap-4 justify-between",children:[e.jsxs("div",{className:"flex-grow min-w-0",children:[a,e.jsx(O,{artifact:s})]}),e.jsx(X,{artifact:s})]})]})};function ce(){const{id:s}=C.useParams(),{data:a}=T(M(s)),t=A(s);return e.jsx(Y,{artifact:t??a})}export{ce as component};
2
+ //# sourceMappingURL=artifact._id-C0r4BJr2.js.map