Movatterモバイル変換


[0]ホーム

URL:


Following system colour schemeSelected dark colour schemeSelected light colour scheme

Python Enhancement Proposals

PEP 694 – Upload 2.0 API for Python Package Indexes

Author:
Barry Warsaw <barry at python.org>, Donald Stufft <donald at stufft.io>, Ee Durbin <ee at python.org>
PEP-Delegate:
Dustin Ingram <di at python.org>
Discussions-To:
Discourse thread
Status:
Draft
Type:
Standards Track
Topic:
Packaging
Created:
11-Jun-2022
Post-History:
27-Jun-2022,06-Jan-202514-Apr-202506-Aug-202527-Sep-202507-Dec-2025

Table of Contents

Abstract

This PEP proposes an extensible API for uploading files to a Python package index such as PyPI.Along with standardization, the upload API provides additional useful features such as support for:

  • a publishing session, which can be used to simultaneously publishall wheels in a package release;
  • “staging” a release, which can be used to test uploads before publicly publishing them,without the need fortest.pypi.org;
  • artifacts which can be overwritten and replaced, until a session is published;
  • detailed status on the state of artifact uploads;
  • new project creation without requiring the uploading of an artifact.
  • a protocol to extend the supported upload mechanisms in the future without requiring a full PEP;these can be standardized and recommended for all indexes, or be index-specific;

Once this new upload API is adopted, the existing legacy API can be deprecated, however this PEPdoes not propose a deprecation schedule for the legacy API.

Rationale

There is currently no standardized API for uploading files to a Python package index such asPyPI. Instead, everyone has been forced to reverse engineer the existing“legacy” API.

The legacy API, while functional, leaks implementation details of the original PyPI code base,which has been faithfully replicated in the new code base and alternative implementations.

In addition, there are a number of major issues with the legacy API:

  • It is fully synchronous, which forces requests to be held open both for the upload itself, andwhile the index processes the uploaded file to determine success or failure.
  • It does not support any mechanism for parallelizing or resuming an upload. With the largestdefault file size on PyPI being around 1GB in size, requiring the entire upload to completesuccessfully means bandwidth is wasted when such uploads experience a network interruption whilethe request is in progress.
  • The atomic unit of operation is a single file. This is problematic when a release logicallyincludes an sdist and multiple binary wheels, leading to race conditions where consumers getdifferent versions of the package if they are unlucky enough to require a package before theirplatform’s wheel has completely uploaded. If the release uploads its sdist first, this may alsomanifest in some consumers seeing only the sdist, triggering a local build from source.
  • Status reporting is very limited. There’s no support for reporting multiple errors, warnings,deprecations, etc. Status is limited to the HTTP status code and reason phrase, of which thereason phrase has been deprecated since HTTP/2 (RFC 7540).
  • Metadata for a release is submitted alongside the file. However, as this metadata is famouslyunreliable, most installers instead choose to download the entire file and read the metadata fromthere.
  • There is no mechanism for allowing an index to do any sort of sanity checks before bandwidth getsexpended on an upload. Many cases of invalid metadata or incorrect permissions could be checkedprior to uploading files.
  • There is no support for “staging” a release prior to publishing it to the index.
  • Creation of new projects requires the uploading of at least one file, leading to “stub” uploadsto claim a project namespace.

The new upload API proposed in this PEP provides ways to solve all of these problems, either directly orthrough an extensible approach, allowing servers to implement features such as resumable and parallel uploads.This upload API this PEP proposes provides better and more standardized error reporting, a more robust releasetesting experience, and atomic and simultaneous publishing of all release artifacts.

Legacy API

The following is an overview of the legacy API. For the detailed description, consult thePyPI user guide documentation.

Endpoint

The existing upload API lives at a base URL. For PyPI, that URL is currentlyhttps://upload.pypi.org/legacy/. Clients performing uploads specify the API they want to callby adding an:action URL parameter with a value offile_upload.[1]

The legacy API also has aprotocol_version parameter,in theory allowing new versions of the API to be defined.In practice this has never happened, and the value is always1.

Thus, the effective upload API on PyPI is:https://upload.pypi.org/legacy/?:action=file_upload&protocol_version=1.

Encoding

