PyPI
OrbitalReg's PyPI adapter implements both the legacy upload API (twine's default) and the simple-index download API used by pip.
Repository types
- Local — uploads via
twine upload, downloads viapip install. - Remote — proxies and caches
https://pypi.org/simple/. - Virtual — federated view; first match wins per package version.
Endpoint shape
Upload (twine): https://orbitalreg.example.com/pypi/<project>/<repo>/legacy/
Download (pip): https://orbitalreg.example.com/pypi/<project>/<repo>/simple/twine
twine upload \
--repository-url https://orbitalreg.example.com/pypi/acme/internal/legacy/ \
--username $ORBITALREG_USER \
--password $ORBITALREG_TOKEN \
dist/*.whl dist/*.tar.gzOr with a ~/.pypirc:
[orbitalreg]
repository = https://orbitalreg.example.com/pypi/acme/internal/legacy/
username = __token__
password = <orbsa_… token>pip
pip install \
--index-url https://__token__:$ORBITALREG_TOKEN@orbitalreg.example.com/pypi/acme/all-libs/simple/ \
my-pkgFor an air-gap-friendly setup, configure the index in ~/.pip/pip.conf once and rely on environment variables for the token.
Wheel + sdist support
Both .whl and .tar.gz distributions are accepted. Metadata is parsed from the wheel's *.dist-info/METADATA (PEP 427) or the sdist's PKG-INFO.
OIDC token exchange (twine)
When using the GitLab CI components, twine upload runs with TWINE_USERNAME=oidc and the password set to the OrbitalReg-exchanged short-lived token. No long-lived PAT in CI variables.
Detection
PyPI packages are scanned by Trivy, Grype, OSV.dev, and Syft. The requires-dist metadata feeds the dependency graph for transitive vulnerability propagation.
Promotion + retention
Standard. Retention rules can target pre-release versions:
name: prune-prereleases
rules:
- keep_by_age:
max_age_days: 30
match_version_regex: "(rc|alpha|beta|dev)"Migration from devpi / pypiserver
Both speak the same simple-index wire format; cutover is a --index-url flag change. Re-uploading an existing artifact is a no-op (content-addressable storage dedups by SHA-256).