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:
- Write it with numpy-style docstrings (the plugin's
docstring_style: numpysetting). - Add a stub page under
docs/api/containing a single:::directive:::: neuropose.your_module - Add a nav entry in
mkdocs.ymlunderAPI 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.mainis 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:
- Bump
versioninpyproject.tomland__version__insrc/neuropose/__init__.py. - Update
CHANGELOG.md. - Tag the commit (
git tag v0.1.0). - Push the tag. A release workflow builds the wheel + sdist and uploads to PyPI once we claim the name.