Metadata-Version: 2.4
Name: pypi-redirect-server
Version: 0.1.0
Summary: A small self-hosted PyPI simple-index server that serves local packages and redirects cache misses upstream.
Author: GGN_2015
License: MIT
Project-URL: Homepage, https://github.com/GGN-2015/pypi_redirect_server
Project-URL: Issues, https://github.com/GGN-2015/pypi_redirect_server/issues
Keywords: pypi,pip,package-index,simple-api,proxy
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# PyPI Redirect Server

PyPI Redirect Server is a small, dependency-free Python service that acts like a
PyPI Simple Repository API server. It serves packages from a local directory when
they are available and redirects missing packages to a configurable upstream
repository such as the official PyPI.

## Features

- Serves local wheel and source distribution files through `/simple/`.
- Redirects cache misses to a configurable upstream repository.
- Uses only the Python standard library at runtime.
- Runs on Windows, macOS, and Linux.
- Refreshes the local package cache while the server is running.
- Logs every request routing decision to stdout.
- Serves the latest cached version by default when a project has multiple versions.
- Provides a console command and a `python -m` entry point.

## Installation

From a checkout:

```console
python -m pip install -e .
```

No runtime dependencies are installed.

## Quick Start

Create a cache directory and put package files in it:

```console
mkdir packages
python -m pip download requests -d packages
```

Start the server:

```console
pypi-redirect-server --package-dir packages --host 127.0.0.1 --port 8080
```

Install packages through the server:

```console
python -m pip install --index-url http://127.0.0.1:8080/simple requests
```

If `requests` exists in `packages`, pip downloads it from this server. If a
package is not in the local cache, the server redirects pip to the configured
upstream repository.

Every request writes a routing log line to stdout:

```text
time=2026-05-28T06:56:05Z client=127.0.0.1:65503 method=GET path="/simple/demo-pkg/" status=200 action=local-index project=demo-pkg requested_version=- selected_version=2.0.0 upstream=no
```

## Upstream Repository

The default upstream is the official PyPI:

```text
https://pypi.org
```

Change it with `--upstream`:

```console
pypi-redirect-server --upstream https://pypi.org/simple
```

The upstream can be either a site root or a Simple API root. For example,
`https://pypi.org` and `https://pypi.org/simple` both work.

## Package Cache Layout

The cache can be flat:

```text
packages/
  demo_pkg-1.0.0-py3-none-any.whl
  other_project-2.1.0.tar.gz
```

It can also be grouped by project:

```text
packages/
  demo-pkg/
    demo_pkg-1.0.0-py3-none-any.whl
```

See [Package Cache](docs/PACKAGE_CACHE.md) for details.

## Configuration

Every setting is available as a command-line flag and as an environment
variable. Common examples:

```console
pypi-redirect-server --package-dir packages --upstream https://pypi.org --port 8080
```

```console
PYPI_REDIRECT_PACKAGE_DIR=packages PYPI_REDIRECT_UPSTREAM=https://pypi.org pypi-redirect-server
```

On PowerShell:

```powershell
$env:PYPI_REDIRECT_PACKAGE_DIR = "packages"
$env:PYPI_REDIRECT_UPSTREAM = "https://pypi.org"
pypi-redirect-server
```

See [Configuration](docs/CONFIGURATION.md) for the full reference.

## Development

Run the tests with:

```console
python -m unittest discover -s tests
```

Run the server directly from the source tree after installation:

```console
python -m pypi_redirect_server --package-dir packages
```

## Behavior

For a request like `/simple/demo/`:

1. The server normalizes `demo` using PEP 503 rules.
2. If cached files for `demo` exist, it returns local links for the latest
   cached version.
3. If a local version selector is present, such as `?version=1.0.0` or
   `?minor=1.2`, it returns the latest matching local files.
4. If no matching local files exist, it redirects to the configured upstream, for
   example `https://pypi.org/simple/demo/`.

Local package file URLs are served from `/packages/<project>/<filename>`.

Use `--all-versions` when you want the local Simple API page to expose every
cached version and let pip do all version resolution client-side.

Pip does not send command-line version constraints such as `demo==1.0.0` to a
Simple API server. The `?version=` and `?minor=` selectors are useful for direct
HTTP clients, but pip normally resolves versions from the links returned by the
index page.
