Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 14 additions & 25 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
branches: [main]
workflow_dispatch:
env:
LATEST_PY_VERSION: '3.12'
LATEST_PY_VERSION: '3.13'
COVERAGE_ARGS: '--cov --cov-report=term --cov-report=xml'
XDIST_ARGS: '--numprocesses=auto --dist=loadfile'

Expand All @@ -24,53 +24,42 @@ jobs:
- '3.11'
- '3.10'
- '3.9'
- '3.14-rc2'
services:
nginx:
image: kennethreitz/httpbin
ports:
- 8080:80

steps:
# Install dependencies, with caching
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- uses: snok/install-poetry@v1.4
- uses: astral-sh/setup-uv@v6
with:
version: 1.8.5
virtualenvs-in-project: true
enable-cache: true
cache-dependency-glob: uv.lock
- name: Install dependencies
run: |
uv python install ${{ matrix.python-version }}
uv sync --all-extras

# Start integration test databases
- uses: supercharge/mongodb-github-action@1.12.0
with:
mongodb-version: 4.4
mongodb-version: '5.0'
- uses: supercharge/redis-github-action@1.8.0
with:
redis-version: '6'
- uses: rrainn/dynamodb-action@v4.0.0

# Cache packages per python version, and reuse until lockfile changes
- name: Cache python packages
id: cache
uses: actions/cache@v4
with:
path: .venv
key: venv-${{ matrix.python-version }}-${{ hashFiles('poetry.lock') }}
- name: Install dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: poetry install -v -E all

- name: Run custom test server
run: |
source $VENV
cd test && gunicorn -D -c server/gunicorn-cfg.py server:app
cd test && uv run gunicorn -D -c server/gunicorn-cfg.py server:app

# Run tests with coverage report
- name: Run tests
run: |
source $VENV
pytest -rs test/unit ${{ env.XDIST_ARGS }} ${{ env.COVERAGE_ARGS }}
pytest -rs test/integration --cov-append ${{ env.XDIST_ARGS }} ${{ env.COVERAGE_ARGS }}
uv run pytest -rs test/unit ${{ env.XDIST_ARGS }} ${{ env.COVERAGE_ARGS }}
uv run pytest -rs test/integration --cov-append ${{ env.XDIST_ARGS }} ${{ env.COVERAGE_ARGS }}

# Latest python version: send coverage report to codecov
- name: 'Upload coverage report to Codecov'
Expand Down
25 changes: 11 additions & 14 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,29 @@ on:
description: 'Version number for pre-releases; defaults to build number'
required: false
default: ''
env:
LATEST_PY_VERSION: '3.12'

jobs:
# Deploy stable builds on tags only, and pre-release builds from manual trigger ("workflow_dispatch")
release:
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: ${{ env.LATEST_PY_VERSION }}
- uses: snok/install-poetry@v1.4
with:
virtualenvs-in-project: true
- uses: astral-sh/setup-uv@v6

- name: Set pre-release version
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
env:
pre-release-suffix: ${{ github.event.inputs.pre-release-suffix || 'dev' }}
pre-release-version: ${{ github.event.inputs.pre-release-version || github.run_number }}
run: |
poetry version $(poetry version -s).${{ env.pre-release-suffix }}${{ env.pre-release-version }}
poetry version
PKG_VERSION=$(uvx --from=toml-cli toml get --toml-path=pyproject.toml project.version)
DEV_VERSION=$PKG_VERSION.${{ env.pre-release-suffix }}${{ env.pre-release-version }}
echo "Setting pre-release version to $DEV_VERSION"
uvx --from=toml-cli toml set --toml-path=pyproject.toml project.version $DEV_VERSION

- name: Build and publish to pypi
run: |
poetry build
poetry publish -u __token__ -p ${{ secrets.PYPI_TOKEN }}
- name: Build package distributions
run: uv build
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
8 changes: 5 additions & 3 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ build:
tools:
python: '3.12'
jobs:
# Use poetry to export optional + documentation dependencies
# Use uv to export optional + documentation dependencies
post_create_environment:
- python -m pip install poetry poetry-plugin-export
- poetry export -o docs/requirements.txt --all-extras --with=docs
- pip install uv
- uv export -q --no-dev --group docs --no-emit-project -o docs/requirements.txt
python:
install:
- method: pip
path: .
- requirements: docs/requirements.txt
16 changes: 8 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

## Dev Installation

To set up for local development (requires [poetry](https://python-poetry.org/docs/#installation)):
To set up for local development (requires [uv](https://docs.astral.sh/uv/getting-started/installation/)):

```sh
$ git clone https://github.com/requests-cache/aiohttp-client-cache
$ cd aiohttp-client-cache
$ poetry install -E all
$ uv sync --all-extras
```

## Pre-commit hooks
Expand Down Expand Up @@ -48,9 +48,9 @@ Tests are divided into unit and integration tests:

### Running Tests

- Run `pytest` to run all tests
- Run `pytest test/unit` to run only unit tests
- Run `pytest test/integration` to run only integration tests
- Run `uv run pytest` to run all tests
- Run `uv run pytest test/unit` to run only unit tests
- Run `uv run pytest test/integration` to run only integration tests

For CI jobs (including PRs), these tests will be run for each supported python version.
You can use [nox](https://nox.thea.codes) to do this locally, if needed:
Expand Down Expand Up @@ -83,11 +83,11 @@ Then, run:

```sh
docker-compose up -d
pytest test/integration
uv run pytest test/integration
```

To test DragonflyDB you need to stop a Redis container (if running) and run `docker compose -f dragonflydb.yaml up`.
No other changes are required, you can run related tests with e.g. `pytest test -k redis`.
No other changes are required, you can run related tests with e.g. `uv run pytest test -k redis`.

## Documentation

Expand All @@ -96,7 +96,7 @@ No other changes are required, you can run related tests with e.g. `pytest test
First, install documentation dependencies:

```sh
$ poetry install -E all --with docs
$ uv sync --all-extras
```

To build the docs locally:
Expand Down
6 changes: 4 additions & 2 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# History

## Unreleased

- Packaging and project config are now handled with [uv](https://docs.astral.sh/uv/). For users, installation still works the same. For developers, see [Contributing Guide](https://aiohttp-client-cache.readthedocs.io/en/stable/contributing.html) for details.

## 0.14.1 (2025-10-01)

- Update type annotation for `CachedSession.__aenter__` with `Self` type
Expand Down Expand Up @@ -195,8 +199,6 @@
- `Expires`
- Add support for HTTP timestamps (RFC 5322) in `expire_after` parameters
- Add a `use_temp` option to `SQLiteBackend` to use a tempfile
- Packaging is now handled with Poetry. For users, installation still works the same. For developers,
see [Contributing Guide](https://aiohttp-client-cache.readthedocs.io/en/stable/contributing.html) for details
- Published package on [conda-forge](https://anaconda.org/conda-forge/aiohttp-client-cache)

## 0.3.0 (2021-04-09)
Expand Down
34 changes: 21 additions & 13 deletions noxfile.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Notes:
* 'test' command: nox will use poetry.lock to determine dependency versions
* 'test' command: nox will use uv.lock to determine dependency versions
* 'lint' command: tools and environments are managed by pre-commit
* All other commands: the current environment will be used instead of creating new ones
"""
Expand All @@ -9,7 +9,6 @@
from shutil import rmtree

import nox
from nox_poetry import session

nox.options.reuse_existing_virtualenvs = True
nox.options.sessions = ['lint', 'cov']
Expand All @@ -29,25 +28,35 @@
XDIST_ARGS = '--numprocesses=auto --dist=loadfile' # Run tests in parallel, grouped by test module


@session(python=['3.9', '3.10', '3.11', '3.12'])
def install_deps(session):
"""Install project and test dependencies into a test-specific virtualenv using uv"""
session.env['UV_PROJECT_ENVIRONMENT'] = session.virtualenv.location
session.run_install(
'uv',
'sync',
'--frozen',
'--all-extras',
)


@nox.session(python=['3.9', '3.10', '3.11', '3.12', '3.13', '3.14'])
def test(session):
"""Run tests for a specific python version"""
test_paths = session.posargs or [UNIT_TESTS]
session.install('.', 'pytest', 'pytest-aiohttp', 'pytest-asyncio', 'pytest-xdist')

install_deps(session)
cmd = f'pytest -rs {XDIST_ARGS}'
session.run(*cmd.split(' '), *test_paths)


@session(python=False)
@nox.session(python=False)
def clean(session):
"""Clean up temporary build + documentation files"""
for dir in CLEAN_DIRS:
print(f'Removing {dir}')
rmtree(dir, ignore_errors=True) # type: ignore[arg-type]


@session(python=False, name='cov')
@nox.session(python=False, name='cov')
def coverage(session):
"""Run tests and generate coverage report"""
cmd_1 = f'pytest {UNIT_TESTS} -rs {XDIST_ARGS} {COVERAGE_ARGS}'
Expand All @@ -56,22 +65,22 @@ def coverage(session):
session.run(*cmd_2.split(' '))


@session(python=False)
@nox.session(python=False)
def docs(session):
"""Build Sphinx documentation"""
cmd = 'sphinx-build docs docs/_build/html -j auto'
session.run(*cmd.split(' '))


@session(python=False)
@nox.session(python=False)
def livedocs(session):
"""Auto-build docs with live reload in browser.
Add `--open` to also open the browser after starting.
"""
args = ['-a']
args += [f'--watch {pattern}' for pattern in LIVE_DOCS_WATCH]
args += [f'--ignore {pattern}' for pattern in LIVE_DOCS_IGNORE]
args += [f'--port {LIVE_DOCS_PORT}', '-j auto']
args += [f'--port {LIVE_DOCS_PORT}', '--host 0.0.0.0', '-j auto']
if session.posargs == ['open']:
args.append('--open-browser')

Expand All @@ -80,8 +89,7 @@ def livedocs(session):
session.run(*cmd.split(' '))


@session(python=False)
@nox.session(python=False)
def lint(session):
"""Run linters and code formatters via pre-commit"""
cmd = 'pre-commit run --all-files'
session.run(*cmd.split(' '))
session.run('pre-commit', 'run', '--all-files')
Loading