CINXE.COM
Introduction - PyPI Docs
<!doctype html> <html lang="en" class="no-js"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <link rel="prev" href="../project_metadata/"> <link rel="next" href="index-api/"> <link rel="icon" href="../assets/favicon.ico"> <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.11"> <title>Introduction - PyPI Docs</title> <link rel="stylesheet" href="../assets/stylesheets/main.4af4bdda.min.css"> <link rel="stylesheet" href="../assets/stylesheets/palette.06af60db.min.css"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback"> <style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style> <link rel="stylesheet" href="../stylesheets/extra.css"> <script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script> <script async type="text/javascript" src="/_/static/javascript/readthedocs-addons.js"></script><meta name="readthedocs-project-slug" content="docspypiorg" /><meta name="readthedocs-version-slug" content="latest" /><meta name="readthedocs-resolver-filename" content="/api/" /><meta name="readthedocs-http-status" content="200" /></head> <body dir="ltr" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo"> <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off"> <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off"> <label class="md-overlay" for="__drawer"></label> <div data-md-component="skip"> <a href="#introduction" class="md-skip"> Skip to content </a> </div> <div data-md-component="announce"> </div> <header class="md-header md-header--shadow" data-md-component="header"> <nav class="md-header__inner md-grid" aria-label="Header"> <a href="https://pypi.org" title="PyPI Docs" class="md-header__button md-logo" aria-label="PyPI Docs" data-md-component="logo"> <img src="../assets/logo.png" alt="logo"> </a> <label class="md-header__button md-icon" for="__drawer"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg> </label> <div class="md-header__title" data-md-component="header-title"> <div class="md-header__ellipsis"> <div class="md-header__topic"> <span class="md-ellipsis"> PyPI Docs </span> </div> <div class="md-header__topic" data-md-component="header-topic"> <span class="md-ellipsis"> Introduction </span> </div> </div> </div> <form class="md-header__option" data-md-component="palette"> <input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to Dark mode" type="radio" name="__palette" id="__palette_0"> <label class="md-header__button md-icon" title="Switch to Dark mode" for="__palette_1" hidden> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3zm3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95zm-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31"/></svg> </label> <input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to Light mode" type="radio" name="__palette" id="__palette_1"> <label class="md-header__button md-icon" title="Switch to Light mode" for="__palette_0" hidden> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5s-1.65.15-2.39.42zM3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29zm.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14zM20.65 7l-1.77 3.79a7.02 7.02 0 0 0-2.38-4.15zm-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29zM12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44z"/></svg> </label> </form> <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script> <label class="md-header__button md-icon" for="__search"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg> </label> <div class="md-search" data-md-component="search" role="dialog"> <label class="md-search__overlay" for="__search"></label> <div class="md-search__inner" role="search"> <form class="md-search__form" name="search"> <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required> <label class="md-search__icon md-icon" for="__search"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg> </label> <nav class="md-search__options" aria-label="Search"> <button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg> </button> </nav> </form> <div class="md-search__output"> <div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix> <div class="md-search-result" data-md-component="search-result"> <div class="md-search-result__meta"> Initializing search </div> <ol class="md-search-result__list" role="presentation"></ol> </div> </div> </div> </div> </div> <div class="md-header__source"> <a href="https://github.com/pypi/warehouse" title="Go to repository" class="md-source" data-md-component="source"> <div class="md-source__icon md-icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg> </div> <div class="md-source__repository"> GitHub </div> </a> </div> </nav> </header> <div class="md-container" data-md-component="container"> <main class="md-main" data-md-component="main"> <div class="md-main__inner md-grid"> <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" > <div class="md-sidebar__scrollwrap"> <div class="md-sidebar__inner"> <nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0"> <label class="md-nav__title" for="__drawer"> <a href="https://pypi.org" title="PyPI Docs" class="md-nav__button md-logo" aria-label="PyPI Docs" data-md-component="logo"> <img src="../assets/logo.png" alt="logo"> </a> PyPI Docs </label> <div class="md-nav__source"> <a href="https://github.com/pypi/warehouse" title="Go to repository" class="md-source" data-md-component="source"> <div class="md-source__icon md-icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg> </div> <div class="md-source__repository"> GitHub </div> </a> </div> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href=".." class="md-nav__link"> <span class="md-ellipsis"> Welcome to PyPI User Documentation </span> </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" > <label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0"> <span class="md-ellipsis"> Project Management </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_2"> <span class="md-nav__icon md-icon"></span> Project Management </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../project-management/storage-limits/" class="md-nav__link"> <span class="md-ellipsis"> Storage Limits </span> </a> </li> <li class="md-nav__item"> <a href="../project-management/yanking/" class="md-nav__link"> <span class="md-ellipsis"> Yanking </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" > <label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0"> <span class="md-ellipsis"> Organization Accounts </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_3"> <span class="md-nav__icon md-icon"></span> Organization Accounts </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../organization-accounts/" class="md-nav__link"> <span class="md-ellipsis"> About </span> </a> </li> <li class="md-nav__item"> <a href="../organization-accounts/org-acc-faq/" class="md-nav__link"> <span class="md-ellipsis"> FAQs </span> </a> </li> <li class="md-nav__item"> <a href="../organization-accounts/roles-entities/" class="md-nav__link"> <span class="md-ellipsis"> Roles and Entities </span> </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_4" > <label class="md-nav__link" for="__nav_3_4" id="__nav_3_4_label" tabindex="0"> <span class="md-ellipsis"> Actions </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_4_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_3_4"> <span class="md-nav__icon md-icon"></span> Actions </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../organization-accounts/actions/billing-actions/" class="md-nav__link"> <span class="md-ellipsis"> Billing Actions </span> </a> </li> <li class="md-nav__item"> <a href="../organization-accounts/actions/org-actions/" class="md-nav__link"> <span class="md-ellipsis"> Organization Actions </span> </a> </li> <li class="md-nav__item"> <a href="../organization-accounts/actions/project-actions/" class="md-nav__link"> <span class="md-ellipsis"> Project Actions </span> </a> </li> <li class="md-nav__item"> <a href="../organization-accounts/actions/team-actions/" class="md-nav__link"> <span class="md-ellipsis"> Team Actions </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="../organization-accounts/pricing-and-payments/" class="md-nav__link"> <span class="md-ellipsis"> Pricing and Payments </span> </a> </li> <li class="md-nav__item"> <a href="../organization-accounts/support/" class="md-nav__link"> <span class="md-ellipsis"> Support </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" > <label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0"> <span class="md-ellipsis"> Trusted Publishers </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_4"> <span class="md-nav__icon md-icon"></span> Trusted Publishers </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../trusted-publishers/" class="md-nav__link"> <span class="md-ellipsis"> Getting Started </span> </a> </li> <li class="md-nav__item"> <a href="../trusted-publishers/adding-a-publisher/" class="md-nav__link"> <span class="md-ellipsis"> Adding a Trusted Publisher to an Existing PyPI Project </span> </a> </li> <li class="md-nav__item"> <a href="../trusted-publishers/creating-a-project-through-oidc/" class="md-nav__link"> <span class="md-ellipsis"> Creating a PyPI Project with a Trusted Publisher </span> </a> </li> <li class="md-nav__item"> <a href="../trusted-publishers/using-a-publisher/" class="md-nav__link"> <span class="md-ellipsis"> Publishing with a Trusted Publisher </span> </a> </li> <li class="md-nav__item"> <a href="../trusted-publishers/security-model/" class="md-nav__link"> <span class="md-ellipsis"> Security Model and Considerations </span> </a> </li> <li class="md-nav__item"> <a href="../trusted-publishers/troubleshooting/" class="md-nav__link"> <span class="md-ellipsis"> Troubleshooting </span> </a> </li> <li class="md-nav__item"> <a href="../trusted-publishers/internals/" class="md-nav__link"> <span class="md-ellipsis"> Internals and Technical Details </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" > <label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0"> <span class="md-ellipsis"> Digital Attestations </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false"> <label class="md-nav__title" for="__nav_5"> <span class="md-nav__icon md-icon"></span> Digital Attestations </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../attestations/" class="md-nav__link"> <span class="md-ellipsis"> Introduction </span> </a> </li> <li class="md-nav__item"> <a href="../attestations/producing-attestations/" class="md-nav__link"> <span class="md-ellipsis"> Producing attestations </span> </a> </li> <li class="md-nav__item"> <a href="../attestations/consuming-attestations/" class="md-nav__link"> <span class="md-ellipsis"> Consuming attestations </span> </a> </li> <li class="md-nav__item"> <a href="../attestations/publish/v1/" class="md-nav__link"> <span class="md-ellipsis"> PyPI Publish Attestation (v1) </span> </a> </li> <li class="md-nav__item"> <a href="../attestations/security-model/" class="md-nav__link"> <span class="md-ellipsis"> Security Model and Considerations </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="../project_metadata/" class="md-nav__link"> <span class="md-ellipsis"> Project Metadata </span> </a> </li> <li class="md-nav__item md-nav__item--active md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_7" checked> <label class="md-nav__link" for="__nav_7" id="__nav_7_label" tabindex="0"> <span class="md-ellipsis"> APIs and Datasets </span> <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_7_label" aria-expanded="true"> <label class="md-nav__title" for="__nav_7"> <span class="md-nav__icon md-icon"></span> APIs and Datasets </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item md-nav__item--active"> <input class="md-nav__toggle md-toggle" type="checkbox" id="__toc"> <label class="md-nav__link md-nav__link--active" for="__toc"> <span class="md-ellipsis"> Introduction </span> <span class="md-nav__icon md-icon"></span> </label> <a href="./" class="md-nav__link md-nav__link--active"> <span class="md-ellipsis"> Introduction </span> </a> <nav class="md-nav md-nav--secondary" aria-label="Table of contents"> <label class="md-nav__title" for="__toc"> <span class="md-nav__icon md-icon"></span> Table of contents </label> <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix> <li class="md-nav__item"> <a href="#api-policies" class="md-nav__link"> <span class="md-ellipsis"> API policies </span> </a> <nav class="md-nav" aria-label="API policies"> <ul class="md-nav__list"> <li class="md-nav__item"> <a href="#caching" class="md-nav__link"> <span class="md-ellipsis"> Caching </span> </a> </li> <li class="md-nav__item"> <a href="#rate-limiting" class="md-nav__link"> <span class="md-ellipsis"> Rate limiting </span> </a> </li> <li class="md-nav__item"> <a href="#api-preference" class="md-nav__link"> <span class="md-ellipsis"> API Preference </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="#integration-guide" class="md-nav__link"> <span class="md-ellipsis"> Integration guide </span> </a> <nav class="md-nav" aria-label="Integration guide"> <ul class="md-nav__list"> <li class="md-nav__item"> <a href="#querying-pypi-for-package-urls" class="md-nav__link"> <span class="md-ellipsis"> Querying PyPI for Package URLs </span> </a> </li> <li class="md-nav__item"> <a href="#official-guidance" class="md-nav__link"> <span class="md-ellipsis"> Official guidance </span> </a> </li> <li class="md-nav__item"> <a href="#predictable-urls" class="md-nav__link"> <span class="md-ellipsis"> Predictable URLs </span> </a> </li> </ul> </nav> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="index-api/" class="md-nav__link"> <span class="md-ellipsis"> Index API </span> </a> </li> <li class="md-nav__item"> <a href="json/" class="md-nav__link"> <span class="md-ellipsis"> JSON API </span> </a> </li> <li class="md-nav__item"> <a href="upload/" class="md-nav__link"> <span class="md-ellipsis"> Upload API </span> </a> </li> <li class="md-nav__item"> <a href="integrity/" class="md-nav__link"> <span class="md-ellipsis"> Integrity API </span> </a> </li> <li class="md-nav__item"> <a href="stats/" class="md-nav__link"> <span class="md-ellipsis"> Stats API </span> </a> </li> <li class="md-nav__item"> <a href="bigquery/" class="md-nav__link"> <span class="md-ellipsis"> BigQuery Datasets </span> </a> </li> <li class="md-nav__item"> <a href="feeds/" class="md-nav__link"> <span class="md-ellipsis"> RSS Feeds </span> </a> </li> <li class="md-nav__item"> <a href="secrets/" class="md-nav__link"> <span class="md-ellipsis"> Secret reporting API </span> </a> </li> </ul> </nav> </li> </ul> </nav> </div> </div> </div> <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" > <div class="md-sidebar__scrollwrap"> <div class="md-sidebar__inner"> <nav class="md-nav md-nav--secondary" aria-label="Table of contents"> <label class="md-nav__title" for="__toc"> <span class="md-nav__icon md-icon"></span> Table of contents </label> <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix> <li class="md-nav__item"> <a href="#api-policies" class="md-nav__link"> <span class="md-ellipsis"> API policies </span> </a> <nav class="md-nav" aria-label="API policies"> <ul class="md-nav__list"> <li class="md-nav__item"> <a href="#caching" class="md-nav__link"> <span class="md-ellipsis"> Caching </span> </a> </li> <li class="md-nav__item"> <a href="#rate-limiting" class="md-nav__link"> <span class="md-ellipsis"> Rate limiting </span> </a> </li> <li class="md-nav__item"> <a href="#api-preference" class="md-nav__link"> <span class="md-ellipsis"> API Preference </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="#integration-guide" class="md-nav__link"> <span class="md-ellipsis"> Integration guide </span> </a> <nav class="md-nav" aria-label="Integration guide"> <ul class="md-nav__list"> <li class="md-nav__item"> <a href="#querying-pypi-for-package-urls" class="md-nav__link"> <span class="md-ellipsis"> Querying PyPI for Package URLs </span> </a> </li> <li class="md-nav__item"> <a href="#official-guidance" class="md-nav__link"> <span class="md-ellipsis"> Official guidance </span> </a> </li> <li class="md-nav__item"> <a href="#predictable-urls" class="md-nav__link"> <span class="md-ellipsis"> Predictable URLs </span> </a> </li> </ul> </nav> </li> </ul> </nav> </div> </div> </div> <div class="md-content" data-md-component="content"> <article class="md-content__inner md-typeset"> <a href="https://github.com/pypi/warehouse/blob/main/docs/user/api/index.md" title="Edit this page" class="md-content__button md-icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20H6V4h7v5h5v3.1l2-2V8l-6-6H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h4zm10.2-7c.1 0 .3.1.4.2l1.3 1.3c.2.2.2.6 0 .8l-1 1-2.1-2.1 1-1c.1-.1.2-.2.4-.2m0 3.9L14.1 23H12v-2.1l6.1-6.1z"/></svg> </a> <h1 id="introduction">Introduction</h1> <p>PyPI has several API endpoints and public datasets, each of which is referenced in the table of contents for this hierarchy.</p> <h2 id="api-policies">API policies</h2> <p>Please be aware of these PyPI API policies.</p> <h3 id="caching">Caching</h3> <p>All API requests are cached. Requests to the JSON, RSS or Index APIs are cached by our CDN provider. You can determine if you've hit the cache based on the <code>X-Cache</code> and <code>X-Cache-Hits</code> headers in the response.</p> <p>Requests to the JSON, RSS and Index APIs also provide an <code>ETag</code> header. If you're making a lot of repeated requests, ensure your API consumer will respect this header to determine whether to actually repeat a request or not.</p> <p>The XML-RPC API does not have the ability to indicate cached responses.</p> <h3 id="rate-limiting">Rate limiting</h3> <p>Due to the heavy caching and CDN use, there is currently no rate limiting of PyPI APIs at the edge. The XML-RPC API may be rate limited if usage is causing degradation of service.</p> <p>In addition, PyPI reserves the right to temporarily or permanently prohibit a consumer based on irresponsible activity.</p> <p>If you plan to make a lot of requests to a PyPI API, adhere to these suggestions:</p> <ul> <li>Set your consumer's <code>User-Agent</code> header to uniquely identify your requests. Adding your contact information to this value would be helpful as well.</li> <li>Try not to make a lot of requests (thousands) in a short amount of time (minutes). Generally PyPI can handle it, but it's preferred to make requests in serial over a longer amount of time if possible.</li> <li>If your consumer is actually an organization or service that will be downloading a lot of packages from PyPI, consider <a href="https://packaging.python.org/guides/index-mirrors-and-caches/">using your own index mirror or cache</a>.</li> </ul> <h3 id="api-preference">API Preference</h3> <p>For periodically checking for new packages or updates to existing packages, use our <a href="feeds/">RSS feeds</a>.</p> <p>No new integrations should use the XML-RPC APIs as they are planned for deprecation. Existing consumers should migrate to JSON/RSS/<a href="index-api/">Index APIs</a>.</p> <h2 id="integration-guide">Integration guide</h2> <p>Many tools already integrate with PyPI, uploading packages or retrieving data; see <a href="https://packaging.python.org/guides/tool-recommendations/">the Python Packaging Guide's tool recommendations</a>.</p> <h3 id="querying-pypi-for-package-urls">Querying PyPI for Package URLs</h3> <p>When copying a download link from <a href="https://pypi.org">https://pypi.org</a>, you get a URL with a random hash value in it.</p> <p>This hash value is calculated from the checksum of the file. The URLs on PyPI for individual files are static and do not change.</p> <h3 id="official-guidance">Official guidance</h3> <p>Query PyPI's <a href="index-api/">Index API</a> or <a href="json/">JSON API</a> to determine where to download files from.</p> <h3 id="predictable-urls">Predictable URLs</h3> <p>You can use our conveyor service to fetch this file, which exists for cases where using the API is impractical or impossible. This is for example the case for Linux package maintainers, as package build scripts or package metadata expect static URLs in some cases.</p> <p>URLs can be constructed as follows, with wheel file names following <a href="https://peps.python.org/pep-0491/#file-name-convention">PEP 491's file name convention</a>.</p> <div class="highlight"><pre><span></span><code><span class="n">host</span> <span class="o">=</span> <span class="s1">'https://files.pythonhosted.org'</span> <span class="k">def</span><span class="w"> </span><span class="nf">source_url</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">version</span><span class="p">):</span> <span class="k">return</span> <span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="n">host</span><span class="si">}</span><span class="s1">/packages/source/</span><span class="si">{</span><span class="n">name</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="si">}</span><span class="s1">/</span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s1">/</span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s1">-</span><span class="si">{</span><span class="n">version</span><span class="si">}</span><span class="s1">.tar.gz'</span> <span class="k">def</span><span class="w"> </span><span class="nf">wheel_url</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">version</span><span class="p">,</span> <span class="n">build_tag</span><span class="p">,</span> <span class="n">python_tag</span><span class="p">,</span> <span class="n">abi_tag</span><span class="p">,</span> <span class="n">platform_tag</span><span class="p">):</span> <span class="c1"># https://www.python.org/dev/peps/pep-0491/#file-name-convention</span> <span class="n">wheel_parts</span> <span class="o">=</span> <span class="p">{</span> <span class="n">tag</span><span class="p">:</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s1">'[^\w\d.]+'</span><span class="p">,</span> <span class="s1">'_'</span><span class="p">,</span> <span class="n">part</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">UNICODE</span><span class="p">)</span> <span class="k">for</span> <span class="n">tag</span><span class="p">,</span> <span class="n">part</span> <span class="ow">in</span> <span class="nb">locals</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="p">}</span> <span class="n">wheel_parts</span><span class="p">[</span><span class="s1">'optional_build_tag'</span><span class="p">]</span> <span class="o">=</span> <span class="sa">f</span><span class="s1">'-</span><span class="si">{</span><span class="n">wheel_parts</span><span class="p">[</span><span class="s2">"build_tag"</span><span class="p">]</span><span class="si">}</span><span class="s1">'</span> <span class="k">if</span> <span class="n">build_tag</span> <span class="k">else</span> <span class="s1">''</span> <span class="n">filename</span> <span class="o">=</span> <span class="s1">'</span><span class="si">{name}</span><span class="s1">-</span><span class="si">{version}{optional_build_tag}</span><span class="s1">-</span><span class="si">{python_tag}</span><span class="s1">-</span><span class="si">{abi_tag}</span><span class="s1">-</span><span class="si">{platform_tag}</span><span class="s1">.whl'</span>\ <span class="o">.</span><span class="n">format_map</span><span class="p">(</span><span class="n">wheel_parts</span><span class="p">)</span> <span class="k">return</span> <span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="n">host</span><span class="si">}</span><span class="s1">/packages/</span><span class="si">{</span><span class="n">python_tag</span><span class="si">}</span><span class="s1">/</span><span class="si">{</span><span class="n">name</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="si">}</span><span class="s1">/</span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s1">/</span><span class="si">{</span><span class="n">filename</span><span class="si">}</span><span class="s1">'</span> </code></pre></div> <p>Example predicable URL use:</p> <div class="highlight"><pre><span></span><code>$<span class="w"> </span>curl<span class="w"> </span>-I<span class="w"> </span>https://files.pythonhosted.org/packages/source/v/virtualenv/virtualenv-15.2.0.tar.gz HTTP/2<span class="w"> </span><span class="m">302</span> location:<span class="w"> </span>https://files.pythonhosted.org/packages/b1/72/2d70c5a1de409ceb3a27ff2ec007ecdd5cc52239e7c74990e32af57affe9/virtualenv-15.2.0.tar.gz </code></pre></div> <p>As you鈥檒l note, it is just a redirect to the canonical file.</p> </article> </div> <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script> </div> </main> <footer class="md-footer"> <div class="md-footer-meta md-typeset"> <div class="md-footer-meta__inner md-grid"> <div class="md-copyright"> Made with <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener"> Material for MkDocs </a> </div> <div class="md-social"> <a href="https://github.com/pypi" target="_blank" rel="noopener" title="github.com" class="md-social__link"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg> </a> <a href="https://twitter.com/pypi" target="_blank" rel="noopener" title="twitter.com" class="md-social__link"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253"/></svg> </a> </div> </div> </div> </footer> </div> <div class="md-dialog" data-md-component="dialog"> <div class="md-dialog__inner md-typeset"></div> </div> <script id="__config" type="application/json">{"base": "..", "features": ["content.action.edit"], "search": "../assets/javascripts/workers/search.f8cc74c7.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script> <script src="../assets/javascripts/bundle.c8b220af.min.js"></script> </body> </html>