The data to be submitted is submitted as aPOST request with the content type ofmultipart/form-data. This reflects the legacy API’s historical nature, which was originallydesigned not as an API, but rather as a web form on the initial PyPI implementation,with client code written to programmatically submit that form.

Content

Roughly speaking, the metadata contained within the package is submitted as parts where the contentdisposition isform-data, and the metadata key is the name of the field. The names of thesevarious pieces of metadata are not documented, and they sometimes, but not always match the namesused in theMETADATA files for package artifacts.The case rarely matches, and theform-data toMETADATA conversion is inconsistent.

The upload artifact file itself is sent as aapplication/octet-stream part with the name ofcontent, and if there is a PGP signature attached, then it will be included as aapplication/octet-stream part with the name ofgpg_signature.

Authentication

Upload authentication is also not standardized.

PyPI uses HTTP Basic AuthenticationwithAPI tokens as the passwordand the username__token__.Trusted Publishersauthenticate via OpenID Connect and receive short-lived API tokensthat are used in the same way.

Upload 2.0 API Specification

This PEP traces the root cause of most of the issues with the existing API to be roughly two things:

  • The metadata is submitted alongside the file, rather than being parsed from thefile itself.[2]
  • It supports only a single request, using only form data, that either succeeds or fails, and allactions are atomic within that single request.

To address these issues, this PEP proposes a multi-request workflow, which at a high level involvesthese steps:

  1. Initiate apublishing session, creating a release stage.
  2. Initiatefile upload session(s) to that stageas part of the publishing session.
  3. Negotiate the specificfile upload mechanism to usebetween client and server.
  4. Execute the file upload mechanism for the file upload session(s) using the negotiated mechanism(s).
  5. Complete the file upload session(s), marking them as completed or canceled.
  6. Complete the publishing session, publishing or discarding the stage.
  7. Optionally check the status of a publishing session.

Versioning

This PEP uses the sameMAJOR.MINOR versioning system as used inPEP 691,but it is otherwise independently versioned.The legacy API is considered by this PEP to be version1.0,but this PEP does not modify the legacy API in any way.

The API proposed in this PEP therefore has the version number2.0.

Both major and minor version numbers of the Upload APIMUST only be changed through the PEP process.Index operators and implementersMUST NOT advertise or implementnew API versions without an approved PEP.This ensures consistency across all implementationsand prevents fragmentation of the ecosystem.

Content Types

LikePEP 691, this PEP proposes that all requests and responses from this upload API will have astandard content type that describes what the content is, what version of the API it represents,and what serialization format has been used.

This standard request content type applies to all requestsexcept for requests to executea file upload mechanism, which will be specified by the documentation for that mechanism.

The structure of theContent-Type header for all other requests is:

application/vnd.pypi.upload.$version+$format

Since minor API version differences should never be disruptive, only the major version is includedin the content type; the version number is prefixed with av.

The major API version specified in the.meta.api-version JSON key of client requestsMUST match theContent-Type header for major version.

UnlikePEP 691, this PEP does not change the existinglegacy1.0 upload API in any way,so servers are required to host the new API described in this PEP at a different endpoint than theexisting upload API.

Since JSON is the only defined request format defined in this PEP, all non-file-upload requestsdefined in this PEPMUST include aContent-Type header value of:

  • application/vnd.pypi.upload.v2+json.

Similar toPEP 691, this PEP also standardizes on using server-driven content negotiation toallow clients to request different versions or serialization formats,which includes theformat part of the content type.However, since this PEP expects the existing legacy1.0 upload APIto exist at a different endpoint,and this PEP currently only provides for JSON serialization,this mechanism is not particularly useful.Clients only have a single version and serialization they can request.However clientsSHOULD be prepared to handle content negotiation gracefullyin the case that additional formats or versions are added in the future.

ServersMUST NOT advertise support for API versions beyond those defined in approved PEPs.Any new versions or formats require standardization through a new PEP.

Unless otherwise specified, all HTTP requests and responses in this document are assumed to includethe HTTP header:

Content-Type: application/vnd.pypi.upload.v2+json

Root Endpoint

All URLs described here are relative to the “root endpoint”, which may be located anywhere withinthe url structure of a domain. For example, the root endpoint could behttps://upload.example.com/, orhttps://example.com/upload/.

The choice of the root endpoint is left up to the index operator.

Authentication for Upload 2.0 API

All endpoints in this specificationMUST use standard HTTP authenticationmechanisms as defined inRFC 7235.

Authentication follows the standard HTTP pattern:

  • Servers use theWWW-Authenticate response header when authentication is required
  • Clients provide credentials via theAuthorization request header
  • 401Unauthorized indicates missing or invalid authentication
  • 403Forbidden indicates insufficient permissions

The specific authentication schemes (e.g., Bearer, Basic, Digest)are determined by the index operator.

Errors

Unless otherwise specified, all error (4xx and 5xx) responses from the serverMUST use theRFC 9457(Problem Details for HTTP APIs) format. In particular, the serverMUST use the “Problem Details JSONObject” defined inSection 3 andSHOULD use theapplication/problem+json mediatype in its responses.

Clients in general should be prepared to handleHTTP response error status codes whichSHOULD contain payloads likethe following, although note that the details are index-specific, as long as they conform to RFC 9457. By wayof example, PyPI could return the following error body:

{"type":"https://docs.pypi.org/api/errors/error-types#invalid-filename","status":400,"title":"The artifact used an invalid wheel file name format","details":"See https://packaging.python.org/en/latest/specifications/binary-distribution-format/","meta":{"api-version":"2.0"},"errors":[{"source":"...","message":"..."}]}

RFC 9457 definestype,status,title, anddetails. Themeta anderrors keys are“extension members”, defined inSection 3.2. The indexSHOULD include theseextension members.

meta
The same request/response metadata structure as defined in thePublishing Session description.
errors
An array of specific errors, each of which contains asource key, which is a string thatindicates what the source of the error is, and amessage key for that specific error.

Themessage andsource strings do not have any specific meaning, and are intended for humaninterpretation to aid in diagnosing underlying issue.

Some responses may return more specific HTTP status codes as described in the text below.

Publishing Session

Create a Publishing Session

A release starts by creating a new publishing session. To create the session, a client submits aPOST request to the root URL like:

{"meta":{"api-version":"2.0"},"name":"foo","version":"1.0",}

The request includes the following top-level keys:

meta (required)
Describes information about the payload itself. Currently, the only defined sub-key isapi-version the value of which must be the string"2.0". Optional sub-keys can defineindex-specific behavior.
name (required)
The name of the project that this session is attempting to release a new version of. The nameMUST conform to thestandard package name formatand the serverMUST normalize the name.
version (required)
The version of the project that this session is attempting to add files to. The version stringMUST conform to thepackaging version specification.

Upon successful session creation, the server returns a201Created response. The responseMUST alsoinclude aLocation header containing the same URL as thelinks.sessionkey in theresponse body.

If a session is created for a project which has no previous release,then the indexMAY reserve the project name before the session is published,however itMUST NOT be possible to navigate to that project usingthe “regular” (i.e.unstaged) access protocols,until the stage is published.If this first-release stage gets canceled,then the indexSHOULD delete the project record, as if it were never uploaded.

The session is owned by the user that created it,and all subsequent requestsMUST be performed with the same credentials,otherwise a403Forbidden will be returned on those subsequent requests.

Optional Index-specific Metadata

Index can optionally define their own metadata for index-specific behavior. The metadata keyMUST begin with an underscore, with the following value easily and uniquely identifying theindex. For example, PyPI could allow for projects to be created in anorganization account of which the publisher is a member by using thefollowing index-specific metadata section:

{"meta":{"api-version":"2.0","_pypi.org":{"organization":"my-main-org"}},"name":"foo","version":"1.0",}

This is only an example. This PEP does not define or reserve any index-specific keys or metadata;that is left up to the index to specify and document. The semantics (e.g. whether bogus keys orvalues result in an error or are ignored) of the index-specific metadata is also undefined here.

Response Body

The successful response includes the following content:

{"meta":{"api-version":"2.0"},"links":{"stage":"...","upload":"...","session":"...",},"mechanisms":["http-post-bytes"],"session-token":"<token-string>","expires-at":"2025-08-01T12:00:00Z","status":"pending","files":{},"notices":["a notice to display to the user"]}

Besides themeta key, which has the same format as the request JSON, the success response hasthe following keys:

links
A dictionary mappingkeys to URLs related to this session,the details of which are provided below.
mechanisms
A list of file-upload mechanisms supported by the server, sorted in server-preferred order.At least one value is required.
session-token
If the index supportspreviewing staged releases, this key will contain the unique“session token” that can be provided to installers in order to previewthe staged release before it’s published. This tokenMUST be cryptographically unguessable. If theindex doesnot support stage previewing, this keyMUST be omitted.
expires-at
AnRFC 3339 formatted timestamp string; this stringMUST represent a UTC timestamp using the“Zulu” (i.e.Z) marker, and use only whole seconds (i.e. no fractional seconds). Thistimestamp represents when the server will expire this session, and thus all of its content,including any uploaded files and the URL links related to the session. The sessionSHOULDremain active until at least this time unless the client itself has canceled or published thesession. ServersMAY choose to extend this expiration time, but should never move itearlier. Clients can query thesession status to get the currentexpiration time of the session.
status
A string that contains one ofpending,published,error, orcanceled,representing the overallstatus of the session.
files
A mapping containing the filenames that have been uploaded to this session, to a mappingcontaining details about eachfile referenced in this session.
notices
An optional key that points to an array of human-readable informational notices that the serverwishes to communicate to the end user. These notices are specific to the overall session, notto any particular file in the session.
Multiple Session Creation Requests

If a second attempt to create a session is received for the same name-version pair while a session for thatpair is in thepending,processing, orcomplete state, then a new session isnot created.Instead, the serverMUST respond with a409Conflict andMUST include aLocation header thatpoints to thesession status URL.

For sessions in theerror orcanceled state, a new session is created with same201Createdresponse and payload, except that thepublishing session status URL,session-token, andlinks.stage valuesMUST be different.

Publishing Session Links

For thelinks key in the success JSON, the following sub-keys are valid:

session
The endpoint where actions for this session can be performed,includingpublishing this session,canceling and discarding the session,querying the current session status,andrequesting an extension of the session lifetime(if the server supports it).
upload
The endpoint session clients will use to initiate afile upload sessionfor each file to be included in this session.
stage
The endpoint where this staged release can bepreviewed prior to publishing thesession. This can be used to download and verify the not-yet-public files. This URLMUST becryptographically unguessable andMUST use the abovesession-token to accomplish this. Thisstage URL should be easily calculated using thesession-token, but the exact format of that URL isindex specific. If the index does not support previewing staged releases, this keyMUST be omitted.
Publishing Session Files

Thefiles key contains a mapping from the names of the files uploaded in this session to asub-mapping with the following keys:

status
A string with valid valuespending,processing,complete,error, andcanceled.If there was an error during upload,then clients should not assume the file is in any usable state,error will be returned and it’s best tocancel or delete the file and start over.This action would remove the file name from thefiles key of thesession status response body.
link
Theabsolute URL that the client should use to reference this specific file. This URL is used toretrieve, replace, or delete thereferenced file. If apreview stages are supported, this URLMUST be cryptographically unguessable, andMUST usethe samepublishing session token to do ensure this constraint. Theexact format of the URL is left to the index, butSHOULD be documented.
notices
An optional key with similar format and semantics as thenotices session key, except thatthese notices are specific to the referenced file.

Complete a Publishing Session

To complete a session and publish the files that have been included in it, a client issues aPOST request to thesessionlinkgiven in thesession creation response body.

The request looks like:

{"meta":{"api-version":"2.0"},"action":"publish",}

If the server is able to immediately complete the publishing session, it may do so and return a201Created response. If it is unable to immediately complete the publishing session(for instance, if it needs to do validation that may take longer than reasonable in a single HTTPrequest), then it may return a202Accepted response.

The serverMUST include aLocation header in the response pointing back to thePublishingSession status URL, which can be used to query the current session status. If the serverreturned a202Accepted, polling that URL can be used to watch for session status changes.

Publishing Session Cancellation

To cancel a publishing session, a client issues aDELETE request tothesessionlinkgiven in thesession creation response body.The server then marks the session as canceled, andSHOULD purge any data that was uploadedas part of that session.Future attempts to access that session URL or any of the publishing session URLsMUST return a404NotFound.

To prevent dangling sessions, servers may also choose to cancel timed-out sessions on their ownaccord. It is recommended that servers expunge their sessions after no less than a week, but eachserver may choose their own schedule. ServersMAY support client-directedsessionextensions.

Publishing Session Status

At any time, a client can query the status of a session by issuing aGET request to the URL given in thelinks.session URL (also provided in thesession creation response’sLocation header).

The server will respond to thisGET request with the samepublishing session creation response, that they got when they initially created the publishing session, except withany changes tostatus,expires-at, orfiles reflected.

Publishing Session Extension

ServersMAY allow clients to extend sessions, but the overall lifetime and number of extensionsallowed is left to the server. To extend a session, a client issues aPOST request to thelinks.session URL (same as above, also theLocation header).

The request looks like:

{"meta":{"api-version":"2.0"},"action":"extend","extend-for":3600}

The number of seconds specified is just a suggestion to the server for the number of additional seconds toextend the current session. For example, if the client wants to extend the current session for another hour,extend-for would be3600. Upon successful extension, the server will respond with the samepublishing session creation response body that they got when theyinitially created the publishing session, except with any changes tostatus,expires-at, orfilesreflected.

If the server refuses to extend the session for the requested number of seconds, itMUST still return asuccess response, and theexpires-at key will simply reflect the current expiration time of the session.

Publishing Session Token

IndexesSHOULD supportpreview stages so that uploaded files can be live testedbefore publishing. E.g. a CI client could perform installation tests using pre-published wheels to ensurethat their new release works as expected before they publish the release publicly.

Indexes advertise their support for staged previews by returning two key pieces of information in theirresponse to publishing session creation. Indexes which don’t supportstaged previewsMUST NOT include these in their responses.

Thesession-token is a short token which could be used as a convenience for installation tool UX, if theywant to support staged previews via a command line switch, e.g.$TOOLinstall--staging$SESSION_TOKEN.Thelinks.stage key gives the full URL to the stage, which could be used in the CLI, e.g.pipinstall--extra-index-url$STAGE_URL. Both the session token and URLMUST be cryptographicallyunguessable, but the algorithm for generating the token is left to the index. The stage URLMUST becalculable from the session token, using a format documented by the index, but the exact format of the URL isalso left to the index.

File Upload Session

Create a File Upload Session

After creating a publishing session, theupload endpoint from the response’ssession links mapping is used to begin the upload of new files into that session. ClientsMUST use the providedupload URL andMUST NOT assume there is any pattern or commonality to thoseURLs from one session to the next.

To initiate a file upload, a client first sends aPOST request to theupload URL.The request looks like:

{"meta":{"api-version":"2.0"},"filename":"foo-1.0.tar.gz","size":1000,"hashes":{"sha256":"...","blake2b":"..."},"metadata":"...","mechanism":"http-post-bytes"}

Besides the standardmeta key, the request JSON has the following additional keys:

filename (required)
The name of the file being uploaded. The filenameMUST conform to either thesource distributionfile name specificationor thebinary distribution file name convention.IndexesSHOULD validate these file names at the time of the request, returning a400BadRequesterror code and an RFC 9457 style error body, as described in theErrors section when thefile names do not conform.
size (required)
The size in bytes of the file being uploaded.
hashes (required)
A mapping of hash names to hex-encoded digests. Each of these digests are the checksums of thefile being uploaded when hashed by the algorithm identified in the name.

By default, any hash algorithm available inhashlib can be used as a key for the hashesdictionary[3]. At least one secure algorithm fromhashlib.algorithms_guaranteedMUST always be included. This PEP specifically recommendssha256.

Multiple hashes may be passed at a time, but all hashes providedMUST be valid for the file.

mechanism (required)
The file-upload mechanisms the client intends to use for this file.This mechanismSHOULD be chosen from the list of mechanisms advertised in thepublishing session creation response body.A clientMAY send a mechanism that is not advertised in cases where server operators havedocumented a new or upcoming mechanism that is available for use on a “pre-release” basis.
metadata (optional)
If given, this is a string value containing the file’score metadata.

ServersMAY use the data provided in this request to do some sanity checking prior to allowingthe file to be uploaded. These checks may include, but are not limited to:

  • checking if thefilename already exists in a published release;
  • checking if thesize would exceed any project or file quota;
  • checking if the contents of themetadata, if provided, are valid.

If the server determines that upload should proceed, it will return a202Accepted response, with theresponse body below. Thestatus of the publishing session will alsoinclude the filename in thefiles mapping. If the server cannot proceed with an upload because themechanism supplied by the client is not supported itMUST return a422UnprocessableContent. TheserverMAY allow parallel uploads of files, but is not required to. If the server determines the uploadcannot proceed, itMUST return a409Conflict.

Response Body

The successful response includes the following:

{"meta":{"api-version":"2.0"},"links":{"file-upload-session":"..."},"status":"pending","expires-at":"2025-08-01T13:00:00Z","mechanism":{"identifier":"http-post-bytes","file_url":"...","attestations_url":"..."}}

ARetry-After response headerMUST be present to indicate to clients when they should next poll for anupdated status.

Besides themeta key, which has the same format as the request JSON, the success response hasthe following keys:

links
A dictionary mappingkeys to URLs related to this session,the details of which are provided below.
status
A string with valid valuespending,processing,complete,error, andcanceledindicating the current state of the file upload session.
expires-at
AnRFC 3339 formatted timestamp string representing when the server will expire this file uploadsession. This stringMUST represent a UTC timestamp using the “Zulu” (i.e.Z) marker,and use only whole seconds (i.e. no fractional seconds). The sessionSHOULD remain activeuntil at least this time unless the client cancels or completes it. ServersMAY choose toextend this expiration time, but should never move it earlier.
mechanism
A mapping containing the necessary details for the supported mechanism as negotiated by the client andserver. This mappingMUST contain a keyidentifier which maps to the identifier string for thechosen file upload mechanism.
File Upload Session Links

For thelinks key in the response payload, the following sub-keys are valid:

file-upload-session
The endpoint where actions for this file-upload-session can be performed. includingcompleting afile upload session,canceling and discarding the file uploadsession,querying the current file upload session status, andrequesting an extension of the file upload session lifetime (if the server supports it).

Complete a File Upload Session

To complete a file upload session, which indicates that the file upload mechanism has been executedand did not produce an error, a client issues aPOST to thefile-upload-session link in thefile upload session creation response body.

The requests looks like:

{"meta":{"api-version":"2.0"},"action":"complete",}

If the server is able to immediately complete the file upload session, it may do so and return a201Created response and set the status of the file upload session tocomplete. If it is unable toimmediately complete the file upload session (for instance, if it needs to do validation that may take longerthan reasonable in a single HTTP request), then it may return a202Accepted response and set the statusof the file upload session toprocessing.

In either case, the server should include aLocation header pointing back to thefile upload sessionstatus URL.

ServersMUST allow clients to poll the file upload session status URL to watch for the status to change.If the server responds with a202Accepted, clients may poll the file upload session status URL to watchfor the status to change. ClientsSHOULD respect theRetry-After header value of the file uploadsession status response.

Cancellation and Deletion

A client can cancel an in-progress file upload session, or delete a file that has been completely uploaded.In both cases, the client performs this by issuing aDELETE request to thelinks.file-upload-sessionURL from thefile upload session creation response of the file they wantto delete.

A successful deletion requestMUST respond with a204NoContent.

Once canceled or deleted, a clientMUST NOT assume that the previous file upload session resource orassociated file upload mechanisms can be reused.

Replacing a Partially or Fully Uploaded File

To replace a session file, the file uploadMUST have been previously completed, canceled, ordeleted. It is not possible to replace a file if the upload for that file is in-progress.

To replace a session file, clients shouldcancel and delete the in-progress upload first. After this, the new file upload can be initiated by beginning theentirefile upload sequence over again. This means providing the metadatarequest again to retrieve a new upload resource URL. ClientsMUST NOT assume that the previous uploadresource URL can be reused after deletion.

File Upload Session Status

The client can query status of the file upload session by issuing aGET request to thelinks.file-upload-session URL from thefile upload session creation response. The server responds to this request with the same payload as the file uploadsession creation response, except with any changesstatus andexpires-at reflected.

File Upload Session Extension

ServersMAY allow clients to extend file upload sessions, but the overall lifetime and number ofextensions allowed is left to the server. To extend a file upload session, a client issues aPOST requestto thelinks.file-upload-session URL from thefile upload session creation response.

The request looks like:

{"meta":{"api-version":"2.0"},"action":"extend","extend-for":3600}

The number of seconds specified is just a suggestion to the server for the number of additional seconds toextend the current file upload session. For example, if the client wants to extend session for another hour,extend-for would be3600. Upon successful extension, the server will respond with the samefileupload session creation response body that they got when they initiallycreated the publishing session, except with any changes tostatus orexpires-at reflected.

If the server refuses to extend the session for the requested number of seconds, itMUST still return asuccess response, and theexpires-at key will simply reflect the current expiration time of the session.

Stage Previews

The ability to preview staged releases before they are published is an important feature of this PEP, enablingan additional level of last-mile testing before the release is available to the public. IndexesMAYprovide this functionality through the URL provided in thestage sub-key of thelinks key returned when the publishing session is created. Thestage URL can be passedto installers such aspip by setting the–extra-index-url flag to this value. Multiplestages can even be previewed by repeating this flag with multiple values.

If supported, the index will return views that expose the staged releases to the installer tool,making them available to download and install into virtual environments built for that last-miletesting. This option allows existing installers to preview staged releases with nochanges to the installer tool required.The details of this user experience are left to installer tool maintainers.

File Upload Mechanisms

ServersMUST implementrequired file upload mechanisms.Such mechanisms serve as a fallback if no server specific implementations exist.

Each major version of the Upload APIMUST specify at least one required file upload mechanism.

New required mechanismsMUST NOT be addedand existing required mechanismsMUST NOT be removedwithout an update to themajor version.Any server-specific or experimental mechanisms added or removedMUST NOT change the major or minor version number of this specification.

Required File Upload Mechanisms

http-post-bytes

Upload API version 2.0 compliant serversMUST support thehttp-post-bytes mechanism.

This mechanismMUST use the same authentication scheme asthe rest of the Upload 2.0 protocol endpoints.

A client executes this mechanism by submitting aPOST request to thefile_urlreturned in thehttp-post-bytes map of themechanism map of thefile upload session creation response body like:

Content-Type: application/octet-stream<binary contents of the file to upload>

ServersMAY support uploading of digital attestations for files (seePEP 740).This support will be indicated by inclusion of anattestations_url key in thehttp-post-bytes map of themechanism map of thefile upload session creation response body.AttestationsMUST be uploaded to theattestations_url beforefile upload session completion.

To upload an attestation, a client submits aPOST request to theattestations_urlcontaining a JSON array ofattestation objects like:

Content-Type: application/json[{"version": 1, "verification_material": {...}, "envelope": {...}},...]

Server Specific File Upload Mechanisms

A given serverMAY implement an arbitrary number of server specific mechanismsand is responsible for documenting their usage.

A server specific implementation file upload mechanism identifier has three parts:

<prefix>-<operator identifier>-<implementation identifier>

Server specific implementationsMUST usevnd as theirprefix.TheoperatoridentifierSHOULD clearly identify the server operator,be unique from other well known indexes,and contain only alphanumeric characters[a-z0-9].TheimplementationidentifierSHOULD concisely describe the underlying implementationand contain only alphanumeric characters[a-z0-9] and-.

When server operators need to make breaking changes to their upload mechanisms,theySHOULD create a new mechanism identifier rather than modifying the existing one.The recommended pattern is to append a version suffix like-v1,-v2, etc.to the implementation identifier.This allows clients to explicitly opt into new versions while maintainingbackward compatibility with existing clients.

For example:

File Upload Mechanism stringServer OperatorMechanism description
vnd-pypi-s3multipart-presignedPyPIS3 multipart upload via pre-signed URL
vnd-pypi-s3multipart-presigned-v2PyPIS3 multipart upload via pre-signed URL version 2
vnd-pypi-http-fetchPyPIFile delivered by instructing server to fetch from a URL via HTTP request
vnd-acmecorp-http-fetchAcme CorpFile delivered by instructing server to fetch from a URL via HTTP request
vnd-acmecorp-postalAcme CorpFile delivered via postal mail
vnd-widgetinc-stream-v1Widget Inc.Streaming upload protocol version 1
vnd-widgetinc-stream-v2Widget Inc.Streaming upload protocol version 2
vnd-madscience-quantumentanglementMad Science LabsUpload via quantum entanglement

If a server intends to precisely match the behavior of another server’s implementation, itMAY respondwith that implementation’s file upload mechanism name.

FAQ

Does this mean PyPI is planning to drop support for the existing upload API?

At this time PyPI does not have any specific plans to drop support for the existing upload API.

Unlike withPEP 691 there are significant benefits to doing so, so it is likely that support forthe legacy upload API to be (responsibly) deprecated and removed at some point in the future.Such future deprecation planning is explicitly out of scope forthis PEP.

Can I use the upload 2.0 API to reserve a project name?

Yes! If you’re not ready to upload files to make a release, you can still reserve a projectname (assuming of course that the name doesn’t already exist).

To do this,create a new publishing session, thenpublish the session without uploading any files. While theversion key is required in theJSON body of the create session request, you can simply use a placeholder version number such as"0.0.0a0". The version is ignored if no artifacts are uploaded.

Generally the user that created the session will become the owner of the new project, however theindex could defineindex-specific metadata to, for example, allowan organization of which the publisher is a member, to own the new project.

Open Questions

Extensions to the Upload 2.0 Protocol

Features such as asynchronous webhook notifications for completion of upload processingwere discussed during review of this PEP.The concept of a capabilities extension for the upload protocol was discussed,which would allow implementers to advertise support for optional featuressuch as asynchronous notifications or webhooks.

This idea was left open due to the complexity that would arise in designingsuch an extension protocol and ensuring that it did not cause excessivefracturing of the ecosystem as Upload 2.0 is rolled out.

Future revisions to the upload protocol should explore such extensionsas experience is gained operating Upload 2.0.

Footnotes

[1]
Obsolete:action valuessubmit,submit_pkg_info, anddoc_upload areno longer supported
[2]
This would be fine if used as a pre-check, but the parallel metadata should bevalidated against the actualMETADATA or similar files within thedistribution.
[3]
Specifically any hash algorithm name thatcan be passed tohashlib.new() andwhich does not require additional parameters.
[4]
Published files may still be yanked (i.e.PEP 592) ordeleted as normal.

Change History

  • 06-Dec-2025
    • Error responses conform to theRFC 9457 format.
  • 23-Sep-2025
    • Remove thenonce andgentoken() algorithm. Indexes are now responsible for generatingan cryptographically secure session token and obfuscated stage URL (but only if they supportstaged previews).
    • Clarify the semantics when multiple session creation requests are received.
    • Clarify publishing session steps such as status polling and session extension.
    • Require thatname conform to the normalization rules, and include a link.
    • Require thatversion conform to the version specs, and include a link.
    • Requirefilename to conform to either the source or binary distribution file name convention, and include links.
    • Reference RFC 3399 instead of ISO 8601 as the timestamp spec. The RFC is a simpler format thatsubsets the ISO standard, and is more appropriate to our use case.
    • Other protocol clarifications.
    • Add optional index-specific metadata keys.
  • 06-Aug-2025
    • Add Dustin as the PEP Delegate.
  • 14-Apr-2025
    • Updates based on PyCon US discussions.
    • Added some error return code descriptions where they were underspecified.
    • Combine the canceling and deleting of upload files sections.
    • Simplify the rules for replacing a staged but not yet published file.
    • Add open question about deferring stage previews.
    • Fix some misspellings and poorly worded text.
  • 06-Jan-2025
    • Resurrect and update the PEP.
    • Added Barry as co-author.
    • Standardize terminology on “stage” rather than “draft”.
    • Proposed the root URL for PyPI to behttps://upload.pypi.org/2.0
    • Added an optionalnonce key for session obfuscation.
    • Standardize JSON keys and made consistent with terminology.
    • Added and modified several APIs, filling gaps and elaborating on details.
    • Align the upload protocol with draft Internet Standard.

Copyright

This document is placed in the public domain or under theCC0-1.0-Universal license, whichever is more permissive.


Source:https://github.com/python/peps/blob/main/peps/pep-0694.rst

Last modified:2025-12-07 20:33:46 GMT


[8]ページ先頭

©2009-2025 Movatter.jp