feat: add PyPI remote type with URL rewriting and basic auth #15

Merged
unkinben merged 2 commits from benvin/pypi-remote into master 2026-04-27 14:46:28 +10:00
Owner

Summary

  • Adds a new pypi package type with simple/ paths treated as mutable (index pages expire, package files cached forever)
  • Rewrites files.pythonhosted.org URLs in simple index HTML responses so package downloads also go through the proxy — configured via pypi_files_url / pypi_files_remote per-remote, making it work for both PyPI and self-hosted registries (Gitea, Devpi, etc.)
  • Adds basic auth support for non-Docker remotes (username / password in remote config), threaded through upstream reachability and conditional HEAD checks
  • Adds .whl content-type (application/zip) and refactors the duplicated content-type block into a shared helper
  • Adds pypi and pypi-files remotes to remotes.yaml, plus a pypi-gitea example for Gitea package registries where index and files share the same base URL

Test plan

  • 169 unit tests pass (uv run pytest)
  • uv run --with pre-commit --default-index http://localhost:8000/api/v1/remote/pypi/simple pre-commit --version with a fresh UV_CACHE_DIR fetches all packages through the proxy (cache misses logged)
  • Second run with a different fresh UV_CACHE_DIR serves everything from proxy cache (cache hits logged, no upstream fetches)
  • Simple index HTML served by proxy has all files.pythonhosted.org hrefs rewritten to the local pypi-files remote path
## Summary - Adds a new `pypi` package type with `simple/` paths treated as mutable (index pages expire, package files cached forever) - Rewrites `files.pythonhosted.org` URLs in simple index HTML responses so package downloads also go through the proxy — configured via `pypi_files_url` / `pypi_files_remote` per-remote, making it work for both PyPI and self-hosted registries (Gitea, Devpi, etc.) - Adds basic auth support for non-Docker remotes (`username` / `password` in remote config), threaded through upstream reachability and conditional HEAD checks - Adds `.whl` content-type (`application/zip`) and refactors the duplicated content-type block into a shared helper - Adds `pypi` and `pypi-files` remotes to `remotes.yaml`, plus a `pypi-gitea` example for Gitea package registries where index and files share the same base URL ## Test plan - [x] 169 unit tests pass (`uv run pytest`) - [x] `uv run --with pre-commit --default-index http://localhost:8000/api/v1/remote/pypi/simple pre-commit --version` with a fresh `UV_CACHE_DIR` fetches all packages through the proxy (cache misses logged) - [x] Second run with a different fresh `UV_CACHE_DIR` serves everything from proxy cache (cache hits logged, no upstream fetches) - [x] Simple index HTML served by proxy has all `files.pythonhosted.org` hrefs rewritten to the local `pypi-files` remote path
unkinben added 1 commit 2026-04-27 14:32:37 +10:00
feat: add pypi remote type with URL rewriting and basic auth
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
8e9d313892
- Add 'pypi' package type to config.py; simple/ paths are mutable by default
- Refactor content-type detection into _get_content_type() helper; add .whl
- Add _resolve_content() which rewrites files host URLs in simple index HTML
  to go through the proxy (pypi_files_url / pypi_files_remote config keys),
  and returns text/html content-type for simple index responses
- Add basic auth support for non-Docker remotes (username + password/token
  in remote config); thread auth through _upstream_reachable and
  check_upstream_changed so mutable TTL checks also authenticate
- Add 'pypi' remote (pypi.org simple index) and 'pypi-files' remote
  (files.pythonhosted.org) to remotes.yaml; add 'pypi-gitea' example for
  Gitea package registries where index and files share the same base URL
- Add unit tests: simple index URL rewriting, HTML content-type, .whl/.tar.gz
  content-types, mutable index detection, and immutable pattern enforcement
unkinben added 1 commit 2026-04-27 14:37:47 +10:00
docs: describe PyPI remote usage with uv system/user uv.toml
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
5de912db75
unkinben merged commit 6b1a6c9eb4 into master 2026-04-27 14:46:28 +10:00
unkinben deleted branch benvin/pypi-remote 2026-04-27 14:46:28 +10:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unkin/artifactapi#15