CINXE.COM

PEP 629 – Versioning PyPI’s Simple API | peps.python.org

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="color-scheme" content="light dark"> <title>PEP 629 – Versioning PyPI’s Simple API | peps.python.org</title> <link rel="shortcut icon" href="../_static/py.png"> <link rel="canonical" href="https://peps.python.org/pep-0629/"> <link rel="stylesheet" href="../_static/style.css" type="text/css"> <link rel="stylesheet" href="../_static/mq.css" type="text/css"> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light"> <link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark"> <link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss"> <meta property="og:title" content='PEP 629 – Versioning PyPI’s Simple API | peps.python.org'> <meta property="og:description" content="This PEP proposes adding a method for versioning the simple API so that clients can determine which features of the simple API that a specific repository supports."> <meta property="og:type" content="website"> <meta property="og:url" content="https://peps.python.org/pep-0629/"> <meta property="og:site_name" content="Python Enhancement Proposals (PEPs)"> <meta property="og:image" content="https://peps.python.org/_static/og-image.png"> <meta property="og:image:alt" content="Python PEPs"> <meta property="og:image:width" content="200"> <meta property="og:image:height" content="200"> <meta name="description" content="This PEP proposes adding a method for versioning the simple API so that clients can determine which features of the simple API that a specific repository supports."> <meta name="theme-color" content="#3776ab"> </head> <body> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all"> <title>Following system colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="9"></circle> <path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path> </svg> </symbol> <symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all"> <title>Selected dark colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path> </svg> </symbol> <symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all"> <title>Selected light colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="5"></circle> <line x1="12" y1="1" x2="12" y2="3"></line> <line x1="12" y1="21" x2="12" y2="23"></line> <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line> <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line> <line x1="1" y1="12" x2="3" y2="12"></line> <line x1="21" y1="12" x2="23" y2="12"></line> <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line> <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line> </svg> </symbol> </svg> <script> document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto" </script> <section id="pep-page-section"> <header> <h1>Python Enhancement Proposals</h1> <ul class="breadcrumbs"> <li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> &raquo; </li> <li><a href="../pep-0000/">PEP Index</a> &raquo; </li> <li>PEP 629</li> </ul> <button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())"> <svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg> <svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg> <svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg> <span class="visually-hidden">Toggle light / dark / auto colour theme</span> </button> </header> <article> <section id="pep-content"> <h1 class="page-title">PEP 629 – Versioning PyPI’s Simple API</h1> <dl class="rfc2822 field-list simple"> <dt class="field-odd">Author<span class="colon">:</span></dt> <dd class="field-odd">Donald Stufft &lt;donald&#32;&#97;t&#32;stufft.io&gt;</dd> <dt class="field-even">BDFL-Delegate<span class="colon">:</span></dt> <dd class="field-even">Brett Cannon &lt;brett&#32;&#97;t&#32;python.org&gt;</dd> <dt class="field-odd">Discussions-To<span class="colon">:</span></dt> <dd class="field-odd"><a class="reference external" href="https://discuss.python.org/t/pep-629-versioning-pypis-simple-api/4720">Discourse thread</a></dd> <dt class="field-even">Status<span class="colon">:</span></dt> <dd class="field-even"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd> <dt class="field-odd">Type<span class="colon">:</span></dt> <dd class="field-odd"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd> <dt class="field-even">Topic<span class="colon">:</span></dt> <dd class="field-even"><a class="reference external" href="../topic/packaging/">Packaging</a></dd> <dt class="field-odd">Created<span class="colon">:</span></dt> <dd class="field-odd">16-Jul-2020</dd> <dt class="field-even">Post-History<span class="colon">:</span></dt> <dd class="field-even">16-Jul-2020</dd> </dl> <hr class="docutils" /> <section id="contents"> <details><summary>Table of Contents</summary><ul class="simple"> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#rationale">Rationale</a></li> <li><a class="reference internal" href="#overview">Overview</a><ul> <li><a class="reference internal" href="#clients">Clients</a></li> </ul> </li> <li><a class="reference internal" href="#rejected-ideas">Rejected Ideas</a><ul> <li><a class="reference internal" href="#using-a-header">Using a Header</a></li> <li><a class="reference internal" href="#using-an-url">Using an URL</a></li> </ul> </li> <li><a class="reference internal" href="#copyright">Copyright</a></li> </ul> </details></section> <div class="admonition note"> <p class="admonition-title">Note</p> <p>This PEP was <a class="reference external" href="https://discuss.python.org/t/pep-629-versioning-pypis-simple-api/4720/15">accepted on 2020-08-20</a>. PyPI <a class="reference external" href="2bfa5a8c75e3af218494fe8de1eb809a43e3bbb9">merged an implementation</a> on 2020-01-28, marking this PEP as “Final”.</p> </div> <section id="abstract"> <h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2> <p>This PEP proposes adding a method for versioning the simple API so that clients can determine which features of the simple API that a specific repository supports.</p> </section> <section id="rationale"> <h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2> <p>When evolving the simple API, clients wish to be able to determine which features the repository supports. Currently there is no mechanism to do this, except by attempting to detect new features by looking at the data in the responses and see if it appears like a particular feature is in use.</p> <p>This works reasonably well for a modern version of a client to determine if the repository supports all of the features it wants to implement, however it does not do anything to tell an older version the client that the repository supports features that it might not understand and to allow messaging to indicate that it might not be correctly understanding the output of the repository.</p> <p>An example of a scenario where this happened was the phasing in of python-requires metadata, while existing clients could still successfully use the repository, they were lacking the ability to understand this new piece of data which would have informed their behavior to select a better file for end users.</p> </section> <section id="overview"> <h2><a class="toc-backref" href="#overview" role="doc-backlink">Overview</a></h2> <p>This PEP proposes the inclusion of a meta tag on the responses of every successful request to a simple API page, which contains a name attribute of “pypi:repository-version”, and a content that is a <a class="pep reference internal" href="../pep-0440/" title="PEP 440 – Version Identification and Dependency Specification">PEP 440</a> compatible version number, which is further constrained to ONLY be Major.Minor, and none of the additional features supported by <a class="pep reference internal" href="../pep-0440/" title="PEP 440 – Version Identification and Dependency Specification">PEP 440</a>.</p> <p>This would end up looking like:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;</span><span class="n">meta</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;pypi:repository-version&quot;</span> <span class="n">content</span><span class="o">=</span><span class="s2">&quot;1.0&quot;</span><span class="o">&gt;</span> </pre></div> </div> <p>When interpreting the repository version:</p> <ul class="simple"> <li>Incrementing the major version is used to signal a backwards incompatible change such that existing clients would no longer be expected to be able to meaningfully use the API.</li> <li>Incrementing the minor version is used to signal a backwards compatible change such that existing clients would still be expected to be able to meaningfully use the API.</li> </ul> <p>It is left up to the discretion of any future PEPs as to what specifically constitutes a backwards incompatible vs compatible change beyond the broad suggestion that existing clients will be able to “meaningfully” continue to use the API, and can include adding, modifying, or removing existing features.</p> <p>It is expectation of this PEP that the major version will never be incremented, and any future major API evolutions would utilize a different mechanism for API evolution. However the major version is included to disambiguate with future versions (e.g. a hypothetical simple api v2 that lived at /v2/, but which would be confusing if the repository-version was set to a version &gt;= 2).</p> <p>This PEP sets the current API version to “1.0”, and expects that future PEPs that further evolve the simple API will increment the minor version number.</p> <section id="clients"> <h3><a class="toc-backref" href="#clients" role="doc-backlink">Clients</a></h3> <p>Clients interacting with the simple API <strong>SHOULD</strong> introspect each response for the repository version, and if that data does not exist <strong>MUST</strong> assume that it is version 1.0.</p> <p>When encountering a major version greater than expected, clients <strong>MUST</strong> hard fail with an appropriate error message for the user.</p> <p>When encountering a minor version greater than expected, clients <strong>SHOULD</strong> warn users with an appropriate message.</p> <p>Clients <strong>MAY</strong> still continue to use feature detection in order to determine what features a repository uses.</p> </section> </section> <section id="rejected-ideas"> <h2><a class="toc-backref" href="#rejected-ideas" role="doc-backlink">Rejected Ideas</a></h2> <section id="using-a-header"> <h3><a class="toc-backref" href="#using-a-header" role="doc-backlink">Using a Header</a></h3> <p>Instead of baking this information into the actual HTML, an alternative would be to use a HTTP header. This idea was considered and ultimately was rejected because it would make mirrors have to start modifying headers instead of being able to operate as a “dumb” HTTP server of files.</p> </section> <section id="using-an-url"> <h3><a class="toc-backref" href="#using-an-url" role="doc-backlink">Using an URL</a></h3> <p>Another traditional mechanism for versioning APIs is to bake it into the URL, something like <code class="docutils literal notranslate"><span class="pre">/1.0/simple/</span></code> or so. This works well for major version changes where olders clients are not expected to be capable of continuing to use it, but it is not well suited to minor version bumps, particularly when the version numbers can be viewed as largely advisory for end users.</p> </section> </section> <section id="copyright"> <h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2> <p>This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.</p> </section> </section> <hr class="docutils" /> <p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0629.rst">https://github.com/python/peps/blob/main/peps/pep-0629.rst</a></p> <p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0629.rst">2025-02-01 08:55:40 GMT</a></p> </article> <nav id="pep-sidebar"> <h2>Contents</h2> <ul> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#rationale">Rationale</a></li> <li><a class="reference internal" href="#overview">Overview</a><ul> <li><a class="reference internal" href="#clients">Clients</a></li> </ul> </li> <li><a class="reference internal" href="#rejected-ideas">Rejected Ideas</a><ul> <li><a class="reference internal" href="#using-a-header">Using a Header</a></li> <li><a class="reference internal" href="#using-an-url">Using an URL</a></li> </ul> </li> <li><a class="reference internal" href="#copyright">Copyright</a></li> </ul> <br> <a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0629.rst">Page Source (GitHub)</a> </nav> </section> <script src="../_static/colour_scheme.js"></script> <script src="../_static/wrap_tables.js"></script> <script src="../_static/sticky_banner.js"></script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10