simple-repository-server
A tool for running a PEP-503 simple Python package repository, including features such as dist metadata (PEP-658) and JSON API (PEP-691)
Installation
python -m pip install simple-repository-server
Usage
The simple-repository-server is designed to be used as a library, but also includes a convenient command line interface for running
a simple repository service:
$ simple-repository-server --help
usage: simple-repository-server [-h] [--port PORT] repository-url [repository-url ...]
Run a Simple Repository Server
positional arguments:
repository-url Repository URL (http/https) or local directory path
options:
-h, --help show this help message and exit
--port PORT
--stream-http-resources
Stream HTTP resources through this server instead of redirecting (default: redirect)
The simplest example of this is to simply mirror the Python Package Index:
python -m simple_repository_server https://pypi.org/simple/
This will run a server (on port 8000 by default), you can then use it with pip or uv with the
appropriate configuration, for example:
export PIP_INDEX_URL=http://localhost:8000/simple/
pip install some-package-to-install
Or with uv:
export UV_INDEX_URL=http://localhost:8000/simple/
uv pip install some-package-to-install
Server capabilities
If multiple repositories are provided to the CLI, the PrioritySelectedProjectsRepository component will be used to
combine them together in a way that mitigates the dependency confusion attack, with the first declared repository having the highest priority.
The server handles PEP-691 content negotiation to serve either HTML or JSON formats.
Per PEP-691, the default (fallback) content type is HTML, but a JSON response can
be previewed in the browser by adding the ?format=application/vnd.pypi.simple.v1+json
querystring to any of the repository URLs.
The server has been configured to include PEP-658 metadata, even if the upstream repository does not include such metadata. This is done on the fly, and as a result the distribution will be temporarily downloaded (in the case of http) to the server in order to extract and serve the metadata.
It is possible to use the resulting repository as input for the
simple-repository-browser, which
offers a web interface to browse and search packages in any simple package repository (PEP-503),
inspired by PyPI / warehouse.
It is expected that as new features appear in the underlying simple-repository library, those
which make general sense to enable by default will be introduced into the CLI without providing a
mechanism to disable those features. For more control, please see the "Non CLI usage" section.
Repository sources
The server can work with both remote repositories and local directories:
# Remote repository
python -m simple_repository_server https://pypi.org/simple/
# Local directory
python -m simple_repository_server /path/to/local/packages/
# Multiple sources (priority order, local having precedence)
python -m simple_repository_server /path/to/local/packages/ https://pypi.org/simple/
Local directories should be organised with each project in its own subdirectory using the canonical package name (lowercase, with hyphens instead of underscores):
/path/to/local/packages/
├── my-package/
│ ├── my_package-1.0.0-py3-none-any.whl
│ └── my-package-1.0.0.tar.gz
└── another-package/
└── another_package-2.1.0-py3-none-any.whl
If metadata files are in the local repository they will be served directly, otherwise they will be extracted on-the-fly and served.
Authentication
The server automatically supports netrc-based authentication for private http repositories.
If a .netrc file exists in your home directory or is specified via the NETRC environment
variable, the server will use those credentials when accessing HTTP repositories.
Resource handling
By default, HTTP resource requests (e.g. wheel downloads) are redirected to their original URLs
(302 redirect).
To stream resources through the server instead, use the --stream-http-resources CLI flag.
Redirecting (default) is suitable for:
- Most public repository scenarios
- When bandwidth and server processing overhead are considerations
Streaming is useful for:
- Air-gapped environments where clients cannot access upstream URLs directly
- When the server has authentication credentials that clients lack
Non CLI usage
This project provides a number of tools in order to build a repository service using FastAPI.
For cases when control of the repository configuration is required, and where details of the
ASGI environment need more precise control, it is expected that simple-repository-server is used
as a library instead of a CLI.
Currently, the API for this functionality is under development, and will certainly change in the future.
License and Support
This code has been released under the MIT license. It is an initial prototype which is developed in-house, and not currently openly developed.
It is hoped that the release of this prototype will trigger interest from other parties that have similar needs. With sufficient collaborative interest there is the potential for the project to be openly developed, and to power Python package repositories across many domains.
Please get in touch at https://github.com/orgs/simple-repository/discussions to share how this project may be useful to you. This will help us to gauge the level of interest and provide valuable insight when deciding whether to commit future resources to the project.
Metadata
Release files for simple-repository-server 0.10.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| simple_repository_server-0.10.0.tar.gz | 21.1 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| simple_repository_server-0.10.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 45.5 kB
Release files / simple_repository_server-0.10.0.tar.gz
| Download URL | simple_repository_server-0.10.0.tar.gz |
|---|---|
| Size | 21.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
33d424c2537d4624e6258a9f2470c73cbeadf085ce2853b41f55289c54e77226
|
|
BLAKE2b-256 checksum How to use checksums |
4d4e9e6997aeefbec6cb405d19b8e3a30505dc9daa8e3e8bf9dd748f9ebda491
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2025.
Transparency logRelease files / simple_repository_server-0.10.0-py3-none-any.whl
| Download URL | simple_repository_server-0.10.0-py3-none-any.whl |
|---|---|
| Size | 24.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f85ea9447c1a70ce5688e8bcef5fa01597254622a96e497d1cbef259031349fc
|
|
BLAKE2b-256 checksum How to use checksums |
21d1217e39de7ab7599fc855ecde3732cb3cb01ebdbbacd2bd4b47fd57e27eb3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2025.
Transparency logSecurity for simple-repository-server 0.10.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for simple_repository_server-0.10.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2025.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.