neuropose/docs/development.md

5.6 KiB

Development

This page is for contributors working on NeuroPose itself.

Environment setup

NeuroPose uses uv for dependency management and Python 3.11. After cloning the repository:

uv venv --python 3.11
source .venv/bin/activate
uv sync --group dev
uv run pre-commit install

uv sync --group dev installs the project in editable mode alongside the full dev dependency set (pytest, ruff, pyright, pre-commit, mkdocs-material, and mkdocstrings).

pre-commit install wires the git hooks declared in .pre-commit-config.yaml into your local repo so every commit is linted, formatted, and scanned for secrets before it lands.

Running tests

Unit tests are fast and do not require the MeTRAbs model or TensorFlow inference:

uv run pytest

Integration tests that require a downloaded model are marked with @pytest.mark.slow and are skipped by default. Run them with:

uv run pytest -m slow

Run a specific test file or test class:

uv run pytest tests/unit/test_estimator.py
uv run pytest tests/unit/test_estimator.py::TestProcessVideo
uv run pytest -k "frame_count"

The autouse _isolate_environment fixture in tests/conftest.py points $HOME and $XDG_DATA_HOME at a per-test temp directory, so no test can accidentally write to your real home directory. It also clears any NEUROPOSE_* variables from your shell so test outcomes do not depend on who is running them.

Linting and formatting

NeuroPose uses ruff for both lint and format. Configuration lives in pyproject.toml under [tool.ruff].

uv run ruff check .          # Lint
uv run ruff check --fix .    # Lint + auto-fix
uv run ruff format .         # Format (equivalent to black)
uv run ruff format --check . # Verify formatted

The selected lint rules are deliberately broad — pycodestyle, pyflakes, isort, bugbear, pyupgrade, simplify, ruff-specific, pep8-naming, comprehensions, pathlib, pytest-style, tidy-imports, numpy-specific, and pydocstyle (numpy convention). The rationale is "lint noise early rather than cruft late": we would rather annoy a contributor with a style fix than let a real bug slip through because the linter was lax.

Type checking

NeuroPose uses pyright in standard mode (not strict — the TensorFlow / OpenCV / scikit-learn stubs would generate thousands of false positives under strict). The plan is to tighten toward strict after the MeTRAbs stack is pinned in commit 11.

uv run pyright

Documentation

Documentation is built with MkDocs and the Material theme. API reference pages are auto-generated from the source docstrings by mkdocstrings.

Live preview at http://localhost:8000:

uv run mkdocs serve

Strict build (the same one CI runs):

uv run mkdocs build --strict

--strict promotes every warning (broken internal link, missing nav entry, unparseable docstring) to an error, so broken docs fail the build instead of silently producing a broken site.

Adding a new module means:

  1. Write it with numpy-style docstrings (the plugin's docstring_style: numpy setting).
  2. Add a stub page under docs/api/ containing a single ::: directive:
    ::: neuropose.your_module
    
  3. Add a nav entry in mkdocs.yml under API Reference.

Project structure

neuropose/
├── src/neuropose/              # The package itself
│   ├── config.py               # pydantic-settings Settings class
│   ├── estimator.py            # per-video MeTRAbs worker
│   ├── interfacer.py           # filesystem-polling daemon
│   ├── visualize.py            # matplotlib overlay rendering
│   ├── io.py                   # prediction schema + atomic save/load
│   ├── cli.py                  # typer CLI entrypoint
│   ├── _model.py               # MeTRAbs loader (stub pending commit 11)
│   └── analyzer/               # post-processing (pending commit 10)
├── tests/
│   ├── conftest.py             # isolated env + synthetic video fixtures
│   ├── unit/                   # fast, no model download
│   └── integration/            # marked slow, downloads the model
├── docs/                       # this documentation
├── .github/workflows/          # CI + docs workflows
├── pyproject.toml              # package metadata, deps, tool configs
└── mkdocs.yml                  # docs site configuration

Commit hygiene

  • Small commits. Each commit should do one thing and leave the repo in a green-CI state.
  • Descriptive commit messages. The body should explain why, not restate the diff. References to audit sections or issue numbers are welcome.
  • No force-push on main. Use a feature branch and open a merge request on the primary forge. main is protected; the CI checks must pass before merging.
  • No git commit --no-verify. If a pre-commit hook fails, fix the underlying issue rather than skipping the hook. The hooks exist because the previous prototype was the poster child for what happens when hygiene slips.

Release process

To be documented when the first tagged release is cut. The short version of the plan:

  1. Bump version in pyproject.toml and __version__ in src/neuropose/__init__.py.
  2. Update CHANGELOG.md.
  3. Tag the commit (git tag v0.1.0).
  4. Push the tag. A release workflow builds the wheel + sdist and uploads to PyPI once we claim the name.