PyPI Registry
Vetrix hosts a per-repository PyPI-compatible package index. Packages are published with twine and installed with pip.
Registry URL
https://<vetrix-host>/pypi/<owner>/<repo>/
Where <owner> is a username or organization name and <repo> is the repository name.
Authentication
All registry operations require a personal access token. Generate one at Settings → Access Tokens.
Publishing a package
Build your distribution
pip install build twine
python -m build
# produces dist/mypackage-1.0.0.tar.gz and dist/mypackage-1.0.0-py3-none-any.whl
Configure .pypirc
[distutils]
index-servers =
vetrix
[vetrix]
repository = https://<vetrix-host>/pypi/<owner>/<repo>/
username = <your-username>
password = <your-token>
Upload
twine upload --repository vetrix dist/*
Or without .pypirc:
twine upload \
--repository-url https://<vetrix-host>/pypi/<owner>/<repo>/ \
--username <your-username> \
--password <your-token> \
dist/*
Installing packages
One-off install
pip install mypackage \
--index-url https://<your-username>:<your-token>@<vetrix-host>/pypi/<owner>/<repo>/simple/
pip.conf (persistent)
~/.config/pip/pip.conf (Linux/macOS) or %APPDATA%\pip\pip.ini (Windows):
[global]
index-url = https://<your-username>:<your-token>@<vetrix-host>/pypi/<owner>/<repo>/simple/
After this, a plain pip install mypackage will use the Vetrix index.
pyproject.toml (Poetry)
[[tool.poetry.source]]
name = "vetrix"
url = "https://<vetrix-host>/pypi/<owner>/<repo>/simple/"
priority = "primary"
Set credentials:
poetry config http-basic.vetrix <username> <token>
requirements.txt with index override
--index-url https://<username>:<token>@<vetrix-host>/pypi/<owner>/<repo>/simple/
mypackage==1.0.0
requests>=2.31
Using multiple indexes
To fall back to PyPI for packages not found in Vetrix:
pip install mypackage \
--index-url https://<username>:<token>@<vetrix-host>/pypi/<owner>/<repo>/simple/ \
--extra-index-url https://pypi.org/simple/
Security note: using --extra-index-url with a public index can expose your packages to dependency confusion attacks. Prefer publishing all dependencies to the Vetrix registry or using --no-index for air-gapped environments.
Listing packages
curl https://<vetrix-host>/pypi/<owner>/<repo>/simple/ \
-H "Authorization: Bearer <token>"
API endpoints
| Method | Path | Description |
|---|---|---|
| GET | /pypi/:owner/:repo/simple/ |
Package index (PEP 503) |
| GET | /pypi/:owner/:repo/simple/:package/ |
Package versions |
| GET | /pypi/:owner/:repo/simple/:package |
Package versions (no trailing slash; equivalent to the row above) |
| POST | /pypi/:owner/:repo/ |
Upload package (twine) |
| GET | /pypi/:owner/:repo/packages/:digest/:filename |
Download package file |
Permissions
| Action | Minimum role |
|---|---|
| Install packages | read |
| Publish packages | write |
The PyPI registry exposes no delete endpoint: neither a package nor an individual version can be removed through it, at any role.