Official Python client for Task Badger. Public package: taskbadger on PyPI.
uv sync --frozen # Install deps (incl. dev + cli extras via dependency-groups)
uv run pytest # Run unit tests (needs Redis; integration_tests/ excluded by default)
uv run pytest integration_tests -vs # Run integration tests (needs Redis + Postgres + API key)
uv run ruff check . --fix # Lint
uv run ruff format . # Format
uv build # Build sdist + wheelPre-commit runs ruff-check + ruff-format; install with uv run pre-commit install.
taskbadger/— SDK sourcesdk.py,mug.py,safe_sdk.py— public API surface (re-exported from__init__.py)decorators.py—@trackdecoratorcelery.py,procrastinate.py— per-queue integrations (optional extras)systems/,_integrations.py— auto-tracking layer (BaseSystemIntegration) wired onto a Celery/Procrastinate appcontext_providers/,_error_context.py— pluggable error context (e.g. Sentry issue links) viainit(context_providers=[...])_heartbeat.py— background thread pinging long-running taskscli/,cli_main.py— Typer-based CLI (optional[cli]extra)internal/— generated byopenapi-python-client; do not hand-edit
tests/— unit tests (pytest, pytest-httpx)integration_tests/— hits real Task Badger API; excluded from default pytest runtaskbadger.yaml— OpenAPI schema used to regenerateinternal/
uv run invoke update-api # Pull latest schema + regenerate
uv run invoke update-api --local # Regenerate from existing taskbadger.yamlThe update-api invoke task curls localhost:8000/api/schema.json by default — pass --local if you don't have the API server running.
- Ruff: line-length 120, target Python 3.10, rules
E F I UP DJ PT. - Supports Python 3.10–3.14 — don't use 3.11+ syntax (e.g.
Self,LiteralString). - Extras (
celery,procrastinate,cli,sentry) are all optional; keep their imports inside the corresponding module (taskbadger/celery.py,taskbadger/procrastinate.py,taskbadger/systems/,taskbadger/cli/,taskbadger/context_providers/sentry.py). taskbadger/internal/*is generator output — lint is best-effort, don't reformat manually.
Conventional Commits for commit subjects and PR titles: type(scope): summary.
- Types:
featfixdocschorerefactorperftestci. Breaking:feat!:/fix!:plus aBREAKING CHANGE:footer. - Scopes (optional):
celery,procrastinate,cli,sdk,sentry,internal. - Label every PR with its type (
feat,fix, …). Release notes are auto-generated from PR titles and grouped by label via.github/release.yml; an unlabelled PR falls into "Other Changes". - PRs merge as merge commits, so only PR titles reach the changelog — commit subjects are history hygiene.
uv run invoke tag-release # Bumps version in pyproject.toml, tags, pushes — triggers release.ymlGitHub Actions then drafts a release; publishing the release triggers publish.yml → PyPI.
pytestskipsintegration_tests/vianorecursedirs— name them explicitly to run.- Integration tests need
TASKBADGER_ORG,TASKBADGER_PROJECT,TASKBADGER_API_KEY, a running Redis, and Postgres viaPROCRASTINATE_DSN(defaults topostgresql://postgres:postgres@localhost:5432/procrastinate). - Unit tests also need Redis —
tests/conftest.pypoints Celery atredis://localhost:6379so serialization is exercised for real. - Don't unpin
openapi-python-client<0.29— 0.29 generatesdatetime.fromisoformatcalls that can't parse the API'sZ-suffixed timestamps on Python 3.10. - User-facing features are documented in
README.md, not a docs site — add a section there when adding one. - Only the core httpx/attrs/dateutil/tomlkit deps are guaranteed at runtime.