Metadata-Version: 2.4
Name: devpi-api-client
Version: 1.0.0
Summary: High-level Python client for managing users, indexes, tokens, and packages on devpi servers.
License: MIT
License-File: LICENSE
Keywords: devpi,pypi,api,client,packaging
Author: ramos
Author-email: crqdev@gmail.com
Requires-Python: >=3.9
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Dist: pkginfo (>=1.12.1.2,<2.0.0.0)
Requires-Dist: pydantic (>=2.11.8,<3.0.0)
Requires-Dist: pymacaroons (>=0.13.0,<0.14.0)
Requires-Dist: requests (>=2.32.5,<3.0.0)
Project-URL: Documentation, https://github.com/veloslab/python-devpi-api-client/blob/main/docs/index.md
Project-URL: Homepage, https://github.com/veloslab/python-devpi-api-client
Project-URL: Repository, https://github.com/veloslab/python-devpi-api-client
Project-URL: changelog, https://github.com/veloslab/python-devpi-api-client/blob/main/CHANGELOG.md
Description-Content-Type: text/markdown

# Devpi API Client

Python client for automating user, index, token, and package management on a devpi server.

## Installation

```bash
pip install devpi-api-client
```

## Quickstart

```python
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:

```python
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:

```bash
poetry run mkdocs serve
```

## Development

### Setup

Install [Poetry](https://python-poetry.org/docs/#installation), then install the dependencies for the groups you need:

```bash
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:

```bash
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:

```bash
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:

```bash
poetry install --with integration
```

Then run the tests:

```bash
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:

```bash
poetry run python scripts/run_integration_tests.py --devpi-version 6.17.0
```

Additional pytest flags can be passed after `--`:

```bash
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:

```bash
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

```bash
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):

```markdown
## [0.2.1] - YYYY-MM-DD

### Fixed
- ...

### Added
- ...
```

### 4. Commit and open a PR

```bash
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:

```bash
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](https://docs.pypi.org/trusted-publishers/) (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.

