CINXE.COM
PEP 243 – Module Repository Upload Mechanism | 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 243 – Module Repository Upload Mechanism | peps.python.org</title> <link rel="shortcut icon" href="../_static/py.png"> <link rel="canonical" href="https://peps.python.org/pep-0243/"> <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 243 – Module Repository Upload Mechanism | peps.python.org'> <meta property="og:description" content="For a module repository system (such as Perl’s CPAN) to be successful, it must be as easy as possible for module authors to submit their work. An obvious place for this submit to happen is in the Distutils tools after the distribution archive has been ..."> <meta property="og:type" content="website"> <meta property="og:url" content="https://peps.python.org/pep-0243/"> <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="For a module repository system (such as Perl’s CPAN) to be successful, it must be as easy as possible for module authors to submit their work. An obvious place for this submit to happen is in the Distutils tools after the distribution archive has been ..."> <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> » </li> <li><a href="../pep-0000/">PEP Index</a> » </li> <li>PEP 243</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 243 – Module Repository Upload Mechanism</h1> <dl class="rfc2822 field-list simple"> <dt class="field-odd">Author<span class="colon">:</span></dt> <dd class="field-odd">Sean Reifschneider <jafo-pep at tummy.com></dd> <dt class="field-even">Discussions-To<span class="colon">:</span></dt> <dd class="field-even"><a class="reference external" href="https://mail.python.org/archives/list/distutils-sig@python.org/">Distutils-SIG list</a></dd> <dt class="field-odd">Status<span class="colon">:</span></dt> <dd class="field-odd"><abbr title="Removed from consideration by sponsor or authors">Withdrawn</abbr></dd> <dt class="field-even">Type<span class="colon">:</span></dt> <dd class="field-even"><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-odd">Topic<span class="colon">:</span></dt> <dd class="field-odd"><a class="reference external" href="../topic/packaging/">Packaging</a></dd> <dt class="field-even">Created<span class="colon">:</span></dt> <dd class="field-even">18-Mar-2001</dd> <dt class="field-odd">Python-Version<span class="colon">:</span></dt> <dd class="field-odd">2.1</dd> <dt class="field-even">Post-History<span class="colon">:</span></dt> <dd class="field-even">20-Mar-2001, 24-Mar-2001</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="#upload-process">Upload Process</a></li> <li><a class="reference internal" href="#return-data">Return Data</a></li> <li><a class="reference internal" href="#sample-form">Sample Form</a></li> <li><a class="reference internal" href="#platforms">Platforms</a></li> <li><a class="reference internal" href="#status">Status</a></li> <li><a class="reference internal" href="#copyright">Copyright</a></li> </ul> </details></section> <section id="abstract"> <h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2> <p>For a module repository system (such as Perl’s CPAN) to be successful, it must be as easy as possible for module authors to submit their work. An obvious place for this submit to happen is in the Distutils tools after the distribution archive has been successfully created. For example, after a module author has tested their software (verifying the results of <code class="docutils literal notranslate"><span class="pre">setup.py</span> <span class="pre">sdist</span></code>), they might type <code class="docutils literal notranslate"><span class="pre">setup.py</span> <span class="pre">sdist</span> <span class="pre">--submit</span></code>. This would flag Distutils to submit the source distribution to the archive server for inclusion and distribution to the mirrors.</p> <p>This PEP only deals with the mechanism for submitting the software distributions to the archive, and does not deal with the actual archive/catalog server.</p> </section> <section id="upload-process"> <h2><a class="toc-backref" href="#upload-process" role="doc-backlink">Upload Process</a></h2> <p>The upload will include the Distutils <code class="docutils literal notranslate"><span class="pre">PKG-INFO</span></code> meta-data information (as specified in <a class="pep reference internal" href="../pep-0241/" title="PEP 241 – Metadata for Python Software Packages">PEP 241</a>), the actual software distribution, and other optional information. This information will be uploaded as a multi-part form encoded the same as a regular HTML file upload request. This form is posted using <code class="docutils literal notranslate"><span class="pre">ENCTYPE="multipart/form-data"</span></code> encoding (<span class="target" id="index-0"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc1867.html"><strong>RFC 1867</strong></a>).</p> <p>The upload will be made to the host “www.python.org” on port 80/tcp (<code class="docutils literal notranslate"><span class="pre">POST</span> <span class="pre">http://www.python.org:80/pypi</span></code>). The form will consist of the following fields:</p> <ul class="simple"> <li><code class="docutils literal notranslate"><span class="pre">distribution</span></code> – The file containing the module software (for example, a <code class="docutils literal notranslate"><span class="pre">.tar.gz</span></code> or <code class="docutils literal notranslate"><span class="pre">.zip</span></code> file).</li> <li><code class="docutils literal notranslate"><span class="pre">distmd5sum</span></code> – The MD5 hash of the uploaded distribution, encoded in ASCII representing the hexadecimal representation of the digest (<code class="docutils literal notranslate"><span class="pre">for</span> <span class="pre">byte</span> <span class="pre">in</span> <span class="pre">digest:</span> <span class="pre">s</span> <span class="pre">=</span> <span class="pre">s</span> <span class="pre">+</span> <span class="pre">('%02x'</span> <span class="pre">%</span> <span class="pre">ord(byte))</span></code>).</li> <li><code class="docutils literal notranslate"><span class="pre">pkginfo</span></code> (optional) – The file containing the distribution meta-data (as specified in <a class="pep reference internal" href="../pep-0241/" title="PEP 241 – Metadata for Python Software Packages">PEP 241</a>). Note that if this is not included, the distribution file is expected to be in <code class="docutils literal notranslate"><span class="pre">.tar</span></code> format (gzipped and bzipped compressed are allowed) or <code class="docutils literal notranslate"><span class="pre">.zip</span></code> format, with a <code class="docutils literal notranslate"><span class="pre">PKG-INFO</span></code> file in the top-level directory it extracts (<code class="docutils literal notranslate"><span class="pre">package-1.00/PKG-INFO</span></code>).</li> <li><code class="docutils literal notranslate"><span class="pre">infomd5sum</span></code> (required if pkginfo field is present) – The MD5 hash of the uploaded meta-data, encoded in ASCII representing the hexadecimal representation of the digest (<code class="docutils literal notranslate"><span class="pre">for</span> <span class="pre">byte</span> <span class="pre">in</span> <span class="pre">digest:</span> <span class="pre">s</span> <span class="pre">=</span> <span class="pre">s</span> <span class="pre">+</span> <span class="pre">('%02x'</span> <span class="pre">%</span> <span class="pre">ord(byte))</span></code>).</li> <li><code class="docutils literal notranslate"><span class="pre">platform</span></code> (optional) – A string representing the target platform for this distribution. This is only for binary distributions. It is encoded as <code class="docutils literal notranslate"><span class="pre"><os_name>-<os_version>-<platform</span> <span class="pre">architecture>-<python</span> <span class="pre">version></span></code>.</li> <li><code class="docutils literal notranslate"><span class="pre">signature</span></code> (optional) – A <span class="target" id="index-1"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc2440.html"><strong>OpenPGP-compatible</strong></a> signature of the uploaded distribution as signed by the author. This may be used by the cataloging system to automate acceptance of uploads.</li> <li><code class="docutils literal notranslate"><span class="pre">protocol_version</span></code> – A string indicating the protocol version that the client supports. This document describes protocol version “1”.</li> </ul> </section> <section id="return-data"> <h2><a class="toc-backref" href="#return-data" role="doc-backlink">Return Data</a></h2> <p>The status of the upload will be reported using HTTP non-standard (<code class="docutils literal notranslate"><span class="pre">X-*</span></code>) headers. The <code class="docutils literal notranslate"><span class="pre">X-Swalow-Status</span></code> header may have the following values:</p> <ul class="simple"> <li><code class="docutils literal notranslate"><span class="pre">SUCCESS</span></code> – Indicates that the upload has succeeded.</li> <li><code class="docutils literal notranslate"><span class="pre">FAILURE</span></code> – The upload is, for some reason, unable to be processed.</li> <li><code class="docutils literal notranslate"><span class="pre">TRYAGAIN</span></code> – The server is unable to accept the upload at this time, but the client should try again at a later time. Potential causes of this are resource shortages on the server, administrative down-time, etc…</li> </ul> <p>Optionally, there may be a <code class="docutils literal notranslate"><span class="pre">X-Swalow-Reason</span></code> header which includes a human-readable string which provides more detailed information about the <code class="docutils literal notranslate"><span class="pre">X-Swalow-Status</span></code>.</p> <p>If there is no <code class="docutils literal notranslate"><span class="pre">X-Swalow-Status</span></code> header, or it does not contain one of the three strings above, it should be treated as a temporary failure.</p> <p>Example:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">f</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="s1">'http://www.python.org:80/pypi'</span><span class="p">)</span> <span class="gp">>>> </span><span class="n">s</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s1">'x-swalow-status'</span><span class="p">]</span> <span class="gp">>>> </span><span class="n">s</span> <span class="o">=</span> <span class="n">s</span> <span class="o">+</span> <span class="s1">': '</span> <span class="o">+</span> <span class="n">f</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'x-swalow-reason'</span><span class="p">,</span> <span class="s1">'<None>'</span><span class="p">)</span> <span class="gp">>>> </span><span class="nb">print</span> <span class="n">s</span> <span class="go">FAILURE: Required field "distribution" missing.</span> </pre></div> </div> </section> <section id="sample-form"> <h2><a class="toc-backref" href="#sample-form" role="doc-backlink">Sample Form</a></h2> <p>The upload client must submit the page in the same form as Netscape Navigator version 4.76 for Linux produces when presented with the following form:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o"><</span><span class="n">H1</span><span class="o">></span><span class="n">Upload</span> <span class="n">file</span><span class="o"></</span><span class="n">H1</span><span class="o">></span> <span class="o"><</span><span class="n">FORM</span> <span class="n">NAME</span><span class="o">=</span><span class="s2">"fileupload"</span> <span class="n">METHOD</span><span class="o">=</span><span class="s2">"POST"</span> <span class="n">ACTION</span><span class="o">=</span><span class="s2">"pypi"</span> <span class="n">ENCTYPE</span><span class="o">=</span><span class="s2">"multipart/form-data"</span><span class="o">></span> <span class="o"><</span><span class="n">INPUT</span> <span class="n">TYPE</span><span class="o">=</span><span class="s2">"file"</span> <span class="n">NAME</span><span class="o">=</span><span class="s2">"distribution"</span><span class="o">><</span><span class="n">BR</span><span class="o">></span> <span class="o"><</span><span class="n">INPUT</span> <span class="n">TYPE</span><span class="o">=</span><span class="s2">"text"</span> <span class="n">NAME</span><span class="o">=</span><span class="s2">"distmd5sum"</span><span class="o">><</span><span class="n">BR</span><span class="o">></span> <span class="o"><</span><span class="n">INPUT</span> <span class="n">TYPE</span><span class="o">=</span><span class="s2">"file"</span> <span class="n">NAME</span><span class="o">=</span><span class="s2">"pkginfo"</span><span class="o">><</span><span class="n">BR</span><span class="o">></span> <span class="o"><</span><span class="n">INPUT</span> <span class="n">TYPE</span><span class="o">=</span><span class="s2">"text"</span> <span class="n">NAME</span><span class="o">=</span><span class="s2">"infomd5sum"</span><span class="o">><</span><span class="n">BR</span><span class="o">></span> <span class="o"><</span><span class="n">INPUT</span> <span class="n">TYPE</span><span class="o">=</span><span class="s2">"text"</span> <span class="n">NAME</span><span class="o">=</span><span class="s2">"platform"</span><span class="o">><</span><span class="n">BR</span><span class="o">></span> <span class="o"><</span><span class="n">INPUT</span> <span class="n">TYPE</span><span class="o">=</span><span class="s2">"text"</span> <span class="n">NAME</span><span class="o">=</span><span class="s2">"signature"</span><span class="o">><</span><span class="n">BR</span><span class="o">></span> <span class="o"><</span><span class="n">INPUT</span> <span class="n">TYPE</span><span class="o">=</span><span class="s2">"hidden"</span> <span class="n">NAME</span><span class="o">=</span><span class="s2">"protocol_version"</span> <span class="n">VALUE</span><span class="o">=</span><span class="s2">"1"</span><span class="o">><</span><span class="n">BR</span><span class="o">></span> <span class="o"><</span><span class="n">INPUT</span> <span class="n">TYPE</span><span class="o">=</span><span class="s2">"SUBMIT"</span> <span class="n">VALUE</span><span class="o">=</span><span class="s2">"Upload"</span><span class="o">></span> <span class="o"></</span><span class="n">FORM</span><span class="o">></span> </pre></div> </div> </section> <section id="platforms"> <h2><a class="toc-backref" href="#platforms" role="doc-backlink">Platforms</a></h2> <p>The following are valid os names:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">aix</span> <span class="n">beos</span> <span class="n">debian</span> <span class="n">dos</span> <span class="n">freebsd</span> <span class="n">hpux</span> <span class="n">mac</span> <span class="n">macos</span> <span class="n">mandrake</span> <span class="n">netbsd</span> <span class="n">openbsd</span> <span class="n">qnx</span> <span class="n">redhat</span> <span class="n">solaris</span> <span class="n">suse</span> <span class="n">windows</span> <span class="n">yellowdog</span> </pre></div> </div> <p>The above include a number of different types of distributions of Linux. Because of versioning issues these must be split out, and it is expected that when it makes sense for one system to use distributions made on other similar systems, the download client will make the distinction.</p> <p>Version is the official version string specified by the vendor for the particular release. For example, “2000” and “nt” (Windows), “9.04” (HP-UX), “7.0” (RedHat, Mandrake).</p> <p>The following are valid architectures:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">alpha</span> <span class="n">hppa</span> <span class="n">ix86</span> <span class="n">powerpc</span> <span class="n">sparc</span> <span class="n">ultrasparc</span> </pre></div> </div> </section> <section id="status"> <h2><a class="toc-backref" href="#status" role="doc-backlink">Status</a></h2> <p>I currently have a proof-of-concept client and server implemented. I plan to have the Distutils patches ready for the 2.1 release. Combined with Andrew’s <a class="pep reference internal" href="../pep-0241/" title="PEP 241 – Metadata for Python Software Packages">PEP 241</a> for specifying distribution meta-data, I hope to have a platform which will allow us to gather real-world data for finalizing the catalog system for the 2.2 release.</p> </section> <section id="copyright"> <h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2> <p>This document has been placed in the public domain.</p> </section> </section> <hr class="docutils" /> <p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0243.rst">https://github.com/python/peps/blob/main/peps/pep-0243.rst</a></p> <p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0243.rst">2023-09-09 17:39:29 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="#upload-process">Upload Process</a></li> <li><a class="reference internal" href="#return-data">Return Data</a></li> <li><a class="reference internal" href="#sample-form">Sample Form</a></li> <li><a class="reference internal" href="#platforms">Platforms</a></li> <li><a class="reference internal" href="#status">Status</a></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-0243.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>