Python client for automating user, index, token, and package management on a devpi server.
pip install devpi-api-clientfrom devpi_api_client import Client
with Client("https://devpi.example.com", user="root", password="s3cret") as client:
client.user.create("service", "changeme", email="svc@example.com")
indexes = client.index.list("service")
token = client.token.create("service", allowed=["upload"], expires_in_seconds=3600)Enable debug logging to observe outgoing requests and error handling:
import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger("devpi_api_client").setLevel(logging.DEBUG)Refer to docs/index.md for contributor and operator guides. Build the HTML docs locally:
poetry run mkdocs serveInstall Poetry, then install the dependencies for the groups you need:
pip install pipx
pipx install poetry
# Core dev tools (linting, type checking, unit tests)
poetry install --with dev
# Add docs build support
poetry install --with dev,docs
# Add integration test support (devpi-server + devpi-tokens)
poetry install --with dev,integration
# Everything
poetry install --with dev,docs,integrationAlways run linting and type checking before opening a pull request:
poetry run ruff check . # lint
poetry run ruff check . --fix # auto-fix lint issues
poetry run mypy devpi_api_client # type checkUnit tests run without any external services and should be your first check:
poetry run pytest tests/ --ignore=tests/integration --cov=devpi_api_client --cov-report=term-missingIntegration tests run against a real devpi server. The helper script handles installation, server startup, and teardown automatically.
First install the integration group if you have not already:
poetry install --with integrationThen run the tests:
poetry run python scripts/run_integration_tests.pyThis uses the devpi binaries from the Poetry environment — no additional download required.
To test against a specific version, pass --devpi-version; the script creates a temporary
isolated venv so the Poetry environment stays clean:
poetry run python scripts/run_integration_tests.py --devpi-version 6.17.0Additional pytest flags can be passed after --:
poetry run python scripts/run_integration_tests.py -- -k test_upload -v| Option | Default | Description |
|---|---|---|
--devpi-version |
latest | devpi-server version to install and test against |
--port |
3141 |
Port the local devpi server will listen on |
--password |
devpi-test-password |
Root password used to initialise the server |
Running against an existing server
If you already have a devpi server running, export the connection details and call pytest directly:
export DEVPI_URL=http://127.0.0.1:3141
export DEVPI_USER=root
export DEVPI_PASSWORD=devpi-test-password
poetry run pytest tests/integration/ -v --tb=shortIn CI, the integration suite runs against a matrix of devpi versions via the
integration-tests job in .github/workflows/ci.yml.
Because main has branch protection, the version bump and changelog update go through a PR.
Tags are not branches and are pushed directly after the PR merges.
| Change type | Command |
|---|---|
| Bug fixes only | poetry version patch — e.g. 0.2.0 → 0.2.1 |
| New features, backwards-compatible | poetry version minor — e.g. 0.2.0 → 0.3.0 |
| Breaking changes | poetry version major — e.g. 0.2.0 → 1.0.0 |
git checkout -b release/v0.2.1
poetry version patch # updates pyproject.toml
poetry version # confirm: "devpi-api-client 0.2.1"Add a new section at the top (below the # Changelog heading):
## [0.2.1] - YYYY-MM-DD
### Fixed
- ...
### Added
- ...git add pyproject.toml CHANGELOG.md
git commit -m "Release v0.2.1"
git push origin release/v0.2.1
gh pr create --title "Release v0.2.1" --body "Version bump and changelog for v0.2.1."Wait for CI to pass, then merge the PR.
After the PR merges:
git checkout main && git pull origin main
gh release create v0.2.1 --title "v0.2.1" --notes "See CHANGELOG.md for details." --target mainOr use the GitHub UI: Releases → Draft a new release, set the tag to v0.2.1, target main, then click Publish release.
Publishing the release triggers .github/workflows/publish.yml, which runs unit tests,
lint, type checks, and the docs build before publishing to PyPI via
Trusted Publishing (no API token required).
If any step fails the package is not published.
See docs/RELEASE_GUIDE.md for the one-time PyPI setup and the full checklist.
MIT License. See LICENSE for full text.