@@ -561,14 +561,16 @@ The ``files`` key contains a mapping from the names of the files uploaded in thi
561561sub-mapping with the following keys:
562562
563563``status ``
564- A string with valid values
565- ``pending ``, ``processing ``, ``complete ``, ``error ``, and ``canceled ``.
566- If there was an error during upload,
567- then clients should not assume the file is in any usable state,
568- ``error `` will be returned and it's best to
569- :ref: `cancel or delete <file-upload-session-cancellation >` the file and start over.
570- This action would remove the file name from the ``files `` key of the
571- :ref: `session status response body <publishing-session-response >`.
564+ A string with valid values ``pending ``, ``processing ``, ``completed ``, and ``error ``, mirroring
565+ the :ref: `state of that file's upload session <file-upload-session-states >`. If there was an
566+ error during upload, then clients should not assume the file is in any usable state, ``error ``
567+ will be returned and it's best to :ref: `cancel or delete <file-upload-session-cancellation >` the
568+ file and start over.
569+
570+ ``canceled `` never appears here. Canceling or deleting a file removes its entry from the ``files ``
571+ mapping of the :ref: `session status response body <publishing-session-response >` entirely, since the
572+ file is no longer part of the session. The file's own :ref: `file upload session status URL
573+ <file-upload-session-status>` continues to report ``canceled ``.
572574
573575``link ``
574576 The *absolute * URL that the client should use to reference this specific file. This URL is used to
@@ -661,6 +663,9 @@ The transitions between these states are:
661663 * - ``open ``
662664 - Publish request accepted for deferred processing (``202 Accepted ``)
663665 - ``processing ``
666+ * - ``open `` or ``error ``
667+ - Publish requested while any file is not ``completed ``
668+ - rejected with ``409 Conflict `` (see :ref: `publishing-session-completion `)
664669 * - ``open `` or ``error ``
665670 - Publish request fails synchronously
666671 - unchanged (the error is returned to the caller)
@@ -710,6 +715,20 @@ The request looks like:
710715 }
711716
712717
718+ Every file in the session **MUST ** have finished uploading before the session can be published. If any entry
719+ in the session's :ref: `files mapping <publishing-session-files >` is in a state other than ``completed ``, the
720+ server **MUST ** reject the publish request with a ``409 Conflict `` :ref: `error response <session-errors >`
721+ identifying the offending file(s) and their current states, and leave the session in its current editable
722+ state. The client resolves this by waiting for each in-flight :ref: `file upload session
723+ <file-upload-session-states>` to resolve, and then either publishing again or first :ref: `deleting
724+ <file-upload-session-cancellation>` the files it no longer intends to publish.
725+
726+ This precondition is deliberately expressed as an allow-list -- only ``completed `` files may be published --
727+ so that a file in any other state blocks publication rather than being silently included or silently dropped.
728+ In particular this covers files in the ``error `` state, which cannot be repaired in place and **MUST ** be
729+ deleted (see :ref: `file-upload-session-states `), as well as any additional file states that a future revision
730+ of this protocol might introduce.
731+
713732If the server is able to immediately complete the publishing session, it may do so and return a ``201
714733Created `` response, moving the session to the terminal :ref: `status <publishing-session-states >`
715734``published ``. If it is unable to immediately complete the publishing session (for instance, if it needs to
@@ -745,7 +764,9 @@ is therefore performed atomically at publish time.
745764
746765**Filename reservation. ** When a client requests publication, the server **MUST ** atomically reserve the
747766filenames of all files in the session within the target release, and hold that reservation for the duration of
748- the publish:
767+ the publish. Because :ref: `publication requires every file in the session to have finished uploading
768+ <publishing-session-completion>`, this reservation covers exactly the fully uploaded files that the session
769+ will publish:
749770
750771- While the reservation is held, any other attempt to upload a file with one of those filenames to the same
751772 release -- whether through this API or the legacy API -- **MUST ** be rejected with a ``409 Conflict ``,
@@ -807,6 +828,15 @@ publishing request is already being processed) the server **MUST** reject the ca
807828Conflict ``, since publication may already be in progress. The client can instead wait for processing to
808829resolve; if it resolves to ``error ``, the session can then be canceled.
809830
831+ Cancellation is otherwise permitted regardless of the states of the session's files. In particular, a session
832+ **MUST NOT ** be refused cancellation because one or more of its file upload sessions is in the ``processing ``
833+ state. Unlike :ref: `deleting an individual file <file-upload-session-cancellation >`, which leaves the session
834+ live and heading toward a publish whose contents would then depend on how that file's processing resolved,
835+ canceling the session guarantees that nothing will be published, so no in-flight validation outcome can affect
836+ the result. The server **MAY ** allow such in-flight processing to run to completion and discard the result
837+ rather than interrupting it. All of the session's file upload sessions are considered ``canceled ``, and their
838+ URLs receive the same treatment as the session's other data-bearing URLs described above.
839+
810840To prevent dangling sessions, servers may also choose to cancel timed-out sessions on their own
811841accord. It is recommended that servers expunge their sessions after no less than a week, but each
812842server may choose their own schedule. Servers **MAY ** support client-directed :ref: `session
@@ -1025,7 +1055,7 @@ the following keys:
10251055 the details of which are provided below.
10261056
10271057``status ``
1028- A string with valid values ``pending ``, ``processing ``, ``complete ``, ``error ``, and ``canceled ``
1058+ A string with valid values ``pending ``, ``processing ``, ``completed ``, ``error ``, and ``canceled ``
10291059 indicating the current :ref: `state of the file upload session <file-upload-session-states >`.
10301060
10311061``expires-at ``
@@ -1069,17 +1099,18 @@ File Upload Session States
10691099A file upload session is always in exactly one of the following states, reported by the ``status ``
10701100key of the :ref: `file upload session status response <file-upload-session-response >`. The same
10711101value is reflected for the file in the ``files `` mapping of the :ref: `publishing session status
1072- <publishing-session-files>`.
1102+ <publishing-session-files>`, except for ``canceled ``: a canceled or deleted file is removed from that
1103+ mapping altogether, and only its own status URL continues to report ``canceled ``.
10731104
10741105.. image :: pep-0694/file-upload-session-states.drawio.svg
10751106 :align: center
10761107 :class: invert-in-dark-mode
10771108 :alt: State diagram for a file upload session. From the initial state the session enters ``pending``,
10781109 during which the negotiated upload mechanism executes. From ``pending`` completing the upload either
1079- succeeds immediately (``201``) to ``complete ``, is accepted for deferred processing (``202``) into
1110+ succeeds immediately (``201``) to ``completed ``, is accepted for deferred processing (``202``) into
10801111 ``processing``, or fails synchronously (``4xx``/``5xx``) to ``error``; ``pending`` can also be
1081- canceled (``DELETE``) to the terminal ``canceled`` state. ``processing`` resolves to ``complete `` on
1082- success or to ``error`` on failure. Both ``complete `` and ``error`` can be deleted (``DELETE``) to
1112+ canceled (``DELETE``) to the terminal ``canceled`` state. ``processing`` resolves to ``completed `` on
1113+ success or to ``error`` on failure. Both ``completed `` and ``error`` can be deleted (``DELETE``) to
10831114 ``canceled``. Canceling during ``processing`` is rejected with ``409``.
10841115
10851116The textual description of each state and a complete transition table follow.
@@ -1095,10 +1126,11 @@ The textual description of each state and a complete transition table follow.
10951126 The client has requested completion and the server accepted the request for deferred processing, returning
10961127 a ``202 Accepted `` (see :ref: `file-upload-session-completion `). This is a transitional state; the client
10971128 polls the :ref: `file upload session status <file-upload-session-status >`, respecting the ``Retry-After ``
1098- header, until it resolves to ``complete `` or ``error ``.
1129+ header, until it resolves to ``completed `` or ``error ``.
10991130
1100- ``complete ``
1101- The file has been fully uploaded, validated, and accepted into the publishing session. The file can still
1131+ ``completed ``
1132+ The file has been fully uploaded, validated, and accepted into the publishing session. This is the only
1133+ state from which a file may be :ref: `published <publishing-session-completion >`. The file can still
11021134 be :ref: `deleted <file-upload-session-cancellation >`, which removes it from the publishing session and
11031135 moves this session to ``canceled ``.
11041136
@@ -1115,7 +1147,7 @@ The textual description of each state and a complete transition table follow.
11151147 and its associated upload mechanisms **MUST NOT ** be assumed reusable; recovering or replacing the file
11161148 requires a new file upload session.
11171149
1118- Only ``canceled `` is terminal. Both ``complete `` and ``error `` still permit a ``DELETE `` (which moves the
1150+ Only ``canceled `` is terminal. Both ``completed `` and ``error `` still permit a ``DELETE `` (which moves the
11191151session to ``canceled ``); from ``error ``, deletion is the only forward action.
11201152
11211153The transitions between these states are:
@@ -1135,7 +1167,7 @@ The transitions between these states are:
11351167 - ``pending ``
11361168 * - ``pending ``
11371169 - Completion request completed immediately (``201 Created ``)
1138- - ``complete ``
1170+ - ``completed ``
11391171 * - ``pending ``
11401172 - Completion request accepted for deferred processing (``202 Accepted ``)
11411173 - ``processing ``
@@ -1147,14 +1179,14 @@ The transitions between these states are:
11471179 - ``canceled ``
11481180 * - ``processing ``
11491181 - Deferred processing succeeds
1150- - ``complete ``
1182+ - ``completed ``
11511183 * - ``processing ``
11521184 - Deferred processing fails
11531185 - ``error ``
11541186 * - ``processing ``
11551187 - Cancellation requested
11561188 - rejected with ``409 Conflict `` (see :ref: `file-upload-session-cancellation `)
1157- * - ``complete ``
1189+ * - ``completed ``
11581190 - File deleted (``DELETE ``)
11591191 - ``canceled ``
11601192 * - ``error ``
@@ -1188,7 +1220,7 @@ The request looks like:
11881220 }
11891221
11901222 If the server is able to immediately complete the file upload session, it may do so and return a ``201
1191- Created `` response and set the status of the file upload session to ``complete ``. If it is unable to
1223+ Created `` response and set the status of the file upload session to ``completed ``. If it is unable to
11921224immediately complete the file upload session (for instance, if it needs to do validation that may take longer
11931225than reasonable in a single HTTP request), then it may return a ``202 Accepted `` response and set the status
11941226of the file upload session to ``processing ``.
@@ -1219,7 +1251,7 @@ to delete.
12191251
12201252A successful deletion request **MUST ** respond with a ``204 No Content ``.
12211253
1222- A ``DELETE `` is permitted while the session is ``pending `` (canceling an in-progress upload), ``complete ``
1254+ A ``DELETE `` is permitted while the session is ``pending `` (canceling an in-progress upload), ``completed ``
12231255(deleting an uploaded file), or ``error `` (discarding a failed upload). If the session is in the
12241256``processing `` state -- that is, a deferred completion is already underway -- the server **MUST ** reject the
12251257``DELETE `` with a ``409 Conflict ``, since the outcome is already being decided. The client can instead wait
@@ -1839,6 +1871,26 @@ Change History
18391871 * Expand the "Why is the project name required" FAQ to note that single-project sessions still improve
18401872 multi-project releases (all projects can be fully staged before a final step publishes each one) and lay a
18411873 foundation for a possible future "publish multiple projects" endpoint.
1874+ * Define what happens when a publish is requested while file uploads are still in flight, which
1875+ was previously unspecified. Publication now has an explicit precondition: every entry in the
1876+ session's ``files `` mapping **MUST ** be in the ``completed `` state, otherwise the server
1877+ **MUST ** reject the publish request with a ``409 Conflict `` identifying the offending file(s)
1878+ and leave the session editable. The rule is written as an allow-list so that files in
1879+ ``error ``, and any file states added by future revisions, block publication rather than being
1880+ silently included or dropped. Add a corresponding row to the publishing session transition
1881+ table and scope the filename reservation to the fully uploaded files the session will publish.
1882+ * Rename the file upload session ``complete `` status to ``completed ``. This matches the
1883+ past-participle form of the other settled statuses (``canceled ``, and the publishing session's
1884+ ``published ``), and disambiguates the *state * from the ``complete `` *action * and its
1885+ ``links.complete `` endpoint, which keep their names.
1886+ * Specify that a publishing session **MUST ** be cancelable regardless of the states of its files, and in
1887+ particular **MUST NOT ** be refused cancellation because a file upload session is ``processing ``. Because
1888+ canceling guarantees nothing will be published, no in-flight validation outcome can affect the result, so
1889+ unlike an individual file deletion there is no race to protect against; the server **MAY ** let in-flight
1890+ processing finish and discard the result rather than interrupting it.
1891+ * Remove ``canceled `` from the valid values of the publishing session ``files `` mapping ``status `` key,
1892+ resolving a contradiction with the existing rule that canceling or deleting a file removes its entry from
1893+ that mapping. The file's own file upload session status URL continues to report ``canceled ``.
18421894
18431895* `26-Jun-2026 <https://discuss.python.org/t/pep-694-pypi-upload-api-2-0-round-3/107923 >`__
18441896
0 commit comments