Skip to main content

Cancelable

PyPI version Python Versions License: MIT Tests Coverage

A comprehensive, production-ready async cancellation system for Python 3.13+ using anyio.

Table of Contents

Features

  • Multiple Cancellation Sources: Timeout, manual tokens, OS signals, and custom conditions
  • Composable Design: Combine multiple cancellation sources easily
  • Stream Processing: Built-in support for cancelable async iterators
  • Operation Tracking: Full lifecycle tracking with status and progress reporting
  • Library Integrations: Ready-to-use FastAPI integration for request cancellation
  • Type Safe: Full type hints and runtime validation with Pydantic
  • Production Ready: Comprehensive error handling, logging, and performance optimized

Installation

Core Installation

The core library includes only essential dependencies (anyio and pydantic):

uv add hother-cancelable

Optional Extras

Cancelable provides optional extras for various integrations and use cases:

Available Extras

Extra Dependencies Purpose
fastapi fastapi FastAPI middleware for request cancellation
examples google-genai, pynput, psutil Run example scripts and demonstrations

Installing with Extras

FastAPI integration:

uv add "hother-cancelable[fastapi]"

Examples:

uv add "hother-cancelable[examples]"

All extras:

uv add "hother-cancelable[fastapi,examples]"

Quick Start

Basic Usage

from hother.cancelable import Cancelable

# Timeout-based cancellation
async with Cancelable.with_timeout(30.0) as cancel:
    result = await long_running_operation()

# Manual cancellation with token
from hother.cancelable import CancellationToken

token = CancellationToken()

async with Cancelable.with_token(token) as cancel:
    # In another task/thread: await token.cancel()
    result = await interruptible_operation()

Stream Processing

# Cancelable stream processing
async with Cancelable.with_timeout(60.0) as cancel:
    async for item in cancel.stream(data_source(), report_interval=100):
        await process_item(item)

Function Decorators

from hother.cancelable import cancelable

@cancelable(timeout=30.0, register_globally=True)
async def process_data(data: list, cancelable: Cancelable = None):
    for i, item in enumerate(data):
        await cancelable.report_progress(f"Processing item {i+1}/{len(data)}")
        await process_item(item)

Integrations

Cancelable provides seamless integration with FastAPI. See the integrations documentation for detailed guides and examples.

  • FastAPI: Add cancellation middleware to FastAPI applications with automatic request-scoped cancellation

Documentation

To build and serve the documentation locally:

  1. Install the documentation dependencies:
uv sync --group doc
source .venv/bin/activate
  1. Serve the documentation:
mkdocs serve

Development

Dependency Groups

Cancelable uses dependency groups for development and documentation:

Group Purpose Key Dependencies
dev Development tools pytest, ruff, basedpyright, twine, git-cliff
doc Documentation building mkdocs, mkdocs-material, mike

Installation

Basic development setup:

uv sync --group dev
source .venv/bin/activate
lefthook install

This creates a virtual environment, installs all development dependencies, and installs the library in editable mode. It also sets up Lefthook git hooks.

Full development setup with extras:

Some tests and examples require optional extras. To run the full test suite:

# Install dev tools + all extras
uv sync --group dev --all-extras

Selective installation:

# Install with specific extras
uv sync --group dev --extra fastapi --extra examples

# Install documentation tools
uv sync --group doc

Quick Reference

Available extras:

  • fastapi - FastAPI middleware
  • examples - Example scripts

Available groups:

  • dev - Development tools (pytest, ruff, basedpyright, etc.)
  • doc - Documentation tools (mkdocs, mkdocs-material, etc.)

Git Hooks with Lefthook

This project uses Lefthook for managing git hooks. Hooks are automatically installed when you run make install-dev.

To run hooks manually:

# Run all pre-commit hooks
lefthook run pre-commit

Tests

Run core tests (without integration extras):

uv run pytest

Integration tests that require optional dependencies (fastapi) will be automatically skipped if the extras are not installed.

Run all tests including integrations:

# First install all extras
uv sync --all-extras

# Then run tests
uv run pytest

Run specific test categories:

# Run only unit tests
uv run pytest tests/unit

# Run only integration tests (requires extras)
uv run pytest tests/integration

Coverage

uv run pytest --cov=hother.cancelable

Building the package

uv build

Release process

This project uses python-semantic-release for fully automated versioning and releases. Every commit to the main branch is analyzed using conventional commits, and releases are created automatically when needed.

How It Works

  1. Commit with conventional format to the main branch
  2. GitHub Actions automatically analyzes commits, determines version bump, creates tag, updates changelog, publishes to PyPI, and creates GitHub release
  3. Documentation is automatically deployed when a release is published

No manual intervention required! 🎉

Version Bumping Rules

Commit Type Version Bump Example
feat: Minor 0.5.0 → 0.6.0
fix:, perf:, refactor: Patch 0.5.0 → 0.5.1
feat!:, BREAKING CHANGE: Major 0.5.0 → 1.0.0
docs:, chore:, ci:, style:, test: No release -

