High-level Python client for managing users, indexes, tokens, and packages on devpi servers.
Project description
Devpi API Client
Python client for automating user, index, token, and package management on a devpi server.
Installation
pip install devpi-api-client
Quickstart
from 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)
Logging
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)
Documentation
Refer to docs/index.md for contributor and operator guides. Build the HTML docs locally:
poetry run mkdocs serve
Development
Setup
Install 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,integration
Code quality
Always 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 check
Testing
Unit tests
Unit 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-missing
Integration tests
Integration 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 integration
Then run the tests:
poetry run python scripts/run_integration_tests.py
This 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.0
Additional 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=short
In CI, the integration suite runs against a matrix of devpi versions via the
integration-tests job in .github/workflows/ci.yml.
Release Process
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.
1. Decide the version bump
| 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 |
2. Create a release branch and bump the version
git checkout -b release/v0.2.1
poetry version patch # updates pyproject.toml
poetry version # confirm: "devpi-api-client 0.2.1"
3. Update CHANGELOG.md
Add a new section at the top (below the # Changelog heading):
## [0.2.1] - YYYY-MM-DD
### Fixed
- ...
### Added
- ...
4. Commit and open a PR
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.
5. Create a GitHub Release
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 main
Or 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.
License
MIT License. See LICENSE for full text.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file devpi_api_client-1.0.0.tar.gz.
File metadata
- Download URL: devpi_api_client-1.0.0.tar.gz
- Upload date:
- Size: 19.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60eb055705de912dedd8d9340f87e042ed99f60063fde423367d4d2a9ed65769
|
|
| MD5 |
3db369e57c1a46bbaebc8981e996214e
|
|
| BLAKE2b-256 |
1de189d443911f6762ad9485d8c4b8ef5ca38479edda55117e514062a1e32af8
|
Provenance
The following attestation bundles were made for devpi_api_client-1.0.0.tar.gz:
Publisher:
publish.yml on veloslab/python-devpi-api-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
devpi_api_client-1.0.0.tar.gz -
Subject digest:
60eb055705de912dedd8d9340f87e042ed99f60063fde423367d4d2a9ed65769 - Sigstore transparency entry: 1055472741
- Sigstore integration time:
-
Permalink:
veloslab/python-devpi-api-client@e5218d74f278e7c4f3e721b18f22b5332ff90464 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/veloslab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e5218d74f278e7c4f3e721b18f22b5332ff90464 -
Trigger Event:
release
-
Statement type:
File details
Details for the file devpi_api_client-1.0.0-py3-none-any.whl.
File metadata
- Download URL: devpi_api_client-1.0.0-py3-none-any.whl
- Upload date:
- Size: 25.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb8ea5041c0a5d41b8dfdcebfc0808a0cae072ae379b4743f026875ec4963298
|
|
| MD5 |
4e322331679f909b1bbef72b79bde11e
|
|
| BLAKE2b-256 |
d4300c8eaacb0263eb02f94b3daf8676c1a729863845366eb39128b63721e60a
|
Provenance
The following attestation bundles were made for devpi_api_client-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on veloslab/python-devpi-api-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
devpi_api_client-1.0.0-py3-none-any.whl -
Subject digest:
cb8ea5041c0a5d41b8dfdcebfc0808a0cae072ae379b4743f026875ec4963298 - Sigstore transparency entry: 1055472802
- Sigstore integration time:
-
Permalink:
veloslab/python-devpi-api-client@e5218d74f278e7c4f3e721b18f22b5332ff90464 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/veloslab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e5218d74f278e7c4f3e721b18f22b5332ff90464 -
Trigger Event:
release
-
Statement type: