prefect 3.6.15__py3-none-any.whl → 3.6.16.dev3__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.
- prefect/__init__.py +20 -0
- prefect/_build_info.py +3 -3
- prefect/_internal/analytics/__init__.py +80 -0
- prefect/_internal/analytics/_config.py +2 -0
- prefect/_internal/analytics/ci_detection.py +39 -0
- prefect/_internal/analytics/client.py +132 -0
- prefect/_internal/analytics/device_id.py +55 -0
- prefect/_internal/analytics/emit.py +90 -0
- prefect/_internal/analytics/enabled.py +33 -0
- prefect/_internal/analytics/events.py +14 -0
- prefect/_internal/analytics/milestones.py +177 -0
- prefect/_internal/analytics/notice.py +60 -0
- prefect/_internal/analytics/service.py +238 -0
- prefect/analytics/__init__.py +67 -0
- prefect/deployments/runner.py +20 -0
- prefect/flow_engine.py +16 -0
- prefect/flows.py +8 -0
- prefect/logging/formatters.py +24 -1
- prefect/server/ui-v2/assets/{artifact-card-BBzQR-Cj.js → artifact-card-BclosG8t.js} +2 -2
- prefect/server/ui-v2/assets/{artifact-card-BBzQR-Cj.js.map → artifact-card-BclosG8t.js.map} +1 -1
- prefect/server/ui-v2/assets/artifact._id-C0r4BJr2.js +2 -0
- prefect/server/ui-v2/assets/artifact._id-C0r4BJr2.js.map +1 -0
- prefect/server/ui-v2/assets/{automation-wizard-EYSfXlQ7.js → automation-wizard-Bmgt6nn8.js} +2 -2
- prefect/server/ui-v2/assets/{automation-wizard-EYSfXlQ7.js.map → automation-wizard-Bmgt6nn8.js.map} +1 -1
- prefect/server/ui-v2/assets/automation._id-Ccke3KJz.js +2 -0
- prefect/server/ui-v2/assets/{automation._id-Dn7jABys.js.map → automation._id-Ccke3KJz.js.map} +1 -1
- prefect/server/ui-v2/assets/{automation_._id.edit-COrqswD3.js → automation_._id.edit-BlKPUTVf.js} +2 -2
- prefect/server/ui-v2/assets/{automation_._id.edit-COrqswD3.js.map → automation_._id.edit-BlKPUTVf.js.map} +1 -1
- prefect/server/ui-v2/assets/{automations-header-DN_dmMXW.js → automations-header-Df2zw3SC.js} +2 -2
- prefect/server/ui-v2/assets/{automations-header-DN_dmMXW.js.map → automations-header-Df2zw3SC.js.map} +1 -1
- prefect/server/ui-v2/assets/{base-job-template-form-section-De2ACYbw.js → base-job-template-form-section-oZD6U-RW.js} +2 -2
- prefect/server/ui-v2/assets/{base-job-template-form-section-De2ACYbw.js.map → base-job-template-form-section-oZD6U-RW.js.map} +1 -1
- prefect/server/ui-v2/assets/{block-type-details-Cklc7TkK.js → block-type-details-CYrdaLot.js} +2 -2
- prefect/server/ui-v2/assets/{block-type-details-Cklc7TkK.js.map → block-type-details-CYrdaLot.js.map} +1 -1
- prefect/server/ui-v2/assets/block-type-logo-CyAWq7mC.js +2 -0
- prefect/server/ui-v2/assets/block-type-logo-CyAWq7mC.js.map +1 -0
- prefect/server/ui-v2/assets/{block._id-tuz1Bcj2.js → block._id-CBgHrpTP.js} +2 -2
- prefect/server/ui-v2/assets/{block._id-tuz1Bcj2.js.map → block._id-CBgHrpTP.js.map} +1 -1
- prefect/server/ui-v2/assets/{block_._id.edit-CFEYhF5R.js → block_._id.edit-CW-kdi4O.js} +2 -2
- prefect/server/ui-v2/assets/{block_._id.edit-CFEYhF5R.js.map → block_._id.edit-CW-kdi4O.js.map} +1 -1
- prefect/server/ui-v2/assets/{catalog-CCPRo7nY.js → catalog-Brh0kn1I.js} +2 -2
- prefect/server/ui-v2/assets/{catalog-CCPRo7nY.js.map → catalog-Brh0kn1I.js.map} +1 -1
- prefect/server/ui-v2/assets/catalog_._slug-MCgzguIZ.js +2 -0
- prefect/server/ui-v2/assets/{catalog_._slug-Bl2J2oI3.js.map → catalog_._slug-MCgzguIZ.js.map} +1 -1
- prefect/server/ui-v2/assets/{catalog_._slug_.create-9UD_SxDN.js → catalog_._slug_.create-DBaeHi9Q.js} +2 -2
- prefect/server/ui-v2/assets/{catalog_._slug_.create-9UD_SxDN.js.map → catalog_._slug_.create-DBaeHi9Q.js.map} +1 -1
- prefect/server/ui-v2/assets/{collapsible-BVQTBG_U.js → collapsible-B_NJS0uJ.js} +2 -2
- prefect/server/ui-v2/assets/{collapsible-BVQTBG_U.js.map → collapsible-B_NJS0uJ.js.map} +1 -1
- prefect/server/ui-v2/assets/{concurrency-limit._id-CsgRxA0a.js → concurrency-limit._id-qzNUQzQa.js} +2 -2
- prefect/server/ui-v2/assets/{concurrency-limit._id-CsgRxA0a.js.map → concurrency-limit._id-qzNUQzQa.js.map} +1 -1
- prefect/server/ui-v2/assets/create-BwXG6EIb.js +2 -0
- prefect/server/ui-v2/assets/{create-D--LHaji.js.map → create-BwXG6EIb.js.map} +1 -1
- prefect/server/ui-v2/assets/{create-BycfZHGQ.js → create-MoiIE9Ms.js} +2 -2
- prefect/server/ui-v2/assets/{create-BycfZHGQ.js.map → create-MoiIE9Ms.js.map} +1 -1
- prefect/server/ui-v2/assets/data-table-CPkppyg6.js +2 -0
- prefect/server/ui-v2/assets/data-table-CPkppyg6.js.map +1 -0
- prefect/server/ui-v2/assets/delete-confirmation-dialog-CwDK_2QS.js +2 -0
- prefect/server/ui-v2/assets/{delete-confirmation-dialog-DHkm2p8m.js.map → delete-confirmation-dialog-CwDK_2QS.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment-action-header-D5GOooPm.js → deployment-action-header-Vp9YsCJO.js} +2 -2
- prefect/server/ui-v2/assets/{deployment-action-header-D5GOooPm.js.map → deployment-action-header-Vp9YsCJO.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment-form-wfg6HeAJ.js → deployment-form-CJcg_6DJ.js} +3 -3
- prefect/server/ui-v2/assets/{deployment-form-wfg6HeAJ.js.map → deployment-form-CJcg_6DJ.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment-links-6iugOgDh.js → deployment-links-CIkJIuHh.js} +2 -2
- prefect/server/ui-v2/assets/{deployment-links-6iugOgDh.js.map → deployment-links-CIkJIuHh.js.map} +1 -1
- prefect/server/ui-v2/assets/deployment._id-C6XrGMp_.js +2 -0
- prefect/server/ui-v2/assets/{deployment._id-Ci9zge5n.js.map → deployment._id-C6XrGMp_.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment._id-whsGcHdu.js → deployment._id-CWgTYmTG.js} +2 -2
- prefect/server/ui-v2/assets/{deployment._id-whsGcHdu.js.map → deployment._id-CWgTYmTG.js.map} +1 -1
- prefect/server/ui-v2/assets/deployment_._id.duplicate-Bg0s0ZJn.js +2 -0
- prefect/server/ui-v2/assets/{deployment_._id.duplicate-D9ZWkh8H.js.map → deployment_._id.duplicate-Bg0s0ZJn.js.map} +1 -1
- prefect/server/ui-v2/assets/deployment_._id.edit-CnoB0UeG.js +2 -0
- prefect/server/ui-v2/assets/{deployment_._id.edit-CS7sObzC.js.map → deployment_._id.edit-CnoB0UeG.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment_._id.run-g7SZuDFi.js → deployment_._id.run-BqPK6rTB.js} +2 -2
- prefect/server/ui-v2/assets/{deployment_._id.run-g7SZuDFi.js.map → deployment_._id.run-BqPK6rTB.js.map} +1 -1
- prefect/server/ui-v2/assets/{dropdown-menu-0atiOSFo.js → dropdown-menu-D7Gwbd15.js} +2 -2
- prefect/server/ui-v2/assets/{dropdown-menu-0atiOSFo.js.map → dropdown-menu-D7Gwbd15.js.map} +1 -1
- prefect/server/ui-v2/assets/{event-resource-display-DHiAb1Up.js → event-resource-display-CDRgVKd4.js} +2 -2
- prefect/server/ui-v2/assets/{event-resource-display-DHiAb1Up.js.map → event-resource-display-CDRgVKd4.js.map} +1 -1
- prefect/server/ui-v2/assets/event._eventDate._eventId-C73GMDkK.js +2 -0
- prefect/server/ui-v2/assets/{event._eventDate._eventId-D7Twzb22.js.map → event._eventDate._eventId-C73GMDkK.js.map} +1 -1
- prefect/server/ui-v2/assets/{flow-run-graph-BhzuSJLm.js → flow-run-graph-ckiE3mA9.js} +2 -2
- prefect/server/ui-v2/assets/{flow-run-graph-BhzuSJLm.js.map → flow-run-graph-ckiE3mA9.js.map} +1 -1
- prefect/server/ui-v2/assets/{flow-run._id-CqpH6bvx.js → flow-run._id-BukrNCAq.js} +2 -2
- prefect/server/ui-v2/assets/{flow-run._id-CqpH6bvx.js.map → flow-run._id-BukrNCAq.js.map} +1 -1
- prefect/server/ui-v2/assets/{flow-run._id-lIIQBD7H.js → flow-run._id-CtI5VZ2M.js} +2 -2
- prefect/server/ui-v2/assets/{flow-run._id-lIIQBD7H.js.map → flow-run._id-CtI5VZ2M.js.map} +1 -1
- prefect/server/ui-v2/assets/flow-run._id-s1UJuakA.js +4 -0
- prefect/server/ui-v2/assets/{flow-run._id-RLy2kBh0.js.map → flow-run._id-s1UJuakA.js.map} +1 -1
- prefect/server/ui-v2/assets/{flow-runs-pagination-BATUweRV.js → flow-runs-pagination-SLbYtvaR.js} +2 -2
- prefect/server/ui-v2/assets/{flow-runs-pagination-BATUweRV.js.map → flow-runs-pagination-SLbYtvaR.js.map} +1 -1
- prefect/server/ui-v2/assets/flow._id-CZ5P0v4N.js +2 -0
- prefect/server/ui-v2/assets/{flow._id-BdQGWPKP.js.map → flow._id-CZ5P0v4N.js.map} +1 -1
- prefect/server/ui-v2/assets/{form-DLrbC7rV.js → form-mws4law8.js} +2 -2
- prefect/server/ui-v2/assets/{form-DLrbC7rV.js.map → form-mws4law8.js.map} +1 -1
- prefect/server/ui-v2/assets/{header-BTAWyeXv.js → header-Bes1LmY7.js} +2 -2
- prefect/server/ui-v2/assets/{header-BTAWyeXv.js.map → header-Bes1LmY7.js.map} +1 -1
- prefect/server/ui-v2/assets/{header-ChFAx5uR.js → header-Bj_zBR-a.js} +2 -2
- prefect/server/ui-v2/assets/{header-ChFAx5uR.js.map → header-Bj_zBR-a.js.map} +1 -1
- prefect/server/ui-v2/assets/{header-CyQqOj1w.js → header-CPxTHSvz.js} +2 -2
- prefect/server/ui-v2/assets/{header-CyQqOj1w.js.map → header-CPxTHSvz.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-m48E4KcG.js → index-B8vo2Lrg.js} +5 -5
- prefect/server/ui-v2/assets/{index-m48E4KcG.js.map → index-B8vo2Lrg.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-D5RT-SAp.js → index-BBeh-3Nh.js} +2 -2
- prefect/server/ui-v2/assets/{index-D5RT-SAp.js.map → index-BBeh-3Nh.js.map} +1 -1
- prefect/server/ui-v2/assets/index-BLnEvHia.js +2 -0
- prefect/server/ui-v2/assets/{index-7i4X9TeK.js.map → index-BLnEvHia.js.map} +1 -1
- prefect/server/ui-v2/assets/index-BpKoubXu.js +2 -0
- prefect/server/ui-v2/assets/index-BpKoubXu.js.map +1 -0
- prefect/server/ui-v2/assets/index-By6YGqR3.js +2 -0
- prefect/server/ui-v2/assets/index-By6YGqR3.js.map +1 -0
- prefect/server/ui-v2/assets/index-CEi3BlKI.js +2 -0
- prefect/server/ui-v2/assets/index-CEi3BlKI.js.map +1 -0
- prefect/server/ui-v2/assets/{index-BaWDC4da.js → index-CS-zxv7Z.js} +2 -2
- prefect/server/ui-v2/assets/{index-BaWDC4da.js.map → index-CS-zxv7Z.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-kP_I5Qfd.js → index-CToHKh4q.js} +2 -2
- prefect/server/ui-v2/assets/{index-kP_I5Qfd.js.map → index-CToHKh4q.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-CKGj5lSu.js → index-CUVvZndW.js} +2 -2
- prefect/server/ui-v2/assets/{index-CKGj5lSu.js.map → index-CUVvZndW.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-CxUfZRkN.js → index-CYVn-I3i.js} +2 -2
- prefect/server/ui-v2/assets/{index-CxUfZRkN.js.map → index-CYVn-I3i.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-CnlN-VC_.js → index-Cun0JN4t.js} +2 -2
- prefect/server/ui-v2/assets/{index-CnlN-VC_.js.map → index-Cun0JN4t.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-BwCLKpNb.js → index-D6ynV6U7.js} +2 -2
- prefect/server/ui-v2/assets/{index-BwCLKpNb.js.map → index-D6ynV6U7.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-CHf6xi9j.js → index-DdNUJLRW.js} +2 -2
- prefect/server/ui-v2/assets/{index-CHf6xi9j.js.map → index-DdNUJLRW.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-CQnWiUE5.js → index-DlHOXQhu.js} +2 -2
- prefect/server/ui-v2/assets/{index-CQnWiUE5.js.map → index-DlHOXQhu.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-Eqdr6Ff7.js → index-DyVw8YE8.js} +2 -2
- prefect/server/ui-v2/assets/{index-Eqdr6Ff7.js.map → index-DyVw8YE8.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-Btb_-PDp.js → index-DzRz7D2P.js} +2 -2
- prefect/server/ui-v2/assets/{index-Btb_-PDp.js.map → index-DzRz7D2P.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-DQGif3jm.js → index-DzUcVNZg.js} +2 -2
- prefect/server/ui-v2/assets/{index-DQGif3jm.js.map → index-DzUcVNZg.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-DNh9ZBy4.js → index-IBvMMs6S.js} +2 -2
- prefect/server/ui-v2/assets/{index-DNh9ZBy4.js.map → index-IBvMMs6S.js.map} +1 -1
- prefect/server/ui-v2/assets/index-_kpA__te.js +2 -0
- prefect/server/ui-v2/assets/{index-CiSFHkhI.js.map → index-_kpA__te.js.map} +1 -1
- prefect/server/ui-v2/assets/index-m9O-nIOl.css +1 -0
- prefect/server/ui-v2/assets/{index-lyQav_XM.js → index-wOvyf10b.js} +2 -2
- prefect/server/ui-v2/assets/{index-lyQav_XM.js.map → index-wOvyf10b.js.map} +1 -1
- prefect/server/ui-v2/assets/{json-input-Ba-BeBcw.js → json-input-Ce-HlRqa.js} +2 -2
- prefect/server/ui-v2/assets/{json-input-Ba-BeBcw.js.map → json-input-Ce-HlRqa.js.map} +1 -1
- prefect/server/ui-v2/assets/{key-value-DkSKn6jE.js → key-value-XHEZOtZX.js} +2 -2
- prefect/server/ui-v2/assets/{key-value-DkSKn6jE.js.map → key-value-XHEZOtZX.js.map} +1 -1
- prefect/server/ui-v2/assets/{key._key-Cjx57ymg.js → key._key-LpsMf3zD.js} +2 -2
- prefect/server/ui-v2/assets/{key._key-Cjx57ymg.js.map → key._key-LpsMf3zD.js.map} +1 -1
- prefect/server/ui-v2/assets/{lazy-markdown-Du2Xu3Yp.js → lazy-markdown-1Hz0xzca.js} +2 -2
- prefect/server/ui-v2/assets/{lazy-markdown-Du2Xu3Yp.js.map → lazy-markdown-1Hz0xzca.js.map} +1 -1
- prefect/server/ui-v2/assets/{login-DxMF9Jvj.js → login-D5uepl9L.js} +2 -2
- prefect/server/ui-v2/assets/{login-DxMF9Jvj.js.map → login-D5uepl9L.js.map} +1 -1
- prefect/server/ui-v2/assets/{markdown-input-DPi8zyRr.js → markdown-input-CG6M9zD0.js} +2 -2
- prefect/server/ui-v2/assets/{markdown-input-DPi8zyRr.js.map → markdown-input-CG6M9zD0.js.map} +1 -1
- prefect/server/ui-v2/assets/python-example-snippet-DRHcUlCX.js +3 -0
- prefect/server/ui-v2/assets/{python-example-snippet-DfCFYPN_.js.map → python-example-snippet-DRHcUlCX.js.map} +1 -1
- prefect/server/ui-v2/assets/{python-input-mr6GD840.js → python-input-BsUS8fw1.js} +2 -2
- prefect/server/ui-v2/assets/{python-input-mr6GD840.js.map → python-input-BsUS8fw1.js.map} +1 -1
- prefect/server/ui-v2/assets/{radio-group-Co3cN0Kv.js → radio-group-BUsmwdrt.js} +2 -2
- prefect/server/ui-v2/assets/{radio-group-Co3cN0Kv.js.map → radio-group-BUsmwdrt.js.map} +1 -1
- prefect/server/ui-v2/assets/{route-error-state-DnBaNT2T.js → route-error-state-BFBpiIhD.js} +2 -2
- prefect/server/ui-v2/assets/{route-error-state-DnBaNT2T.js.map → route-error-state-BFBpiIhD.js.map} +1 -1
- prefect/server/ui-v2/assets/{schema-form-CWDHSME9.js → schema-form-BwTmkvJk.js} +2 -2
- prefect/server/ui-v2/assets/schema-form-BwTmkvJk.js.map +1 -0
- prefect/server/ui-v2/assets/{schema-form-input-string-format-datetime-BSWlW_aQ.js → schema-form-input-string-format-datetime-nrb3g-JJ.js} +4 -4
- prefect/server/ui-v2/assets/{schema-form-input-string-format-datetime-BSWlW_aQ.js.map → schema-form-input-string-format-datetime-nrb3g-JJ.js.map} +1 -1
- prefect/server/ui-v2/assets/{settings-DU5y6tJE.js → settings-CUBtK5aW.js} +2 -2
- prefect/server/ui-v2/assets/{settings-DU5y6tJE.js.map → settings-CUBtK5aW.js.map} +1 -1
- prefect/server/ui-v2/assets/{sort-filter-DpuWNkQo.js → sort-filter-Cv8zAXMp.js} +2 -2
- prefect/server/ui-v2/assets/{sort-filter-DpuWNkQo.js.map → sort-filter-Cv8zAXMp.js.map} +1 -1
- prefect/server/ui-v2/assets/{table-bBL6C0ZK.js → table-BBNGfPra.js} +2 -2
- prefect/server/ui-v2/assets/{table-bBL6C0ZK.js.map → table-BBNGfPra.js.map} +1 -1
- prefect/server/ui-v2/assets/{tags-input-BLPMVWpZ.js → tags-input-DHrnkwjQ.js} +2 -2
- prefect/server/ui-v2/assets/{tags-input-BLPMVWpZ.js.map → tags-input-DHrnkwjQ.js.map} +1 -1
- prefect/server/ui-v2/assets/task-run-concurrency-limits-reset-dialog-Z8-yFZ2_.js +2 -0
- prefect/server/ui-v2/assets/{task-run-concurrency-limits-reset-dialog-S69sih55.js.map → task-run-concurrency-limits-reset-dialog-Z8-yFZ2_.js.map} +1 -1
- prefect/server/ui-v2/assets/{task-run._id-Dl3Azs8t.js → task-run._id-BY58gqs2.js} +2 -2
- prefect/server/ui-v2/assets/{task-run._id-Dl3Azs8t.js.map → task-run._id-BY58gqs2.js.map} +1 -1
- prefect/server/ui-v2/assets/{task-run._id-B_tIDm4K.js → task-run._id-u73Jxfqw.js} +3 -3
- prefect/server/ui-v2/assets/{task-run._id-B_tIDm4K.js.map → task-run._id-u73Jxfqw.js.map} +1 -1
- prefect/server/ui-v2/assets/task-runs-pagination-DUy3147A.js +2 -0
- prefect/server/ui-v2/assets/{task-runs-pagination-VdR-LO4r.js.map → task-runs-pagination-DUy3147A.js.map} +1 -1
- prefect/server/ui-v2/assets/{textarea-B3_TtPRi.js → textarea-DUhh6-kq.js} +2 -2
- prefect/server/ui-v2/assets/{textarea-B3_TtPRi.js.map → textarea-DUhh6-kq.js.map} +1 -1
- prefect/server/ui-v2/assets/timezone-select-D4Q6VBtD.js +2 -0
- prefect/server/ui-v2/assets/{timezone-select-BuPYznge.js.map → timezone-select-D4Q6VBtD.js.map} +1 -1
- prefect/server/ui-v2/assets/{toggle-group-Cn07UIim.js → toggle-group-7WUJn2Tx.js} +2 -2
- prefect/server/ui-v2/assets/{toggle-group-Cn07UIim.js.map → toggle-group-7WUJn2Tx.js.map} +1 -1
- prefect/server/ui-v2/assets/use-delete-automation-confirmation-dialog-D4AD5Ndf.js +2 -0
- prefect/server/ui-v2/assets/{use-delete-automation-confirmation-dialog-DpdsLH4t.js.map → use-delete-automation-confirmation-dialog-D4AD5Ndf.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-delete-block-document-confirmation-dialog-Cq5nGhzr.js → use-delete-block-document-confirmation-dialog-DnwWEGUY.js} +2 -2
- prefect/server/ui-v2/assets/{use-delete-block-document-confirmation-dialog-Cq5nGhzr.js.map → use-delete-block-document-confirmation-dialog-DnwWEGUY.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-flow-runs-selected-rows-DmQSWBTu.js → use-flow-runs-selected-rows-C-tehPRB.js} +2 -2
- prefect/server/ui-v2/assets/{use-flow-runs-selected-rows-DmQSWBTu.js.map → use-flow-runs-selected-rows-C-tehPRB.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-get-artifacts-flow-task-runs-DTwcWiqW.js → use-get-artifacts-flow-task-runs-DRWRrmrb.js} +2 -2
- prefect/server/ui-v2/assets/{use-get-artifacts-flow-task-runs-DTwcWiqW.js.map → use-get-artifacts-flow-task-runs-DRWRrmrb.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-quick-run-CPempwLh.js → use-quick-run-B4Xj-YQQ.js} +2 -2
- prefect/server/ui-v2/assets/{use-quick-run-CPempwLh.js.map → use-quick-run-B4Xj-YQQ.js.map} +1 -1
- prefect/server/ui-v2/assets/use-state-favicon-au2TZdMV.js +2 -0
- prefect/server/ui-v2/assets/{use-state-favicon-M09DmrNy.js.map → use-state-favicon-au2TZdMV.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-stepper-CDucnvzp.js → use-stepper-DyIb3vlq.js} +2 -2
- prefect/server/ui-v2/assets/{use-stepper-CDucnvzp.js.map → use-stepper-DyIb3vlq.js.map} +1 -1
- prefect/server/ui-v2/assets/{utilities-BRCNRcQl.js → utilities-D9Y2wo66.js} +2 -2
- prefect/server/ui-v2/assets/{utilities-BRCNRcQl.js.map → utilities-D9Y2wo66.js.map} +1 -1
- prefect/server/ui-v2/assets/vendor-recharts-BvvJP9Po.js +34 -0
- prefect/server/ui-v2/assets/vendor-recharts-BvvJP9Po.js.map +1 -0
- prefect/server/ui-v2/assets/{work-pool-filter-C2tpSS-w.js → work-pool-filter-CSOATj2D.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool-filter-C2tpSS-w.js.map → work-pool-filter-CSOATj2D.js.map} +1 -1
- prefect/server/ui-v2/assets/work-pool-queue-toggle-Dh7B1zMo.js +2 -0
- prefect/server/ui-v2/assets/{work-pool-queue-toggle-BQ9b-Wxy.js.map → work-pool-queue-toggle-Dh7B1zMo.js.map} +1 -1
- prefect/server/ui-v2/assets/work-pool._workPoolName-B_NFWXKS.js +2 -0
- prefect/server/ui-v2/assets/{work-pool._workPoolName-C_LiL3SE.js.map → work-pool._workPoolName-B_NFWXKS.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.edit-DBHlrVVx.js → work-pool_._workPoolName.edit-Cyzn8g-S.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.edit-DBHlrVVx.js.map → work-pool_._workPoolName.edit-Cyzn8g-S.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.queue._workQueueName-DkITxJOP.js → work-pool_._workPoolName.queue._workQueueName-DQzqQWPT.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.queue._workQueueName-DkITxJOP.js.map → work-pool_._workPoolName.queue._workQueueName-DQzqQWPT.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-queue-icon-text-D4BWBVDN.js → work-queue-icon-text-BOpcJ8YU.js} +2 -2
- prefect/server/ui-v2/assets/{work-queue-icon-text-D4BWBVDN.js.map → work-queue-icon-text-BOpcJ8YU.js.map} +1 -1
- prefect/server/ui-v2/index.html +3 -3
- {prefect-3.6.15.dist-info → prefect-3.6.16.dev3.dist-info}/METADATA +2 -1
- {prefect-3.6.15.dist-info → prefect-3.6.16.dev3.dist-info}/RECORD +223 -211
- prefect/server/ui-v2/assets/artifact._id-BFdf1WUA.js +0 -2
- prefect/server/ui-v2/assets/artifact._id-BFdf1WUA.js.map +0 -1
- prefect/server/ui-v2/assets/automation._id-Dn7jABys.js +0 -2
- prefect/server/ui-v2/assets/block-type-logo-Cbpfxded.js +0 -2
- prefect/server/ui-v2/assets/block-type-logo-Cbpfxded.js.map +0 -1
- prefect/server/ui-v2/assets/catalog_._slug-Bl2J2oI3.js +0 -2
- prefect/server/ui-v2/assets/create-D--LHaji.js +0 -2
- prefect/server/ui-v2/assets/data-table-rlbkLcrY.js +0 -2
- prefect/server/ui-v2/assets/data-table-rlbkLcrY.js.map +0 -1
- prefect/server/ui-v2/assets/delete-confirmation-dialog-DHkm2p8m.js +0 -2
- prefect/server/ui-v2/assets/deployment._id-Ci9zge5n.js +0 -2
- prefect/server/ui-v2/assets/deployment_._id.duplicate-D9ZWkh8H.js +0 -2
- prefect/server/ui-v2/assets/deployment_._id.edit-CS7sObzC.js +0 -2
- prefect/server/ui-v2/assets/event._eventDate._eventId-D7Twzb22.js +0 -2
- prefect/server/ui-v2/assets/flow-run._id-RLy2kBh0.js +0 -4
- prefect/server/ui-v2/assets/flow._id-BdQGWPKP.js +0 -2
- prefect/server/ui-v2/assets/index-7i4X9TeK.js +0 -2
- prefect/server/ui-v2/assets/index-BkiGTHwU.js +0 -2
- prefect/server/ui-v2/assets/index-BkiGTHwU.js.map +0 -1
- prefect/server/ui-v2/assets/index-COouj_0-.css +0 -1
- prefect/server/ui-v2/assets/index-CiSFHkhI.js +0 -2
- prefect/server/ui-v2/assets/index-DATPYZfT.js +0 -2
- prefect/server/ui-v2/assets/index-DATPYZfT.js.map +0 -1
- prefect/server/ui-v2/assets/index-VH4TnZ4e.js +0 -2
- prefect/server/ui-v2/assets/index-VH4TnZ4e.js.map +0 -1
- prefect/server/ui-v2/assets/python-example-snippet-DfCFYPN_.js +0 -3
- prefect/server/ui-v2/assets/schema-form-CWDHSME9.js.map +0 -1
- prefect/server/ui-v2/assets/task-run-concurrency-limits-reset-dialog-S69sih55.js +0 -2
- prefect/server/ui-v2/assets/task-runs-pagination-VdR-LO4r.js +0 -2
- prefect/server/ui-v2/assets/timezone-select-BuPYznge.js +0 -2
- prefect/server/ui-v2/assets/use-delete-automation-confirmation-dialog-DpdsLH4t.js +0 -2
- prefect/server/ui-v2/assets/use-state-favicon-M09DmrNy.js +0 -2
- prefect/server/ui-v2/assets/vendor-recharts-BAN776s_.js +0 -34
- prefect/server/ui-v2/assets/vendor-recharts-BAN776s_.js.map +0 -1
- prefect/server/ui-v2/assets/work-pool-queue-toggle-BQ9b-Wxy.js +0 -2
- prefect/server/ui-v2/assets/work-pool._workPoolName-C_LiL3SE.js +0 -2
- {prefect-3.6.15.dist-info → prefect-3.6.16.dev3.dist-info}/WHEEL +0 -0
- {prefect-3.6.15.dist-info → prefect-3.6.16.dev3.dist-info}/entry_points.txt +0 -0
- {prefect-3.6.15.dist-info → prefect-3.6.16.dev3.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"]
|
prefect/deployments/runner.py
CHANGED
|
@@ -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/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__")
|
prefect/logging/formatters.py
CHANGED
|
@@ -16,6 +16,25 @@ ExceptionInfoType = Union[
|
|
|
16
16
|
]
|
|
17
17
|
|
|
18
18
|
|
|
19
|
+
def _make_record_serializable(record_dict: dict[str, Any]) -> dict[str, Any]:
|
|
20
|
+
"""
|
|
21
|
+
Convert a log record dict to be JSON-serializable by replacing
|
|
22
|
+
non-serializable values with placeholder strings.
|
|
23
|
+
|
|
24
|
+
This is used as a fallback when the initial serialization attempt fails,
|
|
25
|
+
which can happen when log records contain objects like websocket connections
|
|
26
|
+
or other non-serializable types.
|
|
27
|
+
"""
|
|
28
|
+
result = {}
|
|
29
|
+
for key, value in record_dict.items():
|
|
30
|
+
try:
|
|
31
|
+
orjson.dumps(value)
|
|
32
|
+
result[key] = value
|
|
33
|
+
except (TypeError, ValueError):
|
|
34
|
+
result[key] = f"<non-serializable: {type(value).__name__}>"
|
|
35
|
+
return result
|
|
36
|
+
|
|
37
|
+
|
|
19
38
|
def format_exception_info(exc_info: ExceptionInfoType) -> dict[str, Any]:
|
|
20
39
|
# if sys.exc_info() returned a (None, None, None) tuple,
|
|
21
40
|
# then there's nothing to format
|
|
@@ -66,7 +85,11 @@ class JsonFormatter(logging.Formatter):
|
|
|
66
85
|
if record.exc_info:
|
|
67
86
|
record_dict["exc_info"] = format_exception_info(record.exc_info)
|
|
68
87
|
|
|
69
|
-
|
|
88
|
+
try:
|
|
89
|
+
log_json_bytes = self.serializer.dumps(record_dict)
|
|
90
|
+
except Exception:
|
|
91
|
+
record_dict = _make_record_serializable(record_dict)
|
|
92
|
+
log_json_bytes = self.serializer.dumps(record_dict)
|
|
70
93
|
|
|
71
94
|
# JSONSerializer returns bytes; decode to string to conform to
|
|
72
95
|
# the `logging.Formatter.format` interface
|
|
@@ -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-
|
|
2
|
-
//# sourceMappingURL=artifact-card-
|
|
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-
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact._id-C0r4BJr2.js","sources":["../../src/components/artifacts/artifact/artifact-detail-header.tsx","../../src/components/artifacts/artifact/artifact-raw-data-display.tsx","../../src/components/artifacts/artifact/detail-image.tsx","../../src/components/artifacts/artifact/detail-markdown.tsx","../../src/components/artifacts/artifact/detail-progress.tsx","../../src/components/artifacts/artifact/detail-table.tsx","../../src/components/artifacts/artifact/metadata-sidebar/artifact-section.tsx","../../src/components/artifacts/artifact/metadata-sidebar/flow-run-section.tsx","../../src/components/artifacts/artifact/metadata-sidebar/links-section.tsx","../../src/components/artifacts/artifact/metadata-sidebar/task-run-section.tsx","../../src/components/artifacts/artifact/metadata-sidebar/index.tsx","../../src/components/artifacts/artifact/artifact-detail-page.tsx","../../src/routes/artifacts/artifact.$id.tsx?tsr-split=component"],"sourcesContent":["import type { ArtifactWithFlowRunAndTaskRun } from \"@/api/artifacts\";\nimport {\n\tBreadcrumb,\n\tBreadcrumbItem,\n\tBreadcrumbLink,\n\tBreadcrumbList,\n\tBreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\";\nimport { DocsLink } from \"@/components/ui/docs-link\";\nimport { LazyMarkdown } from \"@/components/ui/lazy-markdown\";\nimport { Typography } from \"@/components/ui/typography\";\n\nexport type ArtifactDetailHeaderProps = {\n\tartifact: ArtifactWithFlowRunAndTaskRun;\n};\n\nexport const ArtifactDetailHeader = ({\n\tartifact,\n}: ArtifactDetailHeaderProps) => {\n\tlet header = <></>;\n\tif (artifact.key) {\n\t\theader = (\n\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t<Breadcrumb>\n\t\t\t\t\t<BreadcrumbList>\n\t\t\t\t\t\t<BreadcrumbItem>\n\t\t\t\t\t\t\t<BreadcrumbLink\n\t\t\t\t\t\t\t\tto=\"/artifacts/key/$key\"\n\t\t\t\t\t\t\t\tparams={{ key: artifact.key }}\n\t\t\t\t\t\t\t\tclassName=\"text-xl font-semibold\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{artifact.key}\n\t\t\t\t\t\t\t</BreadcrumbLink>\n\t\t\t\t\t\t</BreadcrumbItem>\n\t\t\t\t\t\t<BreadcrumbSeparator />\n\t\t\t\t\t\t<BreadcrumbItem className=\"text-xl font-semibold\">\n\t\t\t\t\t\t\t{artifact.id}\n\t\t\t\t\t\t</BreadcrumbItem>\n\t\t\t\t\t</BreadcrumbList>\n\t\t\t\t</Breadcrumb>\n\t\t\t</div>\n\t\t);\n\t} else {\n\t\theader = (\n\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t<Breadcrumb>\n\t\t\t\t\t<BreadcrumbList>\n\t\t\t\t\t\t{artifact.flow_run && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<BreadcrumbItem>\n\t\t\t\t\t\t\t\t\t<BreadcrumbLink\n\t\t\t\t\t\t\t\t\t\tto=\"/runs/flow-run/$id\"\n\t\t\t\t\t\t\t\t\t\tparams={{ id: artifact.flow_run_id ?? \"\" }}\n\t\t\t\t\t\t\t\t\t\tclassName=\"text-xl font-semibold\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{artifact.flow_run.name}\n\t\t\t\t\t\t\t\t\t</BreadcrumbLink>\n\t\t\t\t\t\t\t\t</BreadcrumbItem>\n\t\t\t\t\t\t\t\t<BreadcrumbSeparator />\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{artifact.task_run && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<BreadcrumbItem>\n\t\t\t\t\t\t\t\t\t<BreadcrumbLink\n\t\t\t\t\t\t\t\t\t\tto=\"/runs/task-run/$id\"\n\t\t\t\t\t\t\t\t\t\tparams={{ id: artifact.task_run_id ?? \"\" }}\n\t\t\t\t\t\t\t\t\t\tclassName=\"text-xl font-semibold\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{artifact.task_run.name}\n\t\t\t\t\t\t\t\t\t</BreadcrumbLink>\n\t\t\t\t\t\t\t\t</BreadcrumbItem>\n\t\t\t\t\t\t\t\t<BreadcrumbSeparator />\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<BreadcrumbItem className=\"text-xl font-semibold\">\n\t\t\t\t\t\t\t{artifact.id}\n\t\t\t\t\t\t</BreadcrumbItem>\n\t\t\t\t\t</BreadcrumbList>\n\t\t\t\t</Breadcrumb>\n\t\t\t</div>\n\t\t);\n\t}\n\treturn (\n\t\t<>\n\t\t\t<div className=\"flex items-center justify-between\">\n\t\t\t\t{header}\n\t\t\t\t<DocsLink id=\"artifacts-guide\" label=\"Documentation\" />\n\t\t\t</div>\n\t\t\t{artifact.description && (\n\t\t\t\t<div className=\"\">\n\t\t\t\t\t<Typography variant=\"h2\" className=\"my-4 font-bold prose lg:prose-xl\">\n\t\t\t\t\t\t<LazyMarkdown>{artifact.description}</LazyMarkdown>\n\t\t\t\t\t</Typography>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<hr />\n\t\t</>\n\t);\n};\n","import { EditorView, useCodeMirror } from \"@uiw/react-codemirror\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { toast } from \"sonner\";\nimport type { ArtifactWithFlowRunAndTaskRun } from \"@/api/artifacts\";\nimport { Button } from \"@/components/ui/button\";\nimport { Icon } from \"@/components/ui/icons\";\n\ntype ArtifactDataDisplayProps = {\n\tartifact: ArtifactWithFlowRunAndTaskRun;\n};\n\nexport const ArtifactDataDisplay = ({ artifact }: ArtifactDataDisplayProps) => {\n\tconst [showData, setShowData] = useState(false);\n\n\tconst toggleShowData = () => {\n\t\tsetShowData((val) => !val);\n\t};\n\n\tconst editor = useRef<HTMLDivElement | null>(null);\n\tconst basicSetup = {\n\t\thighlightActiveLine: false,\n\t\tfoldGutter: false,\n\t\thighlightActiveLineGutter: false,\n\t};\n\tconst { setContainer } = useCodeMirror({\n\t\tcontainer: editor.current,\n\t\textensions: [EditorView.lineWrapping],\n\t\tvalue: String(artifact.data),\n\t\tindentWithTab: false,\n\t\teditable: true,\n\t\tbasicSetup,\n\t});\n\n\tuseEffect(() => {\n\t\tif (editor.current) {\n\t\t\tsetContainer(editor.current);\n\t\t}\n\t}, [setContainer]);\n\n\tconst handleCopy = (_value: string) => {\n\t\ttoast.success(\"Copied to clipboard\");\n\t\tvoid navigator.clipboard.writeText(_value);\n\t};\n\n\treturn (\n\t\t<div className=\"flex flex-col justify-center items-center\">\n\t\t\t<Button\n\t\t\t\tdata-testid=\"show-raw-data-button\"\n\t\t\t\tvariant={\"outline\"}\n\t\t\t\tonClick={toggleShowData}\n\t\t\t\tclassName=\"my-4\"\n\t\t\t>\n\t\t\t\t{showData ? \"Hide\" : \"Show\"} Raw Data\n\t\t\t</Button>\n\n\t\t\t<div\n\t\t\t\tclassName=\"rounded-md border shadow-xs focus-within:outline-hidden focus-within:ring-1 focus-within:ring-ring relative\"\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: showData ? \"block\" : \"none\",\n\t\t\t\t}}\n\t\t\t\tref={(node) => {\n\t\t\t\t\teditor.current = node;\n\t\t\t\t}}\n\t\t\t\tdata-testid=\"raw-data-display\"\n\t\t\t>\n\t\t\t\t<Button\n\t\t\t\t\tonClick={() => handleCopy(artifact.data as string)}\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\tclassName=\"absolute top-0 right-0 z-10\"\n\t\t\t\t\taria-label=\"copy\"\n\t\t\t\t>\n\t\t\t\t\t<Icon id=\"Copy\" className=\"size-2\" />\n\t\t\t\t</Button>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import { Typography } from \"@/components/ui/typography\";\n\nexport type DetailImageProps = {\n\turl: string;\n};\n\nexport const DetailImage = ({ url }: DetailImageProps) => {\n\treturn (\n\t\t<div data-testid={url} className=\"prose mt-2\">\n\t\t\t<img\n\t\t\t\tdata-testid={`image-${url}`}\n\t\t\t\tsrc={url}\n\t\t\t\talt=\"artifact-image\"\n\t\t\t\tclassName=\"w-full\"\n\t\t\t/>\n\n\t\t\t<Typography variant=\"bodyLarge\">\n\t\t\t\tImage URL:{\" \"}\n\t\t\t\t<a\n\t\t\t\t\tclassName=\"text-blue-700 hover:underline\"\n\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\thref={url}\n\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t>\n\t\t\t\t\t{url}\n\t\t\t\t</a>\n\t\t\t</Typography>\n\t\t</div>\n\t);\n};\n","import { LazyMarkdown } from \"@/components/ui/lazy-markdown\";\n\nexport type DetailMarkdownProps = {\n\tmarkdown: string;\n};\n\nexport const DetailMarkdown = ({ markdown }: DetailMarkdownProps) => {\n\treturn (\n\t\t<div data-testid=\"markdown-display\" className=\"mt-4 prose\">\n\t\t\t<LazyMarkdown>{markdown}</LazyMarkdown>\n\t\t</div>\n\t);\n};\n","import { Typography } from \"@/components/ui/typography\";\n\nexport type DetailProgressProps = {\n\tprogress: number;\n};\n\nexport const DetailProgress = ({ progress }: DetailProgressProps) => {\n\treturn (\n\t\t<Typography data-testid=\"progress-display\" variant=\"bodyLarge\">\n\t\t\tProgress: {progress}%\n\t\t</Typography>\n\t);\n};\n","import { useMemo, useState } from \"react\";\nimport { SearchInput } from \"@/components/ui/input\";\nimport {\n\tTable,\n\tTableBody,\n\tTableCell,\n\tTableHead,\n\tTableHeader,\n\tTableRow,\n} from \"@/components/ui/table\";\n\nexport type DetailTableProps = {\n\ttableData: string;\n};\n\nexport const DetailTable = ({ tableData }: DetailTableProps) => {\n\tconst table = JSON.parse(tableData) as Record<string, string>[];\n\tconst headers = Object.keys(table[0]);\n\tconst [input, setInput] = useState<string>(\"\");\n\n\tconst filteredTable = useMemo(() => {\n\t\treturn table.filter((row) => {\n\t\t\treturn Object.values(row).some((value: string) =>\n\t\t\t\tString(value).toLowerCase().includes(input.toLowerCase()),\n\t\t\t);\n\t\t});\n\t}, [input, table]);\n\n\treturn (\n\t\t<div data-testid=\"table-display\" className=\"mt-4\">\n\t\t\t<div className=\"flex flex-row justify-end items-center mb-2\">\n\t\t\t\t<div>\n\t\t\t\t\t<SearchInput\n\t\t\t\t\t\tplaceholder=\"Search\"\n\t\t\t\t\t\tvalue={input}\n\t\t\t\t\t\tonChange={(e) => setInput(e.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div className=\"rounded-md border overflow-hidden\">\n\t\t\t\t<Table>\n\t\t\t\t\t<TableHeader className=\"bg-muted\">\n\t\t\t\t\t\t<TableRow>\n\t\t\t\t\t\t\t{headers.map((header) => {\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<TableHead key={header} className=\"py-2 text-foreground\">\n\t\t\t\t\t\t\t\t\t\t{header}\n\t\t\t\t\t\t\t\t\t</TableHead>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t</TableHeader>\n\t\t\t\t\t<TableBody>\n\t\t\t\t\t\t{filteredTable.map((row) => {\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<TableRow key={row.id}>\n\t\t\t\t\t\t\t\t\t{headers.map((header) => {\n\t\t\t\t\t\t\t\t\t\treturn <TableCell key={header}>{row[header]}</TableCell>;\n\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</TableBody>\n\t\t\t\t</Table>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import { useMemo } from \"react\";\nimport type { ArtifactWithFlowRunAndTaskRun } from \"@/api/artifacts\";\nimport { KeyValue } from \"@/components/ui/key-value\";\nimport { Typography } from \"@/components/ui/typography\";\nimport { formatDate } from \"@/utils/date\";\n\ntype ArtifactSectionProps = {\n\tartifact: ArtifactWithFlowRunAndTaskRun;\n};\n\nexport const ArtifactSection = ({ artifact }: ArtifactSectionProps) => {\n\tconst createdDate = useMemo(() => {\n\t\tif (!artifact.created) return null;\n\t\treturn formatDate(artifact.created, \"dateTime\");\n\t}, [artifact.created]);\n\n\treturn (\n\t\t<div className=\"mt-4\">\n\t\t\t<Typography variant=\"bodyLarge\" className=\"font-bold\">\n\t\t\t\tArtifact\n\t\t\t</Typography>\n\n\t\t\t<div className=\"mt-3 flex flex-col gap-3\">\n\t\t\t\t<KeyValue\n\t\t\t\t\tlabel=\"Key\"\n\t\t\t\t\tvalue={<span className=\"font-mono\">{artifact.key ?? \"None\"}</span>}\n\t\t\t\t/>\n\n\t\t\t\t<KeyValue\n\t\t\t\t\tlabel=\"Type\"\n\t\t\t\t\tvalue={<span className=\"font-mono\">{artifact.type ?? \"None\"}</span>}\n\t\t\t\t/>\n\n\t\t\t\t<KeyValue\n\t\t\t\t\tlabel=\"Created\"\n\t\t\t\t\tvalue={<span className=\"font-mono\">{createdDate ?? \"None\"}</span>}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import humanizeDuration from \"humanize-duration\";\nimport { useMemo } from \"react\";\nimport type { FlowRun } from \"@/api/flow-runs\";\nimport { Icon } from \"@/components/ui/icons\";\nimport { KeyValue } from \"@/components/ui/key-value\";\nimport { TagBadge } from \"@/components/ui/tag-badge\";\nimport { Typography } from \"@/components/ui/typography\";\nimport { formatDate } from \"@/utils/date\";\n\ntype FlowRunSectionProps = {\n\tflowRun: FlowRun;\n};\n\nexport const FlowRunSection = ({ flowRun }: FlowRunSectionProps) => {\n\tconst startTime = useMemo(() => {\n\t\tif (!flowRun.start_time) return null;\n\t\treturn formatDate(flowRun.start_time, \"dateTime\");\n\t}, [flowRun.start_time]);\n\n\tconst duration = useMemo(() => {\n\t\tif (!flowRun.estimated_run_time) return null;\n\t\treturn humanizeDuration(Math.ceil(flowRun.estimated_run_time) * 1000);\n\t}, [flowRun.estimated_run_time]);\n\n\tconst createdDate = useMemo(() => {\n\t\tif (!flowRun.created) return null;\n\t\treturn formatDate(flowRun.created, \"dateTime\");\n\t}, [flowRun.created]);\n\n\tconst updatedDate = useMemo(() => {\n\t\tif (!flowRun.updated) return null;\n\t\treturn formatDate(flowRun.updated, \"dateTime\");\n\t}, [flowRun.updated]);\n\n\treturn (\n\t\t<div className=\"mt-4\">\n\t\t\t<Typography variant=\"bodyLarge\" className=\"font-bold\">\n\t\t\t\tFlow Run\n\t\t\t</Typography>\n\n\t\t\t<div className=\"mt-3 flex flex-col gap-3\">\n\t\t\t\t<KeyValue\n\t\t\t\t\tlabel=\"Start time\"\n\t\t\t\t\tvalue={\n\t\t\t\t\t\t<span className=\"font-mono flex items-center\">\n\t\t\t\t\t\t\t<Icon id=\"Calendar\" className=\"inline w-4 mr-2\" />\n\t\t\t\t\t\t\t{startTime ?? \"None\"}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t/>\n\n\t\t\t\t<KeyValue\n\t\t\t\t\tlabel=\"Duration\"\n\t\t\t\t\tvalue={\n\t\t\t\t\t\t<span className=\"font-mono flex items-center\">\n\t\t\t\t\t\t\t<Icon id=\"Clock\" className=\"inline w-4 mr-2\" />\n\t\t\t\t\t\t\t{duration ?? \"None\"}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t/>\n\n\t\t\t\t<KeyValue\n\t\t\t\t\tlabel=\"Created\"\n\t\t\t\t\tvalue={<span className=\"font-mono\">{createdDate ?? \"None\"}</span>}\n\t\t\t\t/>\n\n\t\t\t\t<KeyValue\n\t\t\t\t\tlabel=\"Last Updated\"\n\t\t\t\t\tvalue={<span className=\"font-mono\">{updatedDate ?? \"None\"}</span>}\n\t\t\t\t/>\n\n\t\t\t\t<KeyValue\n\t\t\t\t\tlabel=\"Tags\"\n\t\t\t\t\tvalue={\n\t\t\t\t\t\tflowRun.tags && flowRun.tags.length > 0 ? (\n\t\t\t\t\t\t\t<div className=\"flex flex-wrap\">\n\t\t\t\t\t\t\t\t{flowRun.tags.map((tag) => (\n\t\t\t\t\t\t\t\t\t<TagBadge key={tag} tag={tag} />\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<span className=\"font-mono\">None</span>\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t/>\n\n\t\t\t\t<KeyValue\n\t\t\t\t\tlabel=\"State Message\"\n\t\t\t\t\tvalue={\n\t\t\t\t\t\t<span className=\"font-mono\">\n\t\t\t\t\t\t\t{flowRun.state?.message ?? \"None\"}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import { Link } from \"@tanstack/react-router\";\nimport type { ArtifactWithFlowRunAndTaskRun } from \"@/api/artifacts\";\nimport { KeyValue } from \"@/components/ui/key-value\";\n\ntype LinksSectionProps = {\n\tartifact: ArtifactWithFlowRunAndTaskRun;\n};\n\nexport const LinksSection = ({ artifact }: LinksSectionProps) => {\n\tconst { flow_run, task_run } = artifact;\n\tconst hasLinks = artifact.key || flow_run || task_run;\n\n\tif (!hasLinks) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-2\">\n\t\t\t{artifact.key && (\n\t\t\t\t<KeyValue\n\t\t\t\t\tlabel=\"Artifact\"\n\t\t\t\t\tvalue={\n\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\tto=\"/artifacts/key/$key\"\n\t\t\t\t\t\t\tparams={{ key: artifact.key }}\n\t\t\t\t\t\t\tclassName=\"text-blue-500 hover:underline\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{artifact.key}\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{flow_run && (\n\t\t\t\t<KeyValue\n\t\t\t\t\tlabel=\"Flow Run\"\n\t\t\t\t\tvalue={\n\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\tto=\"/runs/flow-run/$id\"\n\t\t\t\t\t\t\tparams={{ id: flow_run.id }}\n\t\t\t\t\t\t\tclassName=\"text-blue-500 hover:underline\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{flow_run.name}\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{task_run && (\n\t\t\t\t<KeyValue\n\t\t\t\t\tlabel=\"Task Run\"\n\t\t\t\t\tvalue={\n\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\tto=\"/runs/task-run/$id\"\n\t\t\t\t\t\t\tparams={{ id: task_run.id }}\n\t\t\t\t\t\t\tclassName=\"text-blue-500 hover:underline\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{task_run.name}\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t<hr className=\"mt-2 border-border\" />\n\t\t</div>\n\t);\n};\n","import { useMemo } from \"react\";\nimport type { TaskRun } from \"@/api/task-runs\";\nimport { KeyValue } from \"@/components/ui/key-value\";\nimport { TagBadge } from \"@/components/ui/tag-badge\";\nimport { Typography } from \"@/components/ui/typography\";\nimport { formatDate } from \"@/utils/date\";\n\ntype TaskRunSectionProps = {\n\ttaskRun: TaskRun;\n};\n\nexport const TaskRunSection = ({ taskRun }: TaskRunSectionProps) => {\n\tconst createdDate = useMemo(() => {\n\t\tif (!taskRun.created) return null;\n\t\treturn formatDate(taskRun.created, \"dateTime\");\n\t}, [taskRun.created]);\n\n\tconst updatedDate = useMemo(() => {\n\t\tif (!taskRun.updated) return null;\n\t\treturn formatDate(taskRun.updated, \"dateTime\");\n\t}, [taskRun.updated]);\n\n\treturn (\n\t\t<div className=\"mt-4\">\n\t\t\t<Typography variant=\"bodyLarge\" className=\"font-bold\">\n\t\t\t\tTask Run\n\t\t\t</Typography>\n\n\t\t\t<div className=\"mt-3 flex flex-col gap-3\">\n\t\t\t\t<KeyValue\n\t\t\t\t\tlabel=\"Created\"\n\t\t\t\t\tvalue={<span className=\"font-mono\">{createdDate ?? \"None\"}</span>}\n\t\t\t\t/>\n\n\t\t\t\t<KeyValue\n\t\t\t\t\tlabel=\"Last Updated\"\n\t\t\t\t\tvalue={<span className=\"font-mono\">{updatedDate ?? \"None\"}</span>}\n\t\t\t\t/>\n\n\t\t\t\t<KeyValue\n\t\t\t\t\tlabel=\"Tags\"\n\t\t\t\t\tvalue={\n\t\t\t\t\t\ttaskRun.tags && taskRun.tags.length > 0 ? (\n\t\t\t\t\t\t\t<div className=\"flex flex-wrap\">\n\t\t\t\t\t\t\t\t{taskRun.tags.map((tag) => (\n\t\t\t\t\t\t\t\t\t<TagBadge key={tag} tag={tag} />\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<span className=\"font-mono\">None</span>\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import type { ArtifactWithFlowRunAndTaskRun } from \"@/api/artifacts\";\nimport { ArtifactSection } from \"./artifact-section\";\nimport { FlowRunSection } from \"./flow-run-section\";\nimport { LinksSection } from \"./links-section\";\nimport { TaskRunSection } from \"./task-run-section\";\n\nexport type MetadataSidebarProps = {\n\tartifact: ArtifactWithFlowRunAndTaskRun;\n};\n\nexport const MetadataSidebar = ({ artifact }: MetadataSidebarProps) => {\n\tconst { flow_run, task_run } = artifact;\n\n\treturn (\n\t\t<div className=\"w-[250px] shrink-0 pt-4\">\n\t\t\t<LinksSection artifact={artifact} />\n\n\t\t\t<ArtifactSection artifact={artifact} />\n\n\t\t\t{(flow_run || task_run) && <hr className=\"mt-4 border-border\" />}\n\n\t\t\t{flow_run && <FlowRunSection flowRun={flow_run} />}\n\n\t\t\t{flow_run && task_run && <hr className=\"mt-4 border-border\" />}\n\n\t\t\t{task_run && <TaskRunSection taskRun={task_run} />}\n\t\t</div>\n\t);\n};\n","import { useMemo } from \"react\";\nimport type { ArtifactWithFlowRunAndTaskRun } from \"@/api/artifacts\";\nimport { ArtifactDetailHeader } from \"./artifact-detail-header\";\nimport { ArtifactDataDisplay } from \"./artifact-raw-data-display\";\nimport { DetailImage } from \"./detail-image\";\nimport { DetailMarkdown } from \"./detail-markdown\";\nimport { DetailProgress } from \"./detail-progress\";\nimport { DetailTable } from \"./detail-table\";\nimport { MetadataSidebar } from \"./metadata-sidebar\";\n\nexport type ArtifactDetailPageProps = {\n\tartifact: ArtifactWithFlowRunAndTaskRun;\n};\n\nexport const ArtifactDetailPage = ({ artifact }: ArtifactDetailPageProps) => {\n\tconst mapArtifactHoc = useMemo(() => {\n\t\tswitch (artifact.type) {\n\t\t\tcase \"markdown\":\n\t\t\tcase \"link\":\n\t\t\t\treturn <DetailMarkdown markdown={artifact.data as string} />;\n\t\t\tcase \"image\":\n\t\t\t\treturn <DetailImage url={artifact.data as string} />;\n\t\t\tcase \"progress\":\n\t\t\t\treturn <DetailProgress progress={artifact.data as number} />;\n\t\t\tcase \"table\":\n\t\t\t\treturn <DetailTable tableData={artifact.data as string} />;\n\t\t\tdefault:\n\t\t\t\treturn <pre>{JSON.stringify(artifact.data, null, 2)}</pre>;\n\t\t}\n\t}, [artifact]);\n\treturn (\n\t\t<div>\n\t\t\t<ArtifactDetailHeader artifact={artifact} />\n\t\t\t<div className=\"flex flex-row gap-4 justify-between\">\n\t\t\t\t<div className=\"flex-grow min-w-0\">\n\t\t\t\t\t{mapArtifactHoc}\n\t\t\t\t\t<ArtifactDataDisplay artifact={artifact} />\n\t\t\t\t</div>\n\t\t\t\t<MetadataSidebar artifact={artifact} />\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import { useSuspenseQuery } from \"@tanstack/react-query\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { buildGetArtifactQuery } from \"@/api/artifacts\";\nimport { useGetArtifactFlowTaskRuns } from \"@/api/artifacts/use-get-artifacts-flow-task-runs/use-get-artifacts-flow-task-runs\";\nimport { ArtifactDetailPage } from \"@/components/artifacts/artifact/artifact-detail-page\";\n\nexport const Route = createFileRoute(\"/artifacts/artifact/$id\")({\n\tcomponent: RouteComponent,\n\tloader: async ({ context, params }) => {\n\t\tconst { id } = params;\n\n\t\tconst artifact = await context.queryClient.ensureQueryData(\n\t\t\tbuildGetArtifactQuery(id),\n\t\t);\n\n\t\treturn { artifact };\n\t},\n});\n\nfunction RouteComponent() {\n\tconst { id } = Route.useParams();\n\n\tconst { data: artifact } = useSuspenseQuery(buildGetArtifactQuery(id));\n\n\tconst artifactWithMetadata = useGetArtifactFlowTaskRuns(id);\n\n\treturn <ArtifactDetailPage artifact={artifactWithMetadata ?? artifact} />;\n}\n"],"names":["ArtifactDetailHeader","artifact","header","jsx","Fragment","Breadcrumb","BreadcrumbList","BreadcrumbItem","BreadcrumbLink","BreadcrumbSeparator","jsxs","DocsLink","Typography","LazyMarkdown","ArtifactDataDisplay","showData","setShowData","useState","toggleShowData","val","editor","useRef","basicSetup","setContainer","useCodeMirror","EditorView","useEffect","handleCopy","_value","toast","Button","node","Icon","DetailImage","url","DetailMarkdown","markdown","DetailProgress","progress","DetailTable","tableData","table","headers","input","setInput","filteredTable","useMemo","row","value","SearchInput","e","Table","TableHeader","TableRow","TableHead","TableBody","TableCell","ArtifactSection","createdDate","formatDate","KeyValue","FlowRunSection","flowRun","startTime","duration","humanizeDuration","updatedDate","tag","TagBadge","LinksSection","flow_run","task_run","Link","TaskRunSection","taskRun","MetadataSidebar","ArtifactDetailPage","mapArtifactHoc","RouteComponent","id","Route","useParams","data","useSuspenseQuery","buildGetArtifactQuery","artifactWithMetadata","useGetArtifactFlowTaskRuns"],"mappings":"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"}
|