Conventional Commit Examples

# Minor version bump (new feature)
git commit -m "feat: add streaming cancellation support"

# Patch version bump (bug fix)
git commit -m "fix: resolve race condition in token cancellation"

# Major version bump (breaking change)
git commit -m "feat!: redesign cancellation API

BREAKING CHANGE: CancellationToken.cancel() is now async"

Manual Release Trigger

If needed, you can manually trigger a release via GitHub Actions:

# Go to: Actions → Semantic Release → Run workflow → Run on main branch

Or use the gh CLI:

gh workflow run semantic-release.yml

Local Version Preview

Check what the next version would be without making changes:

# Check current version
grep 'version = ' pyproject.toml | cut -d'"' -f2

# Preview next version (requires being on main branch)
uv run semantic-release --noop version --print

PyPI Trusted Publishing

This project uses PyPI's Trusted Publishing for secure, token-free releases. The GitHub Actions workflow is automatically authorized to publish to PyPI via OIDC.

No API tokens needed! The workflow authenticates using:

  • Publisher: GitHub Actions
  • Repository: hotherio/cancelable
  • Workflow: semantic-release.yml

Release Checklist for Maintainers

When preparing for a release:

  • Ensure all PRs use conventional commit format in titles
  • Verify CI passes on main branch
  • Commit messages follow conventional commits specification
  • Breaking changes are documented in commit body with BREAKING CHANGE:
  • Push to main or merge PR - release happens automatically!

Changelog

The changelog is automatically generated from conventional commits and updated on every release. View it at CHANGELOG.md.

Documentation Deployment

Documentation is automatically built and deployed when:

  • A release is published (triggered by semantic-release)
  • Changes are pushed to docs/, mkdocs.yml, or the workflow file on main

Manual deployment commands:

# Deploy a specific version
uv run mike deploy --push --update-aliases v0.5 latest

# Set default version
uv run mike set-default latest

# List deployed versions
uv run mike list

Check documentation locally:

uv run mkdocs serve
# or with mike
uv run mike serve

Generate the licenses:

uv run pip-licenses --from=mixed --order count -f md --output-file licenses.md
uv run pip-licenses --from=mixed --order count -f csv --output-file licenses.csv

Build the new documentation:

uv run mike deploy --push --update-aliases <version> latest
uv run mike set-default latest
uv run mike list

Checking the documentation locally

uv run mike serve

Development practices

Branching & Pull-Requests

Each git branch should have the format <tag>/item_<id> with eventually a descriptive suffix.

We us a Squash & Merge approach.

Conventional Commits

We use Conventional Commits.

Format: <type>(<scope>): <subject>

<scope> is optional

Example

feat: add hat wobble
^--^  ^------------^
|     |
|     +-> Summary in present tense.
|
+-------> Type: chore, docs, feat, fix, refactor, style, or test.

More Examples:

  • feat: (new feature for the user, not a new feature for build script)
  • fix: (bug fix for the user, not a fix to a build script)
  • docs: (changes to the documentation)
  • style: (formatting, missing semi colons, etc; no production code change)
  • refactor: (refactoring production code, eg. renaming a variable)
  • test: (adding missing tests, refactoring tests; no production code change)
  • chore: (updating grunt tasks etc; no production code change)
  • build: (changes in the build system)
  • ci: (changes in the CI/CD and deployment pipelines)
  • perf: (significant performance improvement)
  • revert: (revert a previous change)

Contributing

We welcome contributions! Please see our Contributing Guide for details on how to get started.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Release files for hother-cancelable 0.11.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hother-cancelable 0.11.3
File Size Uploaded
hother_cancelable-0.11.3.tar.gz 118.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hother-cancelable 0.11.3
File Interpreter ABI Platform
hother_cancelable-0.11.3-py3-none-any.whl Python 3 none any Details

Total release size: 180.0 kB

Release files / hother_cancelable-0.11.3.tar.gz

Download URL hother_cancelable-0.11.3.tar.gz
Size 118.7 kB
Tags Source
SHA-256 checksum
How to use checksums
90f2fc007e43d0b59367429504707600dbc4000a32cfdc80a21ba899b01c575a
BLAKE2b-256 checksum
How to use checksums
b95234ab62ed259b822da13433bd4bceb43222f7da556cd8f898b17c4135d235
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.

Transparency log

Release files / hother_cancelable-0.11.3-py3-none-any.whl

Download URL hother_cancelable-0.11.3-py3-none-any.whl
Size 61.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dfe1604520d4762261d14a42e4ad2a6346be3e311f6f8e89a9f32ff153f7bca7
BLAKE2b-256 checksum
How to use checksums
407a4fda965bcf66a797d359bf37c104bd509353068e64428812b06ce04ab5e6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.11.3 This release

2 release files

0.11.1

2 release files

0.11.0

2 release files

0.10.1

2 release files

0.10.0

2 release files

0.9.3

2 release files

0.9.0

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page