prefect 3.7.4.dev4__py3-none-any.whl → 3.7.5.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.
- prefect/_build_info.py +3 -3
- prefect/cli/deploy/_core.py +7 -2
- prefect/client/schemas/schedules.py +28 -7
- prefect/deployments/base.py +27 -0
- prefect/flows.py +5 -1
- prefect/server/AGENTS.md +7 -0
- prefect/server/api/workers.py +59 -3
- prefect/server/events/models/automations.py +34 -1
- prefect/server/events/schemas/lifecycle.py +474 -0
- prefect/server/models/artifacts.py +51 -0
- prefect/server/models/block_documents.py +55 -3
- prefect/server/models/block_types.py +50 -6
- prefect/server/models/concurrency_limits.py +62 -8
- prefect/server/models/concurrency_limits_v2.py +49 -6
- prefect/server/models/events.py +159 -0
- prefect/server/models/flows.py +52 -9
- prefect/server/models/variables.py +54 -11
- prefect/server/models/work_queues.py +42 -4
- prefect/server/models/workers.py +55 -4
- prefect/server/ui-v2/assets/{artifact._id-D_sj2Bai.js → artifact._id-CGn6mN4P.js} +2 -2
- prefect/server/ui-v2/assets/{artifact._id-D_sj2Bai.js.map → artifact._id-CGn6mN4P.js.map} +1 -1
- prefect/server/ui-v2/assets/{artifacts-Ckq-7rKM.js → artifacts-Do1ciXaG.js} +2 -2
- prefect/server/ui-v2/assets/{artifacts-Ckq-7rKM.js.map → artifacts-Do1ciXaG.js.map} +1 -1
- prefect/server/ui-v2/assets/{automation-wizard-DK_oIkuy.js → automation-wizard-CEKw1mSo.js} +2 -2
- prefect/server/ui-v2/assets/{automation-wizard-DK_oIkuy.js.map → automation-wizard-CEKw1mSo.js.map} +1 -1
- prefect/server/ui-v2/assets/{automation._id-DHPfuZoy.js → automation._id-DWGZbeYH.js} +2 -2
- prefect/server/ui-v2/assets/{automation._id-DHPfuZoy.js.map → automation._id-DWGZbeYH.js.map} +1 -1
- prefect/server/ui-v2/assets/{automation_._id.edit-DhzmIbRy.js → automation_._id.edit-HRV19VwZ.js} +2 -2
- prefect/server/ui-v2/assets/{automation_._id.edit-DhzmIbRy.js.map → automation_._id.edit-HRV19VwZ.js.map} +1 -1
- prefect/server/ui-v2/assets/{automations-18EVeC4g.js → automations-9tGVzn7H.js} +2 -2
- prefect/server/ui-v2/assets/{automations-18EVeC4g.js.map → automations-9tGVzn7H.js.map} +1 -1
- prefect/server/ui-v2/assets/{automations-OjniTeHI.js → automations-BeIPMhoH.js} +2 -2
- prefect/server/ui-v2/assets/{automations-OjniTeHI.js.map → automations-BeIPMhoH.js.map} +1 -1
- prefect/server/ui-v2/assets/{automations-header-WqOJ9BHA.js → automations-header-CV6NSb4r.js} +2 -2
- prefect/server/ui-v2/assets/{automations-header-WqOJ9BHA.js.map → automations-header-CV6NSb4r.js.map} +1 -1
- prefect/server/ui-v2/assets/{automations-wizard-DLsg6Q9Q.js → automations-wizard-XwyXNcrj.js} +2 -2
- prefect/server/ui-v2/assets/{automations-wizard-DLsg6Q9Q.js.map → automations-wizard-XwyXNcrj.js.map} +1 -1
- prefect/server/ui-v2/assets/{base-job-template-form-section-B_vYchzo.js → base-job-template-form-section-DMs875TU.js} +2 -2
- prefect/server/ui-v2/assets/{base-job-template-form-section-B_vYchzo.js.map → base-job-template-form-section-DMs875TU.js.map} +1 -1
- prefect/server/ui-v2/assets/{block-type-details-CQJNLWUB.js → block-type-details-BcDSzzxg.js} +2 -2
- prefect/server/ui-v2/assets/{block-type-details-CQJNLWUB.js.map → block-type-details-BcDSzzxg.js.map} +1 -1
- prefect/server/ui-v2/assets/{block._id-DLIoJk29.js → block._id-71pTiwRc.js} +2 -2
- prefect/server/ui-v2/assets/{block._id-DLIoJk29.js.map → block._id-71pTiwRc.js.map} +1 -1
- prefect/server/ui-v2/assets/{block_._id.edit-DP7dd7Wq.js → block_._id.edit-CQCrJtwK.js} +2 -2
- prefect/server/ui-v2/assets/{block_._id.edit-DP7dd7Wq.js.map → block_._id.edit-CQCrJtwK.js.map} +1 -1
- prefect/server/ui-v2/assets/{blocks-DA5cj_oB.js → blocks-BO6kd_nW.js} +2 -2
- prefect/server/ui-v2/assets/{blocks-DA5cj_oB.js.map → blocks-BO6kd_nW.js.map} +1 -1
- prefect/server/ui-v2/assets/{catalog-0qes6pkx.js → catalog-CAWqoAr-.js} +2 -2
- prefect/server/ui-v2/assets/{catalog-0qes6pkx.js.map → catalog-CAWqoAr-.js.map} +1 -1
- prefect/server/ui-v2/assets/{catalog_._slug-DrGBCMOe.js → catalog_._slug-BFPfOSRG.js} +2 -2
- prefect/server/ui-v2/assets/{catalog_._slug-DrGBCMOe.js.map → catalog_._slug-BFPfOSRG.js.map} +1 -1
- prefect/server/ui-v2/assets/{catalog_._slug_.create-QphOkjVD.js → catalog_._slug_.create-Zmb9Qc_k.js} +2 -2
- prefect/server/ui-v2/assets/{catalog_._slug_.create-QphOkjVD.js.map → catalog_._slug_.create-Zmb9Qc_k.js.map} +1 -1
- prefect/server/ui-v2/assets/{concurrency-limit._id-CASCpu3g.js → concurrency-limit._id-BkcUCp2C.js} +2 -2
- prefect/server/ui-v2/assets/{concurrency-limit._id-CASCpu3g.js.map → concurrency-limit._id-BkcUCp2C.js.map} +1 -1
- prefect/server/ui-v2/assets/{concurrency-limits-D5CSgwVA.js → concurrency-limits-CenLAieY.js} +2 -2
- prefect/server/ui-v2/assets/{concurrency-limits-D5CSgwVA.js.map → concurrency-limits-CenLAieY.js.map} +1 -1
- prefect/server/ui-v2/assets/{create--i1MDKBO.js → create-B9a1kbgD.js} +2 -2
- prefect/server/ui-v2/assets/{create--i1MDKBO.js.map → create-B9a1kbgD.js.map} +1 -1
- prefect/server/ui-v2/assets/{create-D4Mgq9Tc.js → create-CW_W7MJG.js} +2 -2
- prefect/server/ui-v2/assets/{create-D4Mgq9Tc.js.map → create-CW_W7MJG.js.map} +1 -1
- prefect/server/ui-v2/assets/{data-table-D_g1sVhO.js → data-table-CwWzYblB.js} +2 -2
- prefect/server/ui-v2/assets/{data-table-D_g1sVhO.js.map → data-table-CwWzYblB.js.map} +1 -1
- prefect/server/ui-v2/assets/{data-table-CPTOcoHk.js → data-table-UtREbgzl.js} +2 -2
- prefect/server/ui-v2/assets/{data-table-CPTOcoHk.js.map → data-table-UtREbgzl.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment-form-B3bk-cgB.js → deployment-form-b8Uy0wZi.js} +2 -2
- prefect/server/ui-v2/assets/{deployment-form-B3bk-cgB.js.map → deployment-form-b8Uy0wZi.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment-links-BPfEnrnX.js → deployment-links-D_m7WPrI.js} +2 -2
- prefect/server/ui-v2/assets/{deployment-links-BPfEnrnX.js.map → deployment-links-D_m7WPrI.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment._id-1LR1kAs9.js → deployment._id-VeI6NfbO.js} +2 -2
- prefect/server/ui-v2/assets/{deployment._id-1LR1kAs9.js.map → deployment._id-VeI6NfbO.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment_._id.duplicate-BqeoxpSJ.js → deployment_._id.duplicate-BdBlS5Hk.js} +2 -2
- prefect/server/ui-v2/assets/{deployment_._id.duplicate-BqeoxpSJ.js.map → deployment_._id.duplicate-BdBlS5Hk.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment_._id.edit-CphaQ1Q-.js → deployment_._id.edit-C1G5Wlhz.js} +2 -2
- prefect/server/ui-v2/assets/{deployment_._id.edit-CphaQ1Q-.js.map → deployment_._id.edit-C1G5Wlhz.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment_._id.run-DJgb6uhH.js → deployment_._id.run-CMco3t02.js} +2 -2
- prefect/server/ui-v2/assets/{deployment_._id.run-DJgb6uhH.js.map → deployment_._id.run-CMco3t02.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployments-KARnGMSo.js → deployments-Cw4bUdZz.js} +2 -2
- prefect/server/ui-v2/assets/{deployments-KARnGMSo.js.map → deployments-Cw4bUdZz.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployments-xDRq6pwu.js → deployments-TsvJSdjL.js} +2 -2
- prefect/server/ui-v2/assets/{deployments-xDRq6pwu.js.map → deployments-TsvJSdjL.js.map} +1 -1
- prefect/server/ui-v2/assets/{event-resource-display-Cpa7n5Gi.js → event-resource-display-VOk6tXTt.js} +2 -2
- prefect/server/ui-v2/assets/{event-resource-display-Cpa7n5Gi.js.map → event-resource-display-VOk6tXTt.js.map} +1 -1
- prefect/server/ui-v2/assets/{event._eventDate._eventId-DEOpiwP4.js → event._eventDate._eventId-BZTy7e1G.js} +2 -2
- prefect/server/ui-v2/assets/{event._eventDate._eventId-DEOpiwP4.js.map → event._eventDate._eventId-BZTy7e1G.js.map} +1 -1
- prefect/server/ui-v2/assets/{events-B419Nv8p.js → events-C3fd4JK8.js} +2 -2
- prefect/server/ui-v2/assets/{events-B419Nv8p.js.map → events-C3fd4JK8.js.map} +1 -1
- prefect/server/ui-v2/assets/{events-timeline-BqHjvYQo.js → events-timeline-DMEKqiaJ.js} +2 -2
- prefect/server/ui-v2/assets/{events-timeline-BqHjvYQo.js.map → events-timeline-DMEKqiaJ.js.map} +1 -1
- prefect/server/ui-v2/assets/{flow-run-graph-B9WKwHgt.js → flow-run-graph-CzgTV1Fm.js} +2 -2
- prefect/server/ui-v2/assets/{flow-run-graph-B9WKwHgt.js.map → flow-run-graph-CzgTV1Fm.js.map} +1 -1
- prefect/server/ui-v2/assets/{flow-run._id-C-H9_3kK.js → flow-run._id-BO7lgrUy.js} +2 -2
- prefect/server/ui-v2/assets/{flow-run._id-C-H9_3kK.js.map → flow-run._id-BO7lgrUy.js.map} +1 -1
- prefect/server/ui-v2/assets/{flow-run._id-B-Nq67aN.js → flow-run._id-Bw2S7_Ra.js} +3 -3
- prefect/server/ui-v2/assets/{flow-run._id-B-Nq67aN.js.map → flow-run._id-Bw2S7_Ra.js.map} +1 -1
- prefect/server/ui-v2/assets/{flow._id-BcIuffAZ.js → flow._id-CYUIt-ri.js} +2 -2
- prefect/server/ui-v2/assets/{flow._id-BcIuffAZ.js.map → flow._id-CYUIt-ri.js.map} +1 -1
- prefect/server/ui-v2/assets/{flow._id-BQ9hMaOc.js → flow._id-D0AM7DlY.js} +2 -2
- prefect/server/ui-v2/assets/{flow._id-BQ9hMaOc.js.map → flow._id-D0AM7DlY.js.map} +1 -1
- prefect/server/ui-v2/assets/{flows-CdREF3X8.js → flows-DQ2n-Pk-.js} +2 -2
- prefect/server/ui-v2/assets/{flows-CdREF3X8.js.map → flows-DQ2n-Pk-.js.map} +1 -1
- prefect/server/ui-v2/assets/{header-DcHk9RJB.js → header-B4ptMDx7.js} +2 -2
- prefect/server/ui-v2/assets/{header-DcHk9RJB.js.map → header-B4ptMDx7.js.map} +1 -1
- prefect/server/ui-v2/assets/{header-DcteQO4w.js → header-DJLajBCT.js} +2 -2
- prefect/server/ui-v2/assets/{header-DcteQO4w.js.map → header-DJLajBCT.js.map} +1 -1
- prefect/server/ui-v2/assets/{header-rP3ESS84.js → header-D_rfPmc4.js} +2 -2
- prefect/server/ui-v2/assets/{header-rP3ESS84.js.map → header-D_rfPmc4.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-Bx8t2aUw.js → index-1m3WFD_G.js} +4 -4
- prefect/server/ui-v2/assets/index-1m3WFD_G.js.map +1 -0
- prefect/server/ui-v2/assets/{json-input-DBfGBkOn.js → json-input-BvUPoDaQ.js} +2 -2
- prefect/server/ui-v2/assets/{json-input-DBfGBkOn.js.map → json-input-BvUPoDaQ.js.map} +1 -1
- prefect/server/ui-v2/assets/{key._key-BxFZCzla.js → key._key-tyBiTQht.js} +2 -2
- prefect/server/ui-v2/assets/{key._key-BxFZCzla.js.map → key._key-tyBiTQht.js.map} +1 -1
- prefect/server/ui-v2/assets/{lazy-markdown-Du0WEaoD.js → lazy-markdown-DFiPnlm6.js} +2 -2
- prefect/server/ui-v2/assets/{lazy-markdown-Du0WEaoD.js.map → lazy-markdown-DFiPnlm6.js.map} +1 -1
- prefect/server/ui-v2/assets/login-azcClxzD.js +2 -0
- prefect/server/ui-v2/assets/login-azcClxzD.js.map +1 -0
- prefect/server/ui-v2/assets/{runs-2BGJtY7A.js → runs-BXhNHojM.js} +2 -2
- prefect/server/ui-v2/assets/{runs-2BGJtY7A.js.map → runs-BXhNHojM.js.map} +1 -1
- prefect/server/ui-v2/assets/{runs-DtVmvXjn.js → runs-Bi8xBTnP.js} +2 -2
- prefect/server/ui-v2/assets/{runs-DtVmvXjn.js.map → runs-Bi8xBTnP.js.map} +1 -1
- prefect/server/ui-v2/assets/{schedule-badge-vp3vRuiQ.js → schedule-badge-DyA6_9bW.js} +2 -2
- prefect/server/ui-v2/assets/{schedule-badge-vp3vRuiQ.js.map → schedule-badge-DyA6_9bW.js.map} +1 -1
- prefect/server/ui-v2/assets/{schema-form-B63OZdZA.js → schema-form-BbUYdQ1l.js} +2 -2
- prefect/server/ui-v2/assets/{schema-form-B63OZdZA.js.map → schema-form-BbUYdQ1l.js.map} +1 -1
- prefect/server/ui-v2/assets/{settings-CAfOkKsQ.js → settings-D0cOV1Wh.js} +2 -2
- prefect/server/ui-v2/assets/{settings-CAfOkKsQ.js.map → settings-D0cOV1Wh.js.map} +1 -1
- prefect/server/ui-v2/assets/{task-run-concurrency-limits-reset-dialog-DoT8gKqg.js → task-run-concurrency-limits-reset-dialog-BGyNodD6.js} +2 -2
- prefect/server/ui-v2/assets/{task-run-concurrency-limits-reset-dialog-DoT8gKqg.js.map → task-run-concurrency-limits-reset-dialog-BGyNodD6.js.map} +1 -1
- prefect/server/ui-v2/assets/{task-run._id-ByHXEkPr.js → task-run._id-BzgIQuAB.js} +2 -2
- prefect/server/ui-v2/assets/{task-run._id-ByHXEkPr.js.map → task-run._id-BzgIQuAB.js.map} +1 -1
- prefect/server/ui-v2/assets/{timezone-select-BbC7_ofj.js → timezone-select-YUKrhekj.js} +2 -2
- prefect/server/ui-v2/assets/{timezone-select-BbC7_ofj.js.map → timezone-select-YUKrhekj.js.map} +1 -1
- prefect/server/ui-v2/assets/{toggle-group-3mnMEnd4.js → toggle-group-DtF-kiye.js} +2 -2
- prefect/server/ui-v2/assets/{toggle-group-3mnMEnd4.js.map → toggle-group-DtF-kiye.js.map} +1 -1
- prefect/server/ui-v2/assets/{trigger-details-CXPHSuD6.js → trigger-details-DKXLeut_.js} +2 -2
- prefect/server/ui-v2/assets/{trigger-details-CXPHSuD6.js.map → trigger-details-DKXLeut_.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-delete-automation-confirmation-dialog-DoqZBI87.js → use-delete-automation-confirmation-dialog-rWsqU6dD.js} +2 -2
- prefect/server/ui-v2/assets/{use-delete-automation-confirmation-dialog-DoqZBI87.js.map → use-delete-automation-confirmation-dialog-rWsqU6dD.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-delete-block-document-confirmation-dialog-OksMPjKJ.js → use-delete-block-document-confirmation-dialog-CxykKCvn.js} +2 -2
- prefect/server/ui-v2/assets/{use-delete-block-document-confirmation-dialog-OksMPjKJ.js.map → use-delete-block-document-confirmation-dialog-CxykKCvn.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-delete-deployment-confirmation-dialog-QUJxKWuu.js → use-delete-deployment-confirmation-dialog-BVLOKC3S.js} +2 -2
- prefect/server/ui-v2/assets/{use-delete-deployment-confirmation-dialog-QUJxKWuu.js.map → use-delete-deployment-confirmation-dialog-BVLOKC3S.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-get-artifacts-flow-task-runs-BrI5eJXx.js → use-get-artifacts-flow-task-runs-DYXKmjMZ.js} +2 -2
- prefect/server/ui-v2/assets/{use-get-artifacts-flow-task-runs-BrI5eJXx.js.map → use-get-artifacts-flow-task-runs-DYXKmjMZ.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-resource-options-C8BxAJ3_.js → use-resource-options-CI-_-q8G.js} +2 -2
- prefect/server/ui-v2/assets/{use-resource-options-C8BxAJ3_.js.map → use-resource-options-CI-_-q8G.js.map} +1 -1
- prefect/server/ui-v2/assets/{variables-J400NeB8.js → variables-DzF6dWfi.js} +2 -2
- prefect/server/ui-v2/assets/{variables-J400NeB8.js.map → variables-DzF6dWfi.js.map} +1 -1
- prefect/server/ui-v2/assets/{variables-B_xPJctQ.js → variables-YgoHBKH3.js} +2 -2
- prefect/server/ui-v2/assets/{variables-B_xPJctQ.js.map → variables-YgoHBKH3.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pool-queue-form-zjSDZgJw.js → work-pool-queue-form-DwUMMWWg.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool-queue-form-zjSDZgJw.js.map → work-pool-queue-form-DwUMMWWg.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pool-queue-toggle-D9yejO8R.js → work-pool-queue-toggle-DxntiOMF.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool-queue-toggle-D9yejO8R.js.map → work-pool-queue-toggle-DxntiOMF.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pool._workPoolName-B7GY71Om.js → work-pool._workPoolName-DFsnzX7t.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool._workPoolName-B7GY71Om.js.map → work-pool._workPoolName-DFsnzX7t.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.edit-BI2_05Fv.js → work-pool_._workPoolName.edit-BXgOVNvH.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.edit-BI2_05Fv.js.map → work-pool_._workPoolName.edit-BXgOVNvH.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.queue._workQueueName-DLPPStC4.js → work-pool_._workPoolName.queue._workQueueName-9m0TaeoJ.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.queue._workQueueName-DLPPStC4.js.map → work-pool_._workPoolName.queue._workQueueName-9m0TaeoJ.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.queue.create-BDfrNViS.js → work-pool_._workPoolName.queue.create-Bue87lwm.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.queue.create-BDfrNViS.js.map → work-pool_._workPoolName.queue.create-Bue87lwm.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.queue_._workQueueName.edit-IkPJodEj.js → work-pool_._workPoolName.queue_._workQueueName.edit-BRRcpUcG.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.queue_._workQueueName.edit-IkPJodEj.js.map → work-pool_._workPoolName.queue_._workQueueName.edit-BRRcpUcG.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pools-h0aBSwR4.js → work-pools-BTYKiBdv.js} +2 -2
- prefect/server/ui-v2/assets/{work-pools-h0aBSwR4.js.map → work-pools-BTYKiBdv.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pools-C8fZNspQ.js → work-pools-DmqxpFl6.js} +2 -2
- prefect/server/ui-v2/assets/{work-pools-C8fZNspQ.js.map → work-pools-DmqxpFl6.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-queue-icon-text-DkodkzYl.js → work-queue-icon-text-BVl4_3HI.js} +2 -2
- prefect/server/ui-v2/assets/{work-queue-icon-text-DkodkzYl.js.map → work-queue-icon-text-BVl4_3HI.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-queue-select-DfK_LqtB.js → work-queue-select-qFUs-bnS.js} +2 -2
- prefect/server/ui-v2/assets/{work-queue-select-DfK_LqtB.js.map → work-queue-select-qFUs-bnS.js.map} +1 -1
- prefect/server/ui-v2/index.html +1 -1
- prefect/server/utilities/worker_channel.py +369 -20
- prefect/server/utilities/worker_channel_cleanup.py +451 -0
- {prefect-3.7.4.dev4.dist-info → prefect-3.7.5.dev2.dist-info}/METADATA +1 -1
- {prefect-3.7.4.dev4.dist-info → prefect-3.7.5.dev2.dist-info}/RECORD +181 -179
- prefect/server/ui-v2/assets/index-Bx8t2aUw.js.map +0 -1
- prefect/server/ui-v2/assets/login-D2Aziy0o.js +0 -2
- prefect/server/ui-v2/assets/login-D2Aziy0o.js.map +0 -1
- {prefect-3.7.4.dev4.dist-info → prefect-3.7.5.dev2.dist-info}/WHEEL +0 -0
- {prefect-3.7.4.dev4.dist-info → prefect-3.7.5.dev2.dist-info}/entry_points.txt +0 -0
- {prefect-3.7.4.dev4.dist-info → prefect-3.7.5.dev2.dist-info}/licenses/LICENSE +0 -0
prefect/_build_info.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Generated by versioningit
|
|
2
|
-
__version__ = "3.7.
|
|
3
|
-
__build_date__ = "2026-06-
|
|
4
|
-
__git_commit__ = "
|
|
2
|
+
__version__ = "3.7.5.dev2"
|
|
3
|
+
__build_date__ = "2026-06-09 09:17:59.185976+00:00"
|
|
4
|
+
__git_commit__ = "d858cb6725864c9a993be6a6633009b03b5e6f5e"
|
|
5
5
|
__dirty__ = False
|
prefect/cli/deploy/_core.py
CHANGED
|
@@ -19,7 +19,10 @@ from prefect.cli._prompts import (
|
|
|
19
19
|
)
|
|
20
20
|
from prefect.client.orchestration import get_client
|
|
21
21
|
from prefect.client.schemas.filters import WorkerFilter
|
|
22
|
-
from prefect.deployments.base import
|
|
22
|
+
from prefect.deployments.base import (
|
|
23
|
+
_deployment_already_saved_to_prefect_file,
|
|
24
|
+
_save_deployment_to_prefect_file,
|
|
25
|
+
)
|
|
23
26
|
from prefect.deployments.runner import RunnerDeployment
|
|
24
27
|
from prefect.deployments.steps.core import run_steps
|
|
25
28
|
from prefect.exceptions import ObjectNotFound
|
|
@@ -420,7 +423,9 @@ async def _run_single_deploy(
|
|
|
420
423
|
)
|
|
421
424
|
console.print(message, soft_wrap=True)
|
|
422
425
|
|
|
423
|
-
if is_interactive() and not
|
|
426
|
+
if is_interactive() and not _deployment_already_saved_to_prefect_file(
|
|
427
|
+
deploy_config_before_templating, prefect_file
|
|
428
|
+
):
|
|
424
429
|
if confirm(
|
|
425
430
|
(
|
|
426
431
|
"Would you like to save configuration for this deployment for faster"
|
|
@@ -26,6 +26,26 @@ MAX_ITERATIONS = 1000
|
|
|
26
26
|
MAX_RRULE_LENGTH = 6500
|
|
27
27
|
|
|
28
28
|
|
|
29
|
+
def _iana_timezone_name(tzinfo: datetime.tzinfo) -> str:
|
|
30
|
+
"""Return a valid IANA timezone name for *tzinfo*, or `"UTC"`."""
|
|
31
|
+
for attr in ("key", "name"):
|
|
32
|
+
value: Optional[str] = getattr(tzinfo, attr, None)
|
|
33
|
+
if value and is_valid_timezone(value):
|
|
34
|
+
return value
|
|
35
|
+
|
|
36
|
+
filename: Optional[str] = getattr(tzinfo, "_filename", None)
|
|
37
|
+
if filename:
|
|
38
|
+
normalized = filename.replace("\\", "/")
|
|
39
|
+
marker = "/zoneinfo/"
|
|
40
|
+
idx = normalized.find(marker)
|
|
41
|
+
if idx != -1:
|
|
42
|
+
candidate = normalized[idx + len(marker) :]
|
|
43
|
+
if candidate and is_valid_timezone(candidate):
|
|
44
|
+
return candidate
|
|
45
|
+
|
|
46
|
+
return "UTC"
|
|
47
|
+
|
|
48
|
+
|
|
29
49
|
def is_valid_timezone(v: str) -> bool:
|
|
30
50
|
"""
|
|
31
51
|
Validate that the provided timezone is a valid IANA timezone.
|
|
@@ -204,26 +224,27 @@ class RRuleSchedule(PrefectBaseModel):
|
|
|
204
224
|
if isinstance(rrule, dateutil.rrule.rrule):
|
|
205
225
|
dtstart = _rrule_dt(rrule)
|
|
206
226
|
if dtstart and dtstart.tzinfo is not None:
|
|
207
|
-
timezone = dtstart.tzinfo
|
|
227
|
+
timezone = _iana_timezone_name(dtstart.tzinfo)
|
|
208
228
|
else:
|
|
209
229
|
timezone = "UTC"
|
|
210
230
|
return RRuleSchedule(rrule=str(rrule), timezone=timezone)
|
|
211
231
|
rrules = _rrule(rrule)
|
|
212
232
|
dtstarts = [dts for rr in rrules if (dts := _rrule_dt(rr)) is not None]
|
|
213
233
|
unique_dstarts = set(d.astimezone(ZoneInfo("UTC")) for d in dtstarts)
|
|
214
|
-
|
|
234
|
+
unique_tz_names = set(
|
|
235
|
+
_iana_timezone_name(d.tzinfo) for d in dtstarts if d.tzinfo is not None
|
|
236
|
+
)
|
|
215
237
|
|
|
216
|
-
if len(
|
|
238
|
+
if len(unique_tz_names) > 1:
|
|
217
239
|
raise ValueError(
|
|
218
|
-
f"rruleset has too many dtstart timezones: {
|
|
240
|
+
f"rruleset has too many dtstart timezones: {unique_tz_names}"
|
|
219
241
|
)
|
|
220
242
|
|
|
221
243
|
if len(unique_dstarts) > 1:
|
|
222
244
|
raise ValueError(f"rruleset has too many dtstarts: {unique_dstarts}")
|
|
223
245
|
|
|
224
|
-
if unique_dstarts and
|
|
225
|
-
[
|
|
226
|
-
timezone = unique_tz.tzname(dtstarts[0])
|
|
246
|
+
if unique_dstarts and unique_tz_names:
|
|
247
|
+
[timezone] = unique_tz_names
|
|
227
248
|
else:
|
|
228
249
|
timezone = "UTC"
|
|
229
250
|
|
prefect/deployments/base.py
CHANGED
|
@@ -278,6 +278,33 @@ def _interval_schedule_to_dict(schedule: IntervalSchedule) -> dict[str, Any]:
|
|
|
278
278
|
return schedule_config
|
|
279
279
|
|
|
280
280
|
|
|
281
|
+
def _deployment_already_saved_to_prefect_file(
|
|
282
|
+
deployment: dict[str, Any],
|
|
283
|
+
prefect_file: Path = Path("prefect.yaml"),
|
|
284
|
+
) -> bool:
|
|
285
|
+
"""
|
|
286
|
+
Return True if `prefect.yaml` already contains a deployment entry matching the
|
|
287
|
+
given deployment's name and entrypoint.
|
|
288
|
+
|
|
289
|
+
Used to decide whether the interactive `prefect deploy` flow should offer to
|
|
290
|
+
persist a newly-created deployment: a deployment that is already declared in
|
|
291
|
+
the file does not need to be saved again, but a brand-new one (even when the
|
|
292
|
+
file otherwise exists) should still be offered up for saving.
|
|
293
|
+
"""
|
|
294
|
+
if not prefect_file.exists():
|
|
295
|
+
return False
|
|
296
|
+
|
|
297
|
+
with prefect_file.open(mode="r") as f:
|
|
298
|
+
contents = yaml.safe_load(f) or {}
|
|
299
|
+
|
|
300
|
+
for existing in contents.get("deployments") or []:
|
|
301
|
+
if existing.get("name") == deployment.get("name") and existing.get(
|
|
302
|
+
"entrypoint"
|
|
303
|
+
) == deployment.get("entrypoint"):
|
|
304
|
+
return True
|
|
305
|
+
return False
|
|
306
|
+
|
|
307
|
+
|
|
281
308
|
def _save_deployment_to_prefect_file(
|
|
282
309
|
deployment: dict[str, Any],
|
|
283
310
|
build_steps: list[dict[str, Any]] | None = None,
|
prefect/flows.py
CHANGED
|
@@ -706,7 +706,11 @@ class Flow(Generic[P, R]):
|
|
|
706
706
|
from fastapi.encoders import jsonable_encoder
|
|
707
707
|
|
|
708
708
|
serialized_parameters[key] = jsonable_encoder(value)
|
|
709
|
-
except (TypeError, ValueError):
|
|
709
|
+
except (TypeError, ValueError, RecursionError):
|
|
710
|
+
# `jsonable_encoder` recurses into unknown objects with no cycle
|
|
711
|
+
# or depth limit, so a deeply-nested or self-referential value
|
|
712
|
+
# raises `RecursionError`. Treat it like any other unserializable
|
|
713
|
+
# value and fall back to the placeholder below.
|
|
710
714
|
logger.debug(
|
|
711
715
|
f"Parameter {key!r} for flow {self.name!r} is unserializable. "
|
|
712
716
|
f"Type {type(value).__name__!r} and will not be stored "
|
prefect/server/AGENTS.md
CHANGED
|
@@ -24,6 +24,13 @@ The `variables` endpoints are a good canonical example of this pattern for simpl
|
|
|
24
24
|
|
|
25
25
|
**Singleton server settings** (not tied to a specific run or resource) skip a dedicated table — store them as JSON in the `Configuration` key-value store via `models/configuration.py`. Define a string key constant in the wrapping module (see `models/storage_defaults.py` for the pattern).
|
|
26
26
|
|
|
27
|
+
## Object Lifecycle Events
|
|
28
|
+
|
|
29
|
+
Domain objects emit `prefect.<object>.{created,updated,deleted}` events from their `models/` CRUD functions (`models/variables.py` is the simplest example). Two non-obvious rules:
|
|
30
|
+
|
|
31
|
+
- **Builders live in `events/schemas/lifecycle.py`, not `models/events.py`.** `models/events.py` imports `models.deployments`, so a model imported early in `models/__init__` (e.g. `block_types`, `block_documents`) that imports a builder from there triggers a circular import. The builders in `lifecycle.py` are pure functions of an ORM object + timestamp with no model-layer imports, so any model can use them safely.
|
|
32
|
+
- **Emission is inline and pre-commit.** `emit_*` helpers reference `clients.PrefectServerEventsClient` as a module attribute (so the autouse test fixture's single patch on `events.clients.PrefectServerEventsClient` captures them) and publish within the request transaction — there is no request-scoped buffer, so a rolled-back create still emits.
|
|
33
|
+
|
|
27
34
|
## Database Migrations
|
|
28
35
|
|
|
29
36
|
Migrations use Alembic via wrapper functions in `database/alembic_commands.py`:
|
prefect/server/api/workers.py
CHANGED
|
@@ -25,8 +25,10 @@ import prefect.server.models as models
|
|
|
25
25
|
import prefect.server.schemas as schemas
|
|
26
26
|
from prefect._internal.uuid7 import uuid7
|
|
27
27
|
from prefect.client.schemas.worker_channel import (
|
|
28
|
+
CLEANUP_DELIVERY_CAPABILITY,
|
|
28
29
|
WORK_POOL_SNAPSHOT_CAPABILITY,
|
|
29
30
|
WORKER_HEARTBEAT_CAPABILITY,
|
|
31
|
+
WorkerChannelCapability,
|
|
30
32
|
WorkerChannelCloseReason,
|
|
31
33
|
WorkerChannelProtocolError,
|
|
32
34
|
WorkerHelloFrame,
|
|
@@ -48,6 +50,10 @@ from prefect.server.schemas.statuses import WorkQueueStatus
|
|
|
48
50
|
from prefect.server.utilities import subscriptions
|
|
49
51
|
from prefect.server.utilities import worker_channel as worker_channel_utils
|
|
50
52
|
from prefect.server.utilities.server import PrefectRouter
|
|
53
|
+
from prefect.server.worker_communication.cleanup_queue import (
|
|
54
|
+
WorkerCleanupQueue,
|
|
55
|
+
get_worker_cleanup_queue,
|
|
56
|
+
)
|
|
51
57
|
from prefect.types import DateTime
|
|
52
58
|
from prefect.types._datetime import now
|
|
53
59
|
|
|
@@ -61,7 +67,7 @@ router: PrefectRouter = PrefectRouter(
|
|
|
61
67
|
)
|
|
62
68
|
logger: Logger = get_logger("prefect.server.api.workers")
|
|
63
69
|
|
|
64
|
-
|
|
70
|
+
_OSS_WORKER_CHANNEL_REQUIRED_CAPABILITIES: list[WorkerChannelCapability] = [
|
|
65
71
|
WORKER_HEARTBEAT_CAPABILITY,
|
|
66
72
|
WORK_POOL_SNAPSHOT_CAPABILITY,
|
|
67
73
|
]
|
|
@@ -183,6 +189,26 @@ class WorkerChannelWorkPoolUpdateEvent:
|
|
|
183
189
|
changed_fields: dict[str, dict[str, Any]]
|
|
184
190
|
|
|
185
191
|
|
|
192
|
+
def _worker_requested_cleanup_delivery(hello: WorkerHelloFrame) -> bool:
|
|
193
|
+
return (
|
|
194
|
+
CLEANUP_DELIVERY_CAPABILITY in hello.payload.requested_capabilities
|
|
195
|
+
and bool(hello.payload.handled_cleanup_kinds)
|
|
196
|
+
and hello.payload.max_cleanup_concurrency > 0
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def _accepted_worker_channel_capabilities(
|
|
201
|
+
hello: WorkerHelloFrame,
|
|
202
|
+
*,
|
|
203
|
+
cleanup_queue_available: bool,
|
|
204
|
+
) -> list[WorkerChannelCapability]:
|
|
205
|
+
accepted = list(_OSS_WORKER_CHANNEL_REQUIRED_CAPABILITIES)
|
|
206
|
+
if cleanup_queue_available and _worker_requested_cleanup_delivery(hello):
|
|
207
|
+
accepted.append(CLEANUP_DELIVERY_CAPABILITY)
|
|
208
|
+
|
|
209
|
+
return accepted
|
|
210
|
+
|
|
211
|
+
|
|
186
212
|
async def _receive_worker_hello(websocket: WebSocket) -> WorkerHelloFrame:
|
|
187
213
|
try:
|
|
188
214
|
message = await websocket.receive_json()
|
|
@@ -290,6 +316,7 @@ async def _build_worker_ready_frame(
|
|
|
290
316
|
session: AsyncSession,
|
|
291
317
|
work_pool_name: str,
|
|
292
318
|
hello: WorkerHelloFrame,
|
|
319
|
+
cleanup_queue_available: bool,
|
|
293
320
|
) -> tuple[WorkerReadyFrame, WorkerChannelWorkPoolUpdateEvent | None]:
|
|
294
321
|
try:
|
|
295
322
|
selected_channel_version = select_worker_channel_version(
|
|
@@ -371,7 +398,10 @@ async def _build_worker_ready_frame(
|
|
|
371
398
|
)
|
|
372
399
|
|
|
373
400
|
requested_capabilities = list(dict.fromkeys(hello.payload.requested_capabilities))
|
|
374
|
-
accepted =
|
|
401
|
+
accepted = _accepted_worker_channel_capabilities(
|
|
402
|
+
hello,
|
|
403
|
+
cleanup_queue_available=cleanup_queue_available,
|
|
404
|
+
)
|
|
375
405
|
accepted_set = set(accepted)
|
|
376
406
|
rejected = [
|
|
377
407
|
capability
|
|
@@ -393,7 +423,11 @@ async def _build_worker_ready_frame(
|
|
|
393
423
|
),
|
|
394
424
|
"accepted_capabilities": accepted,
|
|
395
425
|
"rejected_capabilities": rejected,
|
|
396
|
-
"effective_max_cleanup_concurrency":
|
|
426
|
+
"effective_max_cleanup_concurrency": (
|
|
427
|
+
hello.payload.max_cleanup_concurrency
|
|
428
|
+
if CLEANUP_DELIVERY_CAPABILITY in accepted_set
|
|
429
|
+
else 0
|
|
430
|
+
),
|
|
397
431
|
"resolved_work_queues": [
|
|
398
432
|
{"id": work_queue.id, "name": work_queue.name}
|
|
399
433
|
for work_queue in work_queues
|
|
@@ -1058,6 +1092,16 @@ async def worker_channel_connect(
|
|
|
1058
1092
|
|
|
1059
1093
|
try:
|
|
1060
1094
|
hello = await _receive_worker_hello(websocket)
|
|
1095
|
+
cleanup_queue: WorkerCleanupQueue | None = None
|
|
1096
|
+
if _worker_requested_cleanup_delivery(hello):
|
|
1097
|
+
try:
|
|
1098
|
+
cleanup_queue = get_worker_cleanup_queue()
|
|
1099
|
+
except Exception:
|
|
1100
|
+
logger.exception(
|
|
1101
|
+
"Worker cleanup delivery queue initialization failed; "
|
|
1102
|
+
"rejecting cleanup delivery capability"
|
|
1103
|
+
)
|
|
1104
|
+
|
|
1061
1105
|
async with worker_channel_utils.messaging.ephemeral_subscription(
|
|
1062
1106
|
worker_channel_utils.WORKER_CHANNEL_SNAPSHOT_TOPIC,
|
|
1063
1107
|
) as consumer_kwargs:
|
|
@@ -1066,6 +1110,7 @@ async def worker_channel_connect(
|
|
|
1066
1110
|
session=session,
|
|
1067
1111
|
work_pool_name=work_pool_name,
|
|
1068
1112
|
hello=hello,
|
|
1113
|
+
cleanup_queue_available=cleanup_queue is not None,
|
|
1069
1114
|
)
|
|
1070
1115
|
|
|
1071
1116
|
if work_pool_update_event is not None:
|
|
@@ -1094,6 +1139,17 @@ async def worker_channel_connect(
|
|
|
1094
1139
|
work_pool_id=ready.payload.initial_snapshot.work_pool.id,
|
|
1095
1140
|
consumer_id=hello.payload.consumer_id,
|
|
1096
1141
|
worker_name=hello.payload.worker_name,
|
|
1142
|
+
cleanup_queue=(
|
|
1143
|
+
cleanup_queue
|
|
1144
|
+
if CLEANUP_DELIVERY_CAPABILITY
|
|
1145
|
+
in ready.payload.accepted_capabilities
|
|
1146
|
+
else None
|
|
1147
|
+
),
|
|
1148
|
+
cleanup_kinds=tuple(hello.payload.handled_cleanup_kinds),
|
|
1149
|
+
cleanup_work_queue_ids=tuple(
|
|
1150
|
+
work_queue.id for work_queue in ready.payload.resolved_work_queues
|
|
1151
|
+
),
|
|
1152
|
+
max_cleanup_concurrency=ready.payload.effective_max_cleanup_concurrency,
|
|
1097
1153
|
)
|
|
1098
1154
|
await connection.run(ready, consumer_kwargs)
|
|
1099
1155
|
|
|
@@ -10,7 +10,8 @@ from typing_extensions import Literal, TypeAlias
|
|
|
10
10
|
|
|
11
11
|
from prefect.logging import get_logger
|
|
12
12
|
from prefect.server.database import PrefectDBInterface, db_injector
|
|
13
|
-
from prefect.server.events import filters
|
|
13
|
+
from prefect.server.events import clients, filters
|
|
14
|
+
from prefect.server.events.schemas import lifecycle
|
|
14
15
|
from prefect.server.events.schemas.automations import (
|
|
15
16
|
Automation,
|
|
16
17
|
AutomationPartialUpdate,
|
|
@@ -23,6 +24,31 @@ from prefect.utilities.asyncutils import run_coro_as_sync
|
|
|
23
24
|
|
|
24
25
|
logger: logging.Logger = get_logger(__name__)
|
|
25
26
|
|
|
27
|
+
|
|
28
|
+
async def emit_automation_created_event(automation: Automation) -> None:
|
|
29
|
+
"""Emit an event when an automation is created."""
|
|
30
|
+
async with clients.PrefectServerEventsClient() as events_client:
|
|
31
|
+
await events_client.emit(
|
|
32
|
+
lifecycle.automation_created_event(automation, now("UTC"))
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
async def emit_automation_updated_event(automation: Automation) -> None:
|
|
37
|
+
"""Emit an event when an automation is updated."""
|
|
38
|
+
async with clients.PrefectServerEventsClient() as events_client:
|
|
39
|
+
await events_client.emit(
|
|
40
|
+
lifecycle.automation_updated_event(automation, now("UTC"))
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
async def emit_automation_deleted_event(automation: Automation) -> None:
|
|
45
|
+
"""Emit an event when an automation is deleted."""
|
|
46
|
+
async with clients.PrefectServerEventsClient() as events_client:
|
|
47
|
+
await events_client.emit(
|
|
48
|
+
lifecycle.automation_deleted_event(automation, now("UTC"))
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
26
52
|
AutomationChangeEvent: TypeAlias = Literal[
|
|
27
53
|
"automation__created", "automation__updated", "automation__deleted"
|
|
28
54
|
]
|
|
@@ -176,6 +202,7 @@ async def create_automation(
|
|
|
176
202
|
await _sync_automation_related_resources(session, new_automation.id, automation)
|
|
177
203
|
|
|
178
204
|
await _notify(session, automation, "created")
|
|
205
|
+
await emit_automation_created_event(automation)
|
|
179
206
|
return automation
|
|
180
207
|
|
|
181
208
|
|
|
@@ -220,6 +247,11 @@ async def update_automation(
|
|
|
220
247
|
)
|
|
221
248
|
|
|
222
249
|
await _notify(session, automation, "updated")
|
|
250
|
+
|
|
251
|
+
updated_automation = await read_automation(session, automation_id)
|
|
252
|
+
if updated_automation is not None:
|
|
253
|
+
await emit_automation_updated_event(updated_automation)
|
|
254
|
+
|
|
223
255
|
return result.rowcount > 0 # type: ignore
|
|
224
256
|
|
|
225
257
|
|
|
@@ -260,6 +292,7 @@ async def delete_automation(
|
|
|
260
292
|
await _sync_automation_related_resources(session, automation_id, None)
|
|
261
293
|
|
|
262
294
|
await _notify(session, automation, "deleted")
|
|
295
|
+
await emit_automation_deleted_event(automation)
|
|
263
296
|
return True
|
|
264
297
|
|
|
265
298
|
|