
A Python build can run successfully for months, then fail on a clean machine even though the application code has not changed. A pinned package may have disappeared from PyPI, or an unpinned dependency may now resolve to a different version.
A PyPI mirror can help, but the result depends on what it stores. A synchronized copy, a caching proxy, and a historical mirror serve different purposes. This guide explains those differences, how to configure pip, uv, and Poetry, and where a mirror fits alongside lockfiles.
A PyPI mirror provides an alternative source for packages distributed through the Python Package Index. Teams use mirrors and caches to reduce repeated downloads, support offline work, or manage access to public packages.
Python installers can use a compatible package index instead of public PyPI. With pip, the --index-url option changes the index used for installation:
pip install \
--index-url https://mirror.example.com/simple/ \
requests
The command alone does not tell you whether the server synchronizes all packages, caches requested files, or preserves historical repository states. Check those behaviors before choosing a mirror for your builds.
A full synchronized mirror copies index data and package files from upstream. It can provide a local source for installations, including offline use when all required files are present.
A PyPI cache mirror retrieves package files as clients request them and stores them for reuse. Its retention and refresh policies determine whether older files remain accessible.
A historical mirror preserves past index states so dependency resolution can use a chosen repository date. Package-file retention is a separate part of that service and should be checked alongside its snapshot coverage.
A top-level version pin does not necessarily fix the versions of every dependency. For example:
onnx==1.14.0
That release depends on other packages, including a protobuf requirement with a lower bound rather than an exact version. Without a complete lock, installing the same top-level requirement later can select different compatible dependency versions.
Lockfiles address much of this resolution problem by recording the dependency set. They do not preserve the package files themselves. If a recorded distribution disappears from the repository, an exact version pin may still be impossible to download.
StableBuild’s public Deleted PyPI Package Index lists packages and versions removed from PyPI. It provides a concrete example of why dependency selection and package availability need separate attention.
Changing the dependency graph also brings resolution back into play. When a team adds a dependency or regenerates a lockfile, the versions available from today’s index may differ from those available when the project began.
StableBuild captures daily PyPI index snapshots and caches package files on request. It also caches files when it detects upstream deletions. A dated URL selects the index state used for resolution:
pip install \
-i https://your-domain.pypimirror.stablebuild.com/2026-10-01/ \
-r requirements.txt
Use your account’s mirror domain in place of your-domain. With a dated index, packages uploaded afterward are excluded from resolution. Keep the Python version, platform, installer, and other build inputs controlled too; a historical index alone does not guarantee an identical environment.
For current resolution with cached package retrieval, use the live endpoint:
pip install \
-i https://your-domain.pypimirror.stablebuild.com/live/ \
requests
Full daily index snapshots start on September 21, 2023. Earlier dates are reconstructed from retained information and may differ from the original registry. Packages deleted before they could be retained may be unavailable.
Use --index-url, or its short form -i, with an individual package or a requirements file. For CI, set the index through pip configuration or the PIP_INDEX_URL environment variable rather than repeating it in every command.
Pointing pip at an existing endpoint configures the installer; it does not create or host a mirror. If the account-specific URL includes an API key, treat the full URL as a credential and keep it out of public repositories and logs.
For a uv project, define the index in pyproject.toml:
[[tool.uv.index]]
name = "stablebuild"
url = "https://your-domain.pypimirror.stablebuild.com/2026-10-01/"
default = true
Setting default = true replaces uv’s implicit public PyPI index. Other configured indexes can still take priority, so review the complete configuration if the project uses more than one source.
By default, uv limits candidate versions to the first index containing a package. Its index-selection rules matter when you combine public and private sources; review them before changing the strategy.
Poetry supports repositories implementing the Simple Repository API. Configure the mirror in pyproject.toml:
[[tool.poetry.source]]
name = "stablebuild"
url = "https://your-domain.pypimirror.stablebuild.com/2026-10-01/"
priority = "primary"
Configuring a primary source disables Poetry’s implicit PyPI source. Poetry still searches additional primary sources, and you can add public PyPI explicitly. Review source priorities and package source constraints when combining this mirror with private packages.
Poetry source settings apply to Poetry’s resolution workflow. They are not included in the package’s core metadata and do not automatically configure pip when someone installs the project through pip.
A self-hosted mirror may suit organizations that need packages inside a disconnected network or require direct control of package infrastructure. Bandersnatch is a PyPA mirror client that can synchronize package metadata and release files. Filters can limit the packages or distributions retained.
PyPI mirror size depends on scope. A complete copy requires substantially more storage than a filtered mirror or a cache serving a team’s dependencies. Consult PyPI’s current storage statistics before estimating capacity rather than relying on a fixed figure that will age.
Operating the mirror also means owning synchronization, bandwidth, monitoring, backups, and availability. For offline use, verify that every required distribution is present before disconnecting; a cache cannot serve a file it has never retrieved.
Repository managers such as Artifactory or Nexus may be worth evaluating when the brief also includes private publishing, access control, or artifact workflows. Those requirements extend beyond retrieving historical public dependencies. Assess the relevant product’s retention policy separately, rather than assuming caching preserves every old file indefinitely.
A mirror complements version constraints, lockfiles, and hash verification. It controls the repository state and the package files those tools can access; it does not remove the need to review dependencies or apply security updates.
Choose the mirror around the actual requirement. A synchronized local copy can support offline access. A cache can reduce repeated downloads. A historical index can help resolve an older project against packages available at a known date.
For an existing StableBuild integration, test the chosen endpoint in a clean build and confirm the resulting dependency set before adopting it in CI. Review the PyPI mirror setup guide to configure a dated or live endpoint for your project.