@@ -790,9 +790,12 @@ Publishing Session Cancellation
790790
791791To cancel a publishing session, a client issues a ``DELETE `` request to the ``session `` :ref: `link
792792<publishing-session-links>` given in the :ref: `session creation response body <publishing-session-response >`.
793- The server then marks the session as ``canceled ``, and **SHOULD ** purge any data that was uploaded as part of
794- that session. Future attempts to access that session URL or any of the publishing session URLs **MUST **
795- return a ``404 Not Found ``.
793+ The server then marks the session as ``canceled `` and **SHOULD ** purge any data that was uploaded as part of
794+ that session. Once that data is purged, the session's action and data-bearing URLs -- ``links.upload ``,
795+ ``links.publish ``, ``links.extend ``, ``links.stage ``, and the individual file URLs -- **SHOULD ** become
796+ unavailable and **MAY ** return ``404 Not Found ``. The session status URL (``links.session ``) is instead
797+ retained as described in :ref: `publishing-session-retention `: it continues to report the ``canceled `` status
798+ for an index-specific period before it too **MAY ** return ``404 Not Found ``.
796799
797800Cancellation is only permitted while the session is :ref: `open or in the error state
798801<publishing-session-states>`. If the session is in the ``processing `` state (i.e. because a deferred
@@ -820,6 +823,31 @@ The server will respond to this ``GET`` request with the same :ref:`publishing s
820823any changes to ``status ``, ``expires-at ``, or ``files `` reflected.
821824
822825
826+ .. _publishing-session-retention :
827+
828+ Session Status Retention
829+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
830+
831+ A session status URL is not guaranteed to remain valid indefinitely. Once a session reaches a terminal state
832+ -- ``published `` or ``canceled `` -- the server **SHOULD ** continue to serve its :ref: `status URL
833+ <publishing-session-status>`, reporting the terminal ``status ``, for an index-specific retention period, so
834+ that clients can reliably observe the final outcome of a session they did not watch to completion. After that
835+ retention period elapses, the server **MAY ** return ``404 Not Found `` for the status URL. The length of the
836+ retention period is left to the index, but **SHOULD ** be long enough to let a client that initiated or
837+ contributed to the session learn its outcome.
838+
839+ This retention applies only to the session *status *; the data-bearing and action URLs for a terminated session
840+ (for example ``links.stage `` and the individual file URLs) may become unavailable as soon as their underlying
841+ data is no longer needed, as described for :ref: `cancellation <publishing-session-cancellation >`.
842+
843+ Clients **MUST ** be prepared for a session status URL to return ``404 Not Found `` once the session has
844+ terminated and its retention period has elapsed. A ``404 `` on a previously valid session status URL is not in
845+ itself an error; clients **SHOULD ** treat it as indicating that the session no longer exists. Note that once a
846+ terminated session has been purged, a request to :ref: `create a new session <publishing-session-multiple >` for
847+ the same ``name `` and ``version `` will succeed with a ``201 Created `` rather than returning the ``409
848+ Conflict `` that a still-live session would have produced.
849+
850+
823851.. _publishing-session-extension :
824852
825853Publishing Session Extension
@@ -1222,6 +1250,15 @@ The client can query status of the file upload session by issuing a ``GET`` requ
12221250<file-upload-session-response>`. The server responds to this request with the same payload as the file upload
12231251session creation response, except with any changes ``status `` and ``expires-at `` reflected.
12241252
1253+ A file upload session has no existence independent of the publishing session it belongs to, and its status URL
1254+ is retained accordingly. While the parent publishing session is in a non-terminal state, the server
1255+ **SHOULD ** keep each of its file upload session status URLs valid, reporting the file upload session's current
1256+ ``status `` -- including a terminal ``canceled `` -- so that a client can observe the outcome of any file it
1257+ uploaded. Once the parent publishing session itself terminates, its file upload session URLs are retained no
1258+ longer than the parent's own :ref: `status URL <publishing-session-retention >` and **MAY ** return ``404 Not
1259+ Found `` thereafter. As with cancellation, the data-bearing and mechanism portions of these URLs may become
1260+ unavailable as soon as the underlying file data is purged, independent of the status URL.
1261+
12251262.. _file-upload-session-extension :
12261263
12271264File Upload Session Extension
@@ -1704,6 +1741,16 @@ these constraints upfront is simpler when the project is known at session creati
17041741project version. Allowing multiple projects would fundamentally change this model and
17051742complicate the definition of what "publish" means for a session.
17061743
1744+ Even with the single-project restriction, this PEP still improves multi-project releases. A client releasing
1745+ several projects at once can fully :ref: `stage <staged-preview >` every project -- creating a publishing
1746+ session per project and uploading all of its artifacts -- before a final step runs through and
1747+ :ref: `publishes <publishing-session-completion >` each one. This gives the whole set a "stage everything, then
1748+ publish" workflow, even though each publish is still per-project and atomic on its own.
1749+
1750+ The single-project session also lays a foundation that a future "publish multiple projects" operation could
1751+ build on as a separate endpoint, coordinating the publication of several already-staged sessions, without
1752+ changing the per-session model defined here.
1753+
17071754
17081755Why is the version required when creating a publishing session?
17091756---------------------------------------------------------------
@@ -1777,6 +1824,17 @@ Change History
17771824 creation is best-effort and that the authoritative check happens atomically at publish time, reported
17781825 synchronously as a ``409 Conflict `` or, for a deferred publish, by moving the session to the ``error ``
17791826 state with the reason in ``notices ``.
1827+ * Add a **Session Status Retention ** section. Specify that after a session reaches a terminal
1828+ (``published `` or ``canceled ``) state, the server **SHOULD ** keep serving its status URL reporting the
1829+ terminal status for an index-specific retention period, after which it **MAY ** return ``404 Not Found ``,
1830+ and that clients must be prepared for such a ``404 ``. Reconcile the cancellation rules accordingly: the
1831+ data-bearing and action URLs may become unavailable once purged, while the status URL is retained.
1832+ Tie file upload session status URL retention to the parent publishing session: while the parent is
1833+ non-terminal the server **SHOULD ** keep its file upload session status URLs valid, and once the parent
1834+ terminates they are retained no longer than the parent's status URL.
1835+ * Expand the "Why is the project name required" FAQ to note that single-project sessions still improve
1836+ multi-project releases (all projects can be fully staged before a final step publishes each one) and lay a
1837+ foundation for a possible future "publish multiple projects" endpoint.
17801838
17811839* `26-Jun-2026 <https://discuss.python.org/t/pep-694-pypi-upload-api-2-0-round-3/107923 >`__
17821840
0 commit comments