Confucian-spirited dependency health checker for Python projects using pyproject + uv
Project description
AnimaDao
AnimaDao is a pragmatic dependency health checker for Python projects.
It compares declared dependencies with actual imports, flags unused ones, and checks pinned specs (==)
against the latest PyPI releases.
Works with uv and supports three declaration styles.
One-liner GitHub Action
Use the official composite Action to run AnimaDao in one step.
It writes a Markdown report to the Job Summary, optionally uploads artifacts, and can fail the job on policy
violations.
Repo: https://github.com/Absolentia/animadao-action
Recommended pin: uses: Absolentia/animadao-action@v1 (moving major tag).
For full reproducibility you can pin a concrete version, e.g. @v1.0.3.
Minimal usage (declared mode)
- name: AnimaDao (declared)
uses: Absolentia/animadao-action@v1
with:
mode: declared
# One root is enough for most repos; you can also pass multiple roots (e.g. "anima_dao tests")
src: "."
ignore: pip,setuptools,wheel,ruff
fail-if-outdated: "true"
max-unused: "0"
format: md
artifact-name: anima-report-${{ matrix.python-version }}
python-version: ${{ matrix.python-version }}
Installed mode (checks currently installed packages; no “unused” check):
- name: AnimaDao (installed)
uses: Absolentia/animadao-action@v1
with:
mode: installed
fail-if-outdated: "true"
ignore: pip,setuptools,wheel
python-version: ${{ matrix.python-version }}
Full example job (with cache + matrix)
jobs:
anima:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: [ "3.10","3.11","3.12","3.13" ]
steps:
- uses: actions/checkout@v4
# Speed up uv by caching
- uses: actions/cache@v4
with:
path: ~/.cache/uv
key: uv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('uv.lock') }}
- name: AnimaDao (declared)
uses: Absolentia/animadao-action@v1
with:
mode: declared
src: "." # or: "anima_dao tests"
ignore: pip,setuptools,wheel,ruff
fail-if-outdated: "true"
max-unused: "0"
format: md
artifact-name: anima-report-${{ matrix.python-version }}
python-version: ${{ matrix.python-version }}
Notes & tips
- Artifacts in matrix: artifact names must be unique per shard (use
anima-report-${{ matrix.python-version }}), or merge them later to avoid 409 conflicts. - Report visibility: the Action appends the Markdown report to the Job Summary; HTML/JSON are attached as
artifacts when
upload-artifact: "true". - Policies: tune to your process:
- allow a small number of unused deps:
max-unused: "1" - ignore dev tools (e.g.,
ruff,black,mypy,build,twine) viaignore.
- allow a small number of unused deps:
- Multiple source roots: pass them space-separated in
src(e.g.,src: "anima_dao tests"). The Action expands this into repeated--srcflags for the report.
The gate runs against the project root and policy checks (works out of the box). - Pre-release Python: if you run on RC versions (e.g., 3.14-rc), set
allow-prereleases: trueon your ownactions/setup-pythonstep (outside of this Action).
Features
- 🗂 Multiple sources of declared deps:
pyproject.toml— PEP 621[project].dependenciespyproject.toml— Poetry[tool.poetry.dependencies]requirements.txt(incl. nested-rincludes)
- 🔍 Import scan: walks your source tree and extracts top-level imports (AST).
- 🧹 Unused deps: declared but not imported (heuristic, import-name ≈ normalized dist name).
- ⏫ Outdated pins: checks only
==-pinned requirements against PyPI latest. - ⚙️ Two modes:
--mode declared(default) and--mode installed. - 🚫 Ignore lists: skip tool packages (e.g.
pip,setuptools,wheel) or any custom names. - 🧩 Config file: project-level
.animadao.tomlwith sane defaults and CLI overrides. - 🗃️ PyPI cache: TTL + ETag with configurable concurrency for faster checks.
- 📄 Reports:
--format json | md | html.
Requirements
- Python 3.10+
- uv (modern Python package/dependency manager)
Installation
With uv
pip install uv
uv pip install anima-dao
With pip
pip install anima-dao
From sources
- Clone:
git clone https://github.com/Absolentia/AnimaDao.git
cd AnimaDao
- Install
uv:
pip install --upgrade pip
pip install uv
- Create a virtual env:
uv venv
- Install project deps:
uv sync
Configuration
Create .animadao.toml in your project root (optional):
[core]
mode = "declared" # declared | installed
src = ["src", "app"] # optional, source roots for import scan
# PyPI cache / concurrency
pypi_ttl_seconds = 86400 # default: 24h
pypi_concurrency = 8 # default: 8 parallel requests
[ignore]
distributions = ["pip", "setuptools", "wheel"]
imports = []
CLI flags always override config values.
Usage (CLI)
All commands accept a project root (where either pyproject.toml or requirements.txt resides) and an optional source
root to scan imports.
Scan: declared vs imports
uv run animadao scan --project . --src src
Check against PyPI
Declared dependencies (default mode):
uv run animadao check --project . --mode declared --ignore pip --ignore setuptools
Installed packages in the current venv:
uv run animadao check --project . --mode installed --pypi-ttl 43200 --pypi-concurrency 16
Find unused deps (declared but not imported)
uv run animadao unused --project . --src src --ignore pip --ignore wheel
Generate report
JSON:
uv run animadao report --project . --src src --out report.json --format json
Markdown:
uv run animadao report --project . --src src --out report.md --format md
HTML:
uv run animadao report --project . --src src --out report.html --format html
Example report.json:
{
"summary": {
"declared": 12,
"imports_found": 34,
"outdated": 2,
"unpinned": 7,
"unused": 3
},
"outdated": [
{
"name": "requests",
"current": "2.31.0",
"latest": "2.32.3"
}
],
"unpinned": [
{
"name": "numpy",
"spec": ">=1.26"
}
],
"unused": [
"rich",
"typer"
],
"imports": [
"requests",
"json",
"..."
],
"mode": "declared"
}
Supported dependency sources & priority
When resolving declared dependencies, AnimaDao uses the first matching source:
pyproject.toml— PEP 621[project].dependencies(+[project.optional-dependencies]merged)pyproject.toml— Poetry[tool.poetry.dependencies]python = "^3.10"is ignored- Exact versions become
name==X.Y.Z - Caret
^ranges are converted to PEP 440 intervals (best-effort) - Poetry dev/group deps are not included
requirements.txt— plain lines + nested includes via-r/--requirement
Only the first detected source is used to avoid mixing ecosystems.
How it works (quick notes)
- Import mapping: compares normalized distribution names (
-→_) with top-level imports. Known alias:beautifulsoup4↔bs4. - Modes:
declared: checks only==pins from declarations; non-pinned specs appear underunpinned.installed: checks versions of packages currently installed in the environment.
- Networking: PyPI queries via
httpxwith timeouts, using a TTL/ETag cache; failures fall back to cached data.
CI & Releases
- CI (
ci.yml): runspytestwithuvon every push/PR tomain(matrix: Python 3.10–3.13). - Tagger (
tag.yml): manual taggingvX.Y.Z. - Publish: recommended trigger by tag
v*or viaworkflow_runafter tagger.
Create a release:
# bump version in pyproject.toml
git commit -am "chore: bump version to 0.1.1"
git tag -a v0.1.1 -m "v0.1.1"
git push origin v0.1.1
Support matrix
- Python: 3.10 / 3.11 / 3.12 / 3.13
- OS: Linux, macOS, Windows
- Packaging: PEP 621 (project), Poetry, requirements.txt
- Manager:
uv(install & run)
Troubleshooting
-
No module named build
uv pip install build twineoruv sync --extra dev. -
Hatch: “Unable to determine which files to ship”
Ensure package directory exists and add topyproject.toml:[tool.hatch.build.targets.wheel] packages = ["anima_dao"]
-
Publish doesn’t start after tagger
Events fromGITHUB_TOKENdon’t trigger other workflows. Push tag with a PAT or useworkflow_runtrigger. -
403 after moving repo to org
Update remote:git remote set-url origin git@github.com:<ORG>/AnimaDao.gitand check org permissions/SSO.
Contributing
pip install uv
uv sync --extra dev
uv run pytest -vvvv
Please keep type hints (3.10+), docstrings and comments in English, and add tests for new loaders/edge cases.
pre-commit
- Add AnimaDao hooks to
.pre-commit-config.yaml:
repos:
- repo: https://github.com/Absolentia/AnimaDao
rev: v0.1.2 # <-- use the latest tag
hooks:
- id: animadao-check
args: [ --ignore, pip, --ignore, setuptools ]
files: '^(pyproject.toml|requirements.*txt|.*\.py)$'
- id: animadao-report
stages: [ manual ] # optional: run on-demand via `pre-commit run -a animadao-report`
- Install and run:
pip install pre-commit
pre-commit install
pre-commit run -a
Policy examples:
- Fail on outdated pins only:
- id: animadao-check args: [--mode, declared, --fail-if-outdated]
- Strict mode (declared): no outdated, no unpinned, no unused:
- id: animadao-check args: [--mode, declared, --fail-if-outdated, --fail-if-unpinned, --max-unused, "0"]
- Installed mode (CI on lockstep env):
- id: animadao-check-installed args: [--fail-if-outdated]
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 anima_dao-0.2.0.tar.gz.
File metadata
- Download URL: anima_dao-0.2.0.tar.gz
- Upload date:
- Size: 17.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08a17e5a5ae1aface43c4acd4a35b5057b222f331070e42d202f5d08bc0dd85b
|
|
| MD5 |
7a8c0f2f228fa472d6044737df0bfbd6
|
|
| BLAKE2b-256 |
8706e73cb224750bb8113c9857813f3cc171d4b32d673191634e25acf6b01690
|
File details
Details for the file anima_dao-0.2.0-py3-none-any.whl.
File metadata
- Download URL: anima_dao-0.2.0-py3-none-any.whl
- Upload date:
- Size: 19.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e40015d8039ddad4a27ddbcb5c0f65a9b6ca2ebe473a5eb3539a5f26633fa16a
|
|
| MD5 |
fb2a87643af4941555b0454dc41ba763
|
|
| BLAKE2b-256 |
e8cfd450cc2dd754b8ebb481b8fc8c78ca8c088bdd46047c4cacd109bf950f49
|