Legacy API#

The “Legacy API” provides feature parity with pypi-legacy, hence the term “legacy”.

Simple Project API#

The Simple API implements the HTML-based package index API as specified in PEP 503.

GET /simple/#

All of the projects that have been registered.

Example request:

GET /simple/ HTTP/1.1
Host: pypi.org
Accept: text/html

Example response:

HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
X-PyPI-Last-Serial: 871501

<!DOCTYPE html>
<html>
  <head>
    <title>Simple Index</title>
  </head>
  <body>
    <!-- More projects... -->
    <a href="/simple/warehouse/">warehouse</a>
    <!-- ...More projects -->
  </body>
</html>
Response Headers:
  • X-PyPI-Last-Serial – The most recent serial ID number for any project.

Status Codes:
GET /simple/<project>/#

Get all of the distribution download URLs for the project’s available releases (wheels and source distributions). The project is matched case-insensitively with the _, - and . characters considered equal. The links may optionally include a hash using the URL fragment. This fragment is in the form of #<hashname>=<hexdigest>. If present the downloaded file MUST be verified against that hash value. Valid hash values are md5, sha1, sha224, sha256, sha384, and sha512.

If a PGP/GPG signature for a distribution file exists in PyPI, it is available at the same URL as the file with .asc appended, but a link to that signature is not provided in this list of URLs. Therefore, once you have a wheel or sdist filename such as https://file.pythonhosted.org/.../foo-1.0.tar.gz, you can check for the existence of https://file.pythonhosted.org/.../foo-1.0.tar.gz.asc with a separate GET request.

Example request:

GET /simple/beautifulsoup4/ HTTP/1.1
Host: pypi.org
Accept: text/html

Example response:

HTTP/2 200 OK
Content-Type: text/html; charset=utf-8
Etag: "q4SqZutq1tfRDqhh3zQ4gQ"
X-PyPI-Last-Serial: 2857110

<!DOCTYPE html>
<html>
  <head>
    <title>Links for beautifulsoup4</title>
  </head>
  <body>
    <h1>Links for beautifulsoup4</h1>
    <a href="https://files.pythonhosted.org/packages/6f/be/99dcf74d947cc1e7abef5d0c4572abcb479c33ef791d94453a8fd7987d8f/beautifulsoup4-4.0.1.tar.gz#sha256=dc6bc8e8851a1c590c8cc8f25915180fdcce116e268d1f37fa991d2686ea38de">beautifulsoup4-4.0.1.tar.gz</a><br/>
    <a href="https://files.pythonhosted.org/packages/a0/75/db36172ea767dd2f0c9817a99e24f7e9b79c2ce63eb2f8b867284cc60daf/beautifulsoup4-4.0.2.tar.gz#sha256=353792f8246a9551b232949fb14dce21d9b6ced9207bf9f4a69a4c4eb46c8127">beautifulsoup4-4.0.2.tar.gz</a><br/>
    <!-- ...More files -->
    <a href="https://files.pythonhosted.org/packages/9e/d4/10f46e5cfac773e22707237bfcd51bbffeaf0a576b0a847ec7ab15bd7ace/beautifulsoup4-4.6.0-py3-none-any.whl#sha256=11a9a27b7d3bddc6d86f59fb76afb70e921a25ac2d6cc55b40d072bd68435a76">beautifulsoup4-4.6.0-py3-none-any.whl</a><br/>
    <a href="https://files.pythonhosted.org/packages/fa/8d/1d14391fdaed5abada4e0f63543fef49b8331a34ca60c88bd521bcf7f782/beautifulsoup4-4.6.0.tar.gz#sha256=808b6ac932dccb0a4126558f7dfdcf41710dd44a4ef497a0bb59a77f9f078e89">beautifulsoup4-4.6.0.tar.gz</a><br/>
    </body>
</html>
<!--SERIAL 2857110-->
Response Headers:
  • X-PyPI-Last-Serial – The most recent serial ID number for the project.

Status Codes:

Upload API#

The API endpoint served at upload.pypi.org/legacy/ is Warehouse’s emulation of the legacy PyPI upload API. This is the endpoint that tools such as twine use to upload distributions to PyPI.

The upload api can be used to upload artifacts by sending a multipart/form-data POST request with the following fields:

  • :action set to file_upload

  • protocol_version set to 1

  • content with the file to be uploaded and the proper filename (i.e. my_foo_bar-4.2-cp36-cp36m-manylinux1_x86_64.whl)

  • One of the following hash digests:
    • md5_digest set to the md5 hash of the uploaded file in urlsafe base64

    with no padding
    • sha256_digest set to the SHA2-256 hash in hexadecimal

    • blake2_256_digest set to the Blake2b 256-bit hash in hexadecimal

  • filetype set to the type of the artifact, i.e. bdist_wheel or sdist

  • When used with bdist_wheel for filetype, pyversion must be set to a specific release, i.e. cp36, when used with sdist it must be set to source

  • metadata_version, name and version set according to the Core metadata specifications

  • You can set any other field from the Core metadata specifications. All fields need to be renamed to lowercase and hyphens need to replaced by underscores. So instead of “Description-Content-Type” the field must be named “description_content_type”. Note that adding a field “Description-Content-Type” will not raise an error but will be silently ignored.

Note that uploading an artifact with a new version will automatically create that release.