diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ecc76a..774c62e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -128,6 +128,48 @@ jobs: run: | uv run pytest --cov-fail-under=48 + docs: + name: Docs (build + linkcheck) + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Set up uv + uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 + with: + python-version: "3.12" + enable-cache: true + + - name: Sync docs dependency group + run: | + uv sync --locked --group docs --no-dev + + - name: Build HTML docs (warnings are errors) + run: | + uv run sphinx-build -b html -W --keep-going docs docs/_build/html + + - name: Link check (non-blocking) + continue-on-error: true + run: | + uv run sphinx-build -b linkcheck docs docs/_build/linkcheck + + - name: Upload rendered HTML artifact + uses: actions/upload-artifact@v4 + with: + name: docs-html-${{ github.sha }} + path: docs/_build/html + if-no-files-found: error + + - name: Upload linkcheck report + if: always() + uses: actions/upload-artifact@v4 + with: + name: docs-linkcheck-${{ github.sha }} + path: docs/_build/linkcheck + if-no-files-found: warn + package-briefcase-zip: name: Package Briefcase ZIP (Windows) runs-on: windows-latest diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 979e9c4..3bb6b3e 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -3,15 +3,19 @@ version: 2 build: os: ubuntu-22.04 tools: - python: "3.11" + python: "3.12" jobs: pre_install: - python -m pip install --upgrade pip - python -m pip install uv install: - - UV_PROJECT_ENVIRONMENT="${READTHEDOCS_VIRTUALENV_PATH}" uv pip install -r docs/requirements.txt - - UV_PROJECT_ENVIRONMENT="${READTHEDOCS_VIRTUALENV_PATH}" uv pip install . + # Install the project plus the "docs" dependency group (pyproject.toml + # -> [dependency-groups].docs) into the RTD-managed virtualenv, honoring + # uv.lock for reproducibility. No dev/build groups are needed to render docs. + - UV_PROJECT_ENVIRONMENT="${READTHEDOCS_VIRTUALENV_PATH}" uv sync --locked --group docs --no-dev sphinx: configuration: docs/conf.py - fail_on_warning: false + # Treat Sphinx warnings as errors. Known harmless warnings are suppressed + # via `suppress_warnings` in docs/conf.py rather than relaxed here. + fail_on_warning: true diff --git a/docs/conf.py b/docs/conf.py index fecfeb1..88911af 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -8,17 +8,28 @@ project = "Clinical DBS Annotator" author = "Lucia Poma" release = metadata.version(_DIST_NAME) +version = ".".join(release.split(".")[:2]) copyright = f"2025-{datetime.now().year}, {author}" extensions = [ "sphinx.ext.autodoc", "sphinx.ext.napoleon", "sphinx.ext.viewcode", + "sphinx.ext.intersphinx", + "sphinx_copybutton", ] templates_path = ["_templates"] exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] +# Known, non-actionable warnings that would otherwise fail `-W` builds. +# `image.not_readable` covers screenshots under docs/_static/ that are +# re-generated from the running app and not committed to git (tracked in +# the documentation strategy, P3: screenshot pipeline). +suppress_warnings = [ + "image.not_readable", +] + html_theme = "sphinx_rtd_theme" html_static_path = ["_static"] @@ -30,3 +41,14 @@ "sticky_navigation": True, "navigation_depth": 3, } + +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), +} + +# `linkcheck` tuning: timeout aggressive, retry transient failures, and ignore +# anchor-only link failures on sites that rewrite fragments (common on GitHub). +linkcheck_timeout = 15 +linkcheck_retries = 2 +linkcheck_anchors = False +linkcheck_ignore: list[str] = [] diff --git a/docs/contributing.rst b/docs/contributing.rst index b85fc70..5b39d48 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -1,7 +1,9 @@ Contributing to Clinical DBS Annotator ====================================== -We welcome contributions to the Clinical DBS Annotator! This document provides guidelines for contributors who want to help improve this open-source software for deep brain stimulation research. +We welcome contributions to the Clinical DBS Annotator! This page is the +authoritative contributor guide for the repository. The short +``CONTRIBUTING.md`` at the repository root is a pointer into this page. .. contents:: :local: @@ -15,10 +17,15 @@ Prerequisites To contribute to this project, you should have: -- Python 3.11 or higher -- Git installed and configured -- Basic knowledge of PyQt5/PyQt6 (helpful but not required) -- Understanding of deep brain stimulation concepts (helpful but not required) +- **Python 3.12 or newer** (matches ``requires-python`` in ``pyproject.toml``; + CI tests on 3.12, 3.13, and 3.14). +- **uv** (https://github.com/astral-sh/uv) for dependency management and + running tools. +- **Git** installed and configured. +- Familiarity with **PySide6 / Qt** is helpful but not required. The codebase + follows a Model-View-Controller (MVC) structure under ``src/dbs_annotator/``. +- Understanding of deep brain stimulation concepts is helpful for clinical + contributions but not required for code or documentation work. Development Setup ~~~~~~~~~~~~~~~~~ @@ -27,19 +34,44 @@ Development Setup .. code-block:: bash - git clone https://github.com/yourusername/App_ClinicalDBSAnnot.git + git clone https://github.com//App_ClinicalDBSAnnot.git cd App_ClinicalDBSAnnot -2. **Make sure uv is installed. Then, create a virtual environment and install dependencies**: +2. **Create the virtual environment and install all dev dependencies** + (``uv`` reads ``pyproject.toml`` and ``uv.lock``; no manual ``venv`` + activation is needed): + .. code-block:: bash - - uv sync -3. **Run the application** to verify installation: + uv sync --locked --dev + + To additionally install the Briefcase packaging tools, use the ``build`` + group: .. code-block:: bash - uv run python -m clinical_dbs_annotator + uv sync --locked --dev --group build + + To build the documentation locally, use the ``docs`` group: + + .. code-block:: bash + + uv sync --locked --group docs --no-dev + +3. **Install the git pre-commit hooks** (ruff, ty, actionlint, ``uv lock`` + check): + + .. code-block:: bash + + uv run pre-commit install + +4. **Run the application** to verify the installation: + + .. code-block:: bash + + uv run python -m dbs_annotator + # or, equivalently, using the convenience entry point + uv run python run.py Types of Contributions ---------------------- @@ -51,59 +83,82 @@ Bug Reports If you find a bug, please: -1. **Check existing issues** to see if it's already reported +1. **Check existing issues** to see if it's already reported. 2. **Create a new issue** with: - - Clear title describing the bug - - Steps to reproduce the issue - - Expected vs actual behavior - - System information (OS, Python version, etc.) - - Screenshots if applicable + + - Clear title describing the bug. + - Steps to reproduce the issue. + - Expected vs actual behaviour. + - System information (OS, Python version, application version from + ``dbs_annotator.__version__``). + - Screenshots or a short screen recording if the issue is in the GUI. Feature Requests ~~~~~~~~~~~~~~~~ For new features: -1. **Check existing issues** for similar requests -2. **Create an issue** describing: - - The feature you'd like to see - - Why it would be useful - - How you envision it working - - Any implementation ideas you have +1. **Check existing issues** for similar requests. +2. **Open an issue** describing: + + - The feature you'd like to see. + - Why it would be useful (clinical motivation, research workflow, etc.). + - How you envision it working. + - Any implementation ideas you have. Code Contributions ~~~~~~~~~~~~~~~~~~ -We accept code contributions through pull requests. Please follow these guidelines: +We accept code contributions through pull requests. Please follow these +guidelines: -1. **Fork and create a branch**: +1. **Create a feature branch** off ``main`` (or the currently active + integration branch): .. code-block:: bash git checkout -b feature/your-feature-name -2. **Make your changes** following our coding standards (see below) +2. **Make your changes** following the coding standards below. + +3. **Run the local quality gate** before pushing: + + .. code-block:: bash -3. **Test your changes** thoroughly + uv run ruff format . + uv run ruff check . + uv run ty check . + uv run pytest -4. **Commit your changes**: +4. **Commit your changes** using a short, descriptive message (Conventional + Commits are encouraged but not required): .. code-block:: bash - git commit -m "feat: add new feature description" + git commit -m "feat: add directional-lead contact picker" -5. **Push to your fork** and create a pull request +5. **Push to your fork** and open a pull request against the upstream + repository. Documentation Improvements ~~~~~~~~~~~~~~~~~~~~~~~~~~ -Documentation is crucial for research software. We welcome: +Documentation lives in this ``docs/`` tree (Sphinx + reStructuredText) plus +``README.md`` and ``CHANGELOG.md`` at the repository root. We welcome: -- Improved README sections -- Better API documentation -- Additional examples and tutorials -- Translation to other languages -- Fixing typos and grammatical errors +- New or revised user-workflow pages. +- API docstring improvements (Google or NumPy style; rendered by + ``sphinx.ext.napoleon``). +- Additional examples, screenshots, or short screencasts. +- Fixing typos and grammatical errors. + +Build the docs locally before submitting: + +.. code-block:: bash + + uv sync --locked --group docs --no-dev + uv run sphinx-build -b html -W --keep-going docs docs/_build/html + uv run sphinx-build -b linkcheck docs docs/_build/linkcheck Code Standards --------------- @@ -111,89 +166,96 @@ Code Standards Style Guidelines ~~~~~~~~~~~~~~~~ -We follow these coding standards: +Formatting and linting are enforced by **ruff** (see ``[tool.ruff]`` in +``pyproject.toml``) and static typing is checked by **ty**. Both run in CI and +as pre-commit hooks, so local runs should stay green. -- **Python**: PEP 8 style guide -- **Docstrings**: Google style or NumPy style -- **Comments**: Clear, concise comments explaining complex logic -- **Variable names**: Descriptive names in snake_case -- **Class names**: PascalCase +- **Formatter**: ``ruff format`` (line length 88). +- **Linter**: ``ruff check`` with rules ``E, W, F, I, N, UP, B, C4``. +- **Type checker**: ``ty check .``. +- **Docstrings**: Google or NumPy style (Napoleon is enabled). +- **Naming**: ``snake_case`` for functions and variables; ``PascalCase`` for + classes; module-private names prefixed with a single underscore. Example: .. code-block:: python - def calculate_stimulation_amplitude(self, contact_states: Dict) -> float: - """Calculate the total stimulation amplitude for given contact states. - + def calculate_total_amplitude( + contact_states: dict[int, ContactState], + contact_amplitudes: dict[int, float], + ) -> float: + """Sum the cathodic amplitude contributed by each active contact. + Args: - contact_states: Dictionary mapping contact indices to their states - + contact_states: Mapping from contact index to its active state. + contact_amplitudes: Mapping from contact index to amplitude in mA. + Returns: - Total stimulation amplitude in milliamps - + Total delivered cathodic amplitude in milliamps. + Raises: - ValueError: If contact states are invalid + ValueError: If ``contact_states`` is empty. """ if not contact_states: raise ValueError("Contact states cannot be empty") - - total_amplitude = 0.0 + + total = 0.0 for contact_idx, state in contact_states.items(): - if state == ContactState.CATHODIC: - total_amplitude += self.contact_amplitudes.get(contact_idx, 0.0) - - return total_amplitude + if state is ContactState.CATHODIC: + total += contact_amplitudes.get(contact_idx, 0.0) + return total Testing ~~~~~~~ -All new features should include tests: +All new features should include tests. The project uses **pytest** with +``pytest-qt`` for GUI interaction tests. -1. **Unit tests** for individual functions/classes -2. **Integration tests** for GUI interactions -3. **Manual testing** for user workflows +- **Unit tests** for models, utilities, and pure-logic controllers. +- **GUI tests** using ``pytest-qt`` (``qtbot`` fixture) for widget behaviour. +- **Integration tests** marked with ``@pytest.mark.integration`` for + cross-module behaviour. +- Slow flows may be marked ``@pytest.mark.slow`` and skipped locally with + ``pytest -m "not slow"``. -Test structure: +Example: .. code-block:: python - import unittest - from clinical_dbs_annotator.models.electrode_viewer import ElectrodeCanvas - - class TestElectrodeCanvas(unittest.TestCase): - def setUp(self): - self.canvas = ElectrodeCanvas() - - def test_scale_calculation(self): - """Test that scale calculation works correctly.""" - # Mock electrode model - mock_model = Mock() - mock_model.num_contacts = 8 - mock_model.contact_height = 1.5 - mock_model.contact_spacing = 0.5 - - self.canvas.model = mock_model - scale = self.canvas.calculate_scale() - - self.assertIsInstance(scale, float) - self.assertGreater(scale, 0) + import pytest + from dbs_annotator.models.electrode_viewer import ElectrodeCanvas + + + @pytest.mark.gui + def test_electrode_canvas_scales_to_widget(qtbot): + canvas = ElectrodeCanvas() + qtbot.addWidget(canvas) + canvas.resize(400, 600) + assert canvas.calculate_scale() > 0 Run tests with: .. code-block:: bash - python -m pytest tests/ + uv run pytest + +On headless Linux (including CI) set ``QT_QPA_PLATFORM=offscreen`` so Qt does +not require a display server: + +.. code-block:: bash + + QT_QPA_PLATFORM=offscreen uv run pytest GUI Testing ~~~~~~~~~~~ -For GUI components: +For Qt components: -1. **Test widget creation** doesn't crash -2. **Test user interactions** (clicks, inputs) -3. **Test data flow** between components -4. **Test error handling** in user interactions +1. **Test widget construction** using the ``qtbot`` fixture. +2. **Test user interactions** (clicks, key presses, text input). +3. **Test data flow** between views, controllers, and models. +4. **Test error handling** paths surfaced through the UI. Pull Request Process -------------------- @@ -201,11 +263,19 @@ Pull Request Process Before Submitting ~~~~~~~~~~~~~~~~~ -1. **Update documentation** if needed -2. **Add tests** for new functionality -3. **Run all tests** and ensure they pass -4. **Check code style** with tools like flake8 or black -5. **Test the application** manually +1. **Update documentation** in ``docs/`` when user-visible behaviour changes. +2. **Update** ``CHANGELOG.md`` under ``[Unreleased]`` using the Keep a + Changelog format. +3. **Add or update tests** for new functionality. +4. **Run the local quality gate**: ``ruff format``, ``ruff check``, + ``ty check``, ``pytest``. +5. **Regenerate the lockfile** if you changed dependencies in + ``pyproject.toml`` (including the ``build`` group used by Briefcase) and + commit the updated ``uv.lock``: + + .. code-block:: bash + + uv lock Pull Request Template ~~~~~~~~~~~~~~~~~~~~~ @@ -213,37 +283,44 @@ Pull Request Template When creating a pull request, please include: **Description** -- Brief description of changes -- Why these changes are needed -- How you tested the changes + +- Brief description of the change. +- Motivation (clinical workflow, bug, refactor, documentation, etc.). +- Notes on how you tested the change. **Type of Change** -- [ ] Bug fix -- [ ] New feature -- [ ] Breaking change -- [ ] Documentation update -**Testing** -- [ ] Unit tests pass -- [ ] Manual testing completed -- [ ] GUI testing completed +- Bug fix +- New feature +- Breaking change +- Documentation update +- Build / CI / packaging change **Checklist** -- [ ] Code follows project style guidelines -- [ ] Self-review completed -- [ ] Documentation updated -- [ ] Tests added/updated + +- Code follows the project style (ruff, ty clean). +- Tests added or updated and passing locally. +- Documentation updated (``docs/`` and/or ``README.md``). +- ``CHANGELOG.md`` updated under ``[Unreleased]``. +- ``uv.lock`` regenerated if dependencies changed. Review Process ~~~~~~~~~~~~~~ Our review process: -1. **Automated checks** (tests, code style) -2. **Peer review** by maintainers -3. **Discussion** of any required changes -4. **Testing** by reviewer -5. **Approval** and merge +1. **Automated checks** via GitHub Actions: + + - ``actionlint`` on workflow files. + - ``uv audit`` for dependency vulnerabilities. + - ``ruff`` (lint + format) and ``ty`` (type check). + - ``pytest`` on Ubuntu, Windows, and macOS with a coverage floor. + - Briefcase ZIP packaging smoke test on Windows. + - Documentation build (Sphinx ``-W``) and link check. + +2. **Peer review** by maintainers. +3. **Discussion** of any required changes. +4. **Approval** and merge. Community Guidelines -------------------- @@ -253,48 +330,36 @@ Code of Conduct We are committed to providing a welcoming and inclusive environment. Please: -- Be respectful and professional -- Welcome newcomers and help them learn -- Focus on constructive feedback -- Assume good intentions -- Be patient with different perspectives +- Be respectful and professional. +- Welcome newcomers and help them learn. +- Focus on constructive feedback. +- Assume good intentions. +- Be patient with different perspectives. Communication Channels ~~~~~~~~~~~~~~~~~~~~~~ -- **GitHub Issues**: For bug reports and feature requests -- **GitHub Discussions**: For general questions and ideas -- **Pull Requests**: For code contributions - -Getting Help -~~~~~~~~~~~~ - -If you need help contributing: - -1. **Check existing issues** and discussions -2. **Read the documentation** thoroughly -3. **Ask questions** in GitHub Discussions -4. **Contact maintainers** if needed +- **GitHub Issues** — for bug reports and feature requests. +- **GitHub Discussions** — for general questions and ideas. +- **Pull Requests** — for code, documentation, and CI contributions. Recognition -~~~~~~~~~~~~ +~~~~~~~~~~~ -Contributors are recognized through: +Contributors are recognised through: -- **Author credits** in commit history -- **Contributors section** in README -- **Co-authorship** opportunities for significant contributions -- **Acknowledgments** in publications +- Author credits in the commit history. +- Acknowledgements in release notes and, where appropriate, in publications. Research Impact ~~~~~~~~~~~~~~~ -This software is designed for research use. If you use or extend this software in your research: +This software is designed for clinical research use. If you use or extend it +in your research: -- **Cite the software** in your publications -- **Let us know** about your use cases -- **Share feedback** to help improve the software -- **Consider contributing** improvements back +- **Cite the software** in your publications. +- **Share feedback** so we can improve future versions. +- **Consider contributing** improvements back to the upstream repository. Development Workflow --------------------- @@ -302,69 +367,82 @@ Development Workflow Branch Strategy ~~~~~~~~~~~~~~~ -We use a simple branching strategy: +We use a simple trunk-based strategy: -- ``main``: Stable production code -- ``develop``: Integration branch for features -- ``feature/*``: Feature development branches -- ``bugfix/*``: Bug fix branches -- ``hotfix/*``: Critical fixes for production +- ``main`` — integration branch; always releasable. +- ``feature/*`` — feature development branches. +- ``fix/*`` — bug-fix branches. +- ``docs/*`` — documentation-only branches. +- ``enh/*`` — larger enhancement / refactor branches. Release Process ~~~~~~~~~~~~~~~ -1. **Update version number** in setup.py -2. **Update changelog** with new features and fixes -3. **Create release tag** on GitHub -4. **Upload to PyPI** (if applicable) -5. **Update documentation** +1. Update ``dbs_annotator.__version__`` in + ``src/dbs_annotator/__init__.py`` (Hatch reads this as the distribution + version) and, if it changed, ``[tool.briefcase].version`` in + ``pyproject.toml``. These two values must match. +2. Move the ``[Unreleased]`` section of ``CHANGELOG.md`` to a new + ``[X.Y.Z] - YYYY-MM-DD`` section. +3. Open a release PR, land it on ``main``, then push the matching + ``vX.Y.Z`` tag. +4. The ``CD - Create GitHub Release`` workflow builds Python wheels/sdist and + Briefcase installers (Windows MSI, macOS DMG, Linux system package), then + creates the GitHub Release with artifacts attached. +5. Read the Docs publishes the matching versioned documentation from the tag. Continuous Integration -~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~ -We use GitHub Actions for: +GitHub Actions handles: -- **Automated testing** on multiple Python versions -- **Code style checks** -- **Documentation building** -- **Package building** +- Workflow linting (``actionlint``). +- Dependency auditing (``uv audit``). +- Lint, format, and type checking (ruff, ty). +- Cross-platform tests (Ubuntu, Windows, macOS) with coverage. +- Briefcase ZIP packaging smoke test on Windows. +- Documentation build and link check. +- Release builds for Python wheels/sdist and Briefcase installers. -Specialized Contributions +Specialised Contributions -------------------------- Clinical Domain Experts ~~~~~~~~~~~~~~~~~~~~~~~ -If you're a clinical researcher or DBS specialist: +If you are a clinician or DBS specialist: -- **Share use cases** and workflows -- **Suggest improvements** based on clinical needs -- **Provide feedback** on electrode models and stimulation patterns -- **Help validate** clinical accuracy +- Share real-world session workflows and edge cases. +- Review and suggest improvements to clinical scale presets. +- Provide feedback on electrode model definitions and contact diagrams. +- Help validate clinical accuracy of exported reports. -GUI/UX Experts -~~~~~~~~~~~~~~ +GUI / UX Contributors +~~~~~~~~~~~~~~~~~~~~~ -For contributors with GUI expertise: +For contributors with design expertise: -- **Improve user interface** design -- **Enhance user experience** workflows -- **Test accessibility** features -- **Suggest visual improvements** +- Improve the interaction design of the wizard steps. +- Enhance the responsive behaviour on smaller displays. +- Test accessibility (keyboard navigation, screen readers, contrast). +- Propose visual refinements to the light and dark themes. Data Scientists ~~~~~~~~~~~~~~~ -For data science contributions: +For data-science contributions: -- **Improve data analysis** features -- **Add statistical tools** for outcome analysis -- **Enhance longitudinal reporting** -- **Integrate with external tools** +- Improve analysis features in the longitudinal report. +- Add statistical tooling for outcome analysis. +- Enhance the BIDS-compliant TSV schema and export. +- Integrate with external analysis pipelines. Thank You ----------- +--------- -Thank you for considering contributing to the Clinical DBS Annotator! Your contributions help make deep brain stimulation research more accessible and effective for the research community. +Thank you for considering contributing to the Clinical DBS Annotator! Your +contributions help make deep brain stimulation research more accessible and +reproducible. -For questions about contributing, please open an issue or start a discussion on GitHub. +For questions about contributing, please open an issue or start a discussion +on GitHub. diff --git a/docs/requirements.txt b/docs/requirements.txt deleted file mode 100644 index c462aad..0000000 --- a/docs/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -"sphinx>=9.0.4" -"sphinx-rtd-theme>=3.1.0" \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 32aeccb..81ab16b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,12 +1,20 @@ [project] name = "dbs-annotator" -description = "A graphical user interface for annotating DBS clinical programming sessions" +description = "An application for annotating clinical programming sessions." readme = "README.md" requires-python = ">=3.12" authors = [ - { name = "Lucia Poma", email = "lucia.poma@wysscenter.ch" } + { name = "Lucia Poma", email = "lucia.poma@wysscenter.ch" }, + { name = "Matteo Vissani" }, + { name = "Richard Köhler", email = "richard.koehler@wysscenter.ch" }, +] +keywords = [ + "dbs", + "clinical", + "annotation", + "neuroscience", + "deep-brain-stimulation", ] -keywords = ["dbs", "clinical", "annotation", "neuroscience", "deep-brain-stimulation"] dynamic = ["version"] classifiers = [ "Development Status :: 4 - Beta", @@ -42,21 +50,16 @@ dev = [ "pandas-stubs>=3.0.0.260204", "pyside6-stubs>=6.7.3.0", ] -build = [ - "briefcase>=0.3.26", -] -docs = [ - "sphinx>=9.0.4", - "sphinx-rtd-theme>=3.1.0", -] +build = ["briefcase>=0.3.26"] +docs = ["sphinx>=9.0.4", "sphinx-rtd-theme>=3.1.0", "sphinx-copybutton>=0.5.2"] [project.scripts] dbs-annotator = "dbs_annotator.__main__:main" [project.urls] -Homepage = "https://github.com/bml/dbs-annotator" -Repository = "https://github.com/bml/dbs-annotator" -Documentation = "https://github.com/bml/dbs-annotator/blob/main/README.md" +Homepage = "https://github.com/Brain-Modulation-Lab/App_ClinicalDBSAnnot" +Repository = "https://github.com/Brain-Modulation-Lab/App_ClinicalDBSAnnot" +Documentation = "https://app-clinicaldbsannot.readthedocs.io/en/latest/" [build-system] requires = ["hatchling"] @@ -80,9 +83,7 @@ addopts = [ "--cov-report=html", "--cov-report=term-missing", ] -filterwarnings = [ - "ignore::DeprecationWarning", -] +filterwarnings = ["ignore::DeprecationWarning"] markers = [ "gui: Qt GUI / widget tests", "integration: cross-module behavior", @@ -99,50 +100,38 @@ omit = ["*/tests/*"] [tool.ruff] line-length = 88 target-version = "py312" -extend-exclude = [ - ".eggs", - ".git", - ".hatch", - ".venv", - "build", - "dist", -] +extend-exclude = [".eggs", ".git", ".hatch", ".venv", "build", "dist"] [tool.ruff.lint] select = [ - "E", # pycodestyle errors - "W", # pycodestyle warnings - "F", # pyflakes - "I", # isort - "N", # pep8-naming - "UP", # pyupgrade - "B", # flake8-bugbear - "C4", # flake8-comprehensions -] -ignore = [ - "E501", # line too long (handled by formatter/line-length) + "E", # pycodestyle errors + "W", # pycodestyle warnings + "F", # pyflakes + "I", # isort + "N", # pep8-naming + "UP", # pyupgrade + "B", # flake8-bugbear + "C4", # flake8-comprehensions ] [tool.uv] -# Only resolve/package versions that are at least 1 week old. exclude-newer = "1 week" # BeeWare Briefcase: native installers (Windows MSI / macOS .app + DMG). # App entrypoint: `python -m dbs_annotator` (see src/dbs_annotator/__main__.py). # Project [project] metadata (version via Hatch, dependencies) is merged by Briefcase. [tool.briefcase] -project_name = "Clinical DBS Annotator" +project_name = "DBS Annotator" bundle = "ch.wysscenter.dbsannotator" # Briefcase requires a static version here even when [project] uses dynamic version from Hatch. version = "0.3.0" license = { file = "LICENSE" } [tool.briefcase.app.dbs_annotator] -# Windows stub executable name is "{formal_name}.exe" (see BeeWare windows app template). formal_name = "DBSAnnotator" -description = "A graphical user interface for annotating DBS clinical programming sessions" +description = "An application for annotating clinical programming sessions." long_description = """ -Clinical DBS Annotator is a desktop application used to structure and review +DBS Annotator is a desktop application used to structure and review deep-brain stimulation programming sessions in a reproducible workflow. It supports clinicians and researchers by organizing session information, @@ -151,7 +140,6 @@ tracking stimulation settings, and generating standardized exports and reports. sources = ["src/dbs_annotator", "icons", "styles"] icon = "icons/logoneutral" installer_icon = "icons/logoneutral" -# Force Briefcase's internal pip installer to resolve against live PyPI. requirement_installer_args = [ "--index-url", "https://pypi.org/simple", @@ -163,7 +151,6 @@ requirement_installer_args = [ "60", "--no-cache-dir", ] -# PySide6/Qt GUI (not Toga). Packaging uses the same dependency set as [project]. [tool.briefcase.app.dbs_annotator.macOS] universal_build = false diff --git a/uv.lock b/uv.lock index 773d3a5..dabf2b3 100644 --- a/uv.lock +++ b/uv.lock @@ -11,7 +11,7 @@ resolution-markers = [ ] [options] -exclude-newer = "2026-04-13T11:57:02.9397424Z" +exclude-newer = "2026-04-13T13:19:08.4322388Z" exclude-newer-span = "P1W" [[package]] @@ -468,6 +468,7 @@ dev = [ ] docs = [ { name = "sphinx" }, + { name = "sphinx-copybutton" }, { name = "sphinx-rtd-theme" }, ] @@ -498,6 +499,7 @@ dev = [ ] docs = [ { name = "sphinx", specifier = ">=9.0.4" }, + { name = "sphinx-copybutton", specifier = ">=0.5.2" }, { name = "sphinx-rtd-theme", specifier = ">=3.1.0" }, ] @@ -1927,6 +1929,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/73/f7/b1884cb3188ab181fc81fa00c266699dab600f927a964df02ec3d5d1916a/sphinx-9.1.0-py3-none-any.whl", hash = "sha256:c84fdd4e782504495fe4f2c0b3413d6c2bf388589bb352d439b2a3bb99991978", size = 3921742, upload-time = "2025-12-31T15:09:25.561Z" }, ] +[[package]] +name = "sphinx-copybutton" +version = "0.5.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/2b/a964715e7f5295f77509e59309959f4125122d648f86b4fe7d70ca1d882c/sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd", size = 23039, upload-time = "2023-04-14T08:10:22.998Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/48/1ea60e74949eecb12cdd6ac43987f9fd331156388dcc2319b45e2ebb81bf/sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e", size = 13343, upload-time = "2023-04-14T08:10:20.844Z" }, +] + [[package]] name = "sphinx-rtd-theme" version = "3.1.0"