diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 683408fc..b48496a3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -103,7 +103,7 @@ jobs: python-version: ${{ matrix.python }} - name: Install Dependencies - run: pip install -e .[dev] + run: pip install -r dev-requirements.txt - name: Print installed packages run: pip freeze diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..5784c876 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,122 @@ +# Contributing to labthings-fastapi + +First off, thank you for considering contributing to `labthings-fastapi`! We welcome contributions from everyone, whether it's reporting a bug, suggesting a feature, improving documentation, or writing code. + +This document outlines the processes for getting help, reporting issues, and contributing to the codebase. + +## Seeking Support + +If you have a question about how to use `labthings-fastapi`, or if you are running into trouble: + +* **Check the Documentation:** Please review the official documentation on [readthedocs]. +* **GitHub Discussions / Issues:** If you cannot find the answer, feel free to open an issue on our [GitHub Issues page]. +* **OpenFlexure Community:** Because `labthings-fastapi` is the underlying framework for v3 of the [OpenFlexure Microscope software], you may also find support by engaging with the broader [OpenFlexure Forum]. + +## Reporting Issues or Bugs + +If you find a bug or have a feature request, please report it by opening an issue on our [GitHub Issues page]. + +When reporting an issue, please include as much detail as possible: + +* **Description:** A clear and concise description of what the bug is. +* **Reproduction steps:** How can we reproduce the problem? (A minimal reproducible example is highly appreciated). +* **Expected behaviour:** What did you expect to happen? +* **Environment:** Include your OS, Python version, and `labthings-fastapi` version. Include full error tracebacks if applicable. + +## Contributing Code or Documentation + +We welcome pull requests for bug fixes, new features, and documentation improvements. + +### 1. Local Development Setup + +To work on the code, you will need to clone the repository and install the development dependencies. +Please see the [installation notes](./README.md#installation-notes) for more detail about compatible Python versions and Windows installation. + +```bash +# Clone the repository +git clone https://github.com/labthings/labthings-fastapi.git +cd labthings-fastapi + +# Install the package in editable mode with development dependencies +pip install -r dev-requirements.txt +``` + +### 2. Linting and Testing + +We use several tools to maintain code quality. All of these run in CI with [GitHub Actions], but you should run them locally before submitting a Pull Request. Both `ruff` and `flake8` are configured from [`pyproject.toml`]. + +* **Linting:** We use [`ruff`] for fast linting and formatting. We highly recommend setting up a pre-commit hook to ensure [`ruff`] passes on every commit. + ```bash + ruff format --check + ruff check . + ``` + +* **Docstrings:** [`flake8`] is primarily used to enable stricter checks on docstrings. + ```bash + flake8 src + ``` + +* **Spelling:** We use [`codespell`] to prevent common spelling mistakes in code and documentation. + ```bash + codespell . + ``` + +* **Type Checking:** We use [`mypy`] for static type checking. It is configured in `pyproject.toml`. + ```bash + mypy + ``` + +* **Testing:** We use [`pytest`] for our test suite and test coverage. Ensure all tests pass locally. + ```bash + pytest --cov=src + ``` + +### 3. Managing Dependencies + +Dependencies are defined in [`pyproject.toml`]. If you need to compile a `dev-requirements.txt` file (e.g., for reproducible CI/CD or local isolated environments), you can do so using [`uv`]: + +```bash +uv pip compile --extra dev pyproject.toml --output-file dev-requirements.txt +``` + +*(If you're not using `uv`, regular `pip-compile` from `pip-tools` will achieve the same thing).* + +### 4. Submitting a Pull Request (PR) + +All changes to the codebase must go via pull requests. Unless you are a core maintainer with write access, please use the standard fork-and-branch workflow: + +1. **Fork the repository** to your own GitHub account using the "Fork" button at the top of the repository page. +2. **Clone your fork** locally and set up the upstream remote: + ```bash + git clone https://github.com/YOUR-USERNAME/labthings-fastapi.git + cd labthings-fastapi + git remote add upstream https://github.com/labthings/labthings-fastapi.git + ``` +3. **Create a new branch** for your feature or bugfix: + ```bash + git checkout -b feature-name + ``` +4. **Commit your changes** with clear, descriptive commit messages. +5. **Push your branch** up to your fork: + ```bash + git push origin feature-name + ``` +6. **Open a Pull Request** against the `main` branch of the `labthings/labthings-fastapi` repository. + +**Pull Request Guidelines:** + +* Code should only be merged once all the checks in the CI test job are passing. +* **Unpinned Dependencies:** Note that we have a specific CI job called `test-with-unpinned-dependencies`. It is acceptable to merge code if only this specific job fails, provided the failure is due to upstream dependency issues. We prefer to deal with upstream dependency issues in a separate PR, particularly when the required fixes are distinct from the code in your current PR. The same applies to the `pip-audit` job. +* Update documentation (`docs/` or docstrings) if your changes modify existing behavior or add new features. + +[readthedocs]: https://labthings-fastapi.readthedocs.io/ +[GitHub Issues page]: https://github.com/labthings/labthings-fastapi/issues +[OpenFlexure Forum]: https://openflexure.discourse.group/ +[OpenFlexure Microscope software]: https://gitlab.com/openflexure/openflexure-microscope-server/ +[GitHub Actions]: https://github.com/labthings/labthings-fastapi/actions +[`ruff`]: https://docs.astral.sh/ruff/ +[`pyproject.toml`]: ./pyproject.toml +[`flake8`]: https://flake8.pycqa.org/en/latest/ +[`mypy`]: https://mypy-lang.org/ +[`pytest`]: https://docs.pytest.org/en/stable/ +[`uv`]: https://docs.astral.sh/uv/ \ No newline at end of file diff --git a/README.md b/README.md index 93dbb005..3cb7c009 100644 --- a/README.md +++ b/README.md @@ -11,19 +11,18 @@ Documentation, including install instructions, is available on [readthedocs]. See [readthedocs] for installation instructions that are automatically tested. You can install this package with `pip install labthings-fastapi`. -## Developer notes -For the latest development version, clone this repository and run `pip install -e .[dev]`. +### Installation Notes -The code is linted with `ruff .`, type checked with `mypy`, and tested with `pytest`. These all run in CI with GitHub Actions. We recommend a [pre-commit hook] to ensure `ruff` passes on every commit. `flake8` is also run in CI, primarily to enable stricter checks on docstrings. It is run as `flake8 src`. `ruff` and `flake8` are both configured from `pyproject.toml`. +`labthings-fastapi` supports **Python 3.10, 3.11, 3.12, and 3.13**. The upper limit is strictly capped at 3.13 due to current `pydantic-core` dependencies. -All changes to the codebase should go via pull requests, and should only be merged once all the checks in the `test` job are passing. It is preferable to merge code where the `test-with-unpinned-dependencies` job fails, and deal with the dependency issues in another PR, particularly where the required changes are distinct from the code in the PR. +> **Note: Windows Installations on devices with ARM processors** +> +> Installing on Windows devices with ARM processors requires Visual Studio with the **"Desktop development with C++"** workload enabled. This is necessary because `pydantic` relies on Rust, which in turn requires C++ build tools to compile. +> +> *If you are using a centrally managed machine, you will need administrator privileges to install these system-level dependencies.* -Dependencies are defined in `pyproject.toml` and can be compiled to `dev-requirements.txt` with: -``` -uv pip compile dev-requirements.in -o dev-requirements.txt -``` -If you're not using `uv`, just regular `pip-compile` from `pip-tools` should do the same thing. +For instructions on how to set up a development environment, run tests, and contribute to this project, please see [CONTRIBUTING.md]. ## Demo @@ -34,3 +33,4 @@ See [readthedocs] for a runnable demo. [OpenFlexure Microscope software]: https://gitlab.com/openflexure/openflexure-microscope-server/ [pre-commit hook]: https://openflexure.org/contribute#use-git-hooks-for-ci-checks [readthedocs]: https://labthings-fastapi.readthedocs.io/ +[CONTRIBUTING.md]: ./CONTRIBUTING.md diff --git a/dev-requirements.txt b/dev-requirements.txt index d5a51512..7ca9f741 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -64,6 +64,7 @@ docstring-parser-fork==0.0.14 # via pydoclint docutils==0.21.2 # via + # myst-parser # restructuredtext-lint # sphinx # sphinx-prompt @@ -80,10 +81,6 @@ email-validator==2.3.0 # via # fastapi # pydantic -exceptiongroup==1.3.1 - # via - # anyio - # pytest fastapi==0.135.4 # via labthings-fastapi fastapi-cli==0.0.27 @@ -143,6 +140,7 @@ itsdangerous==2.2.0 jinja2==3.1.6 # via # fastapi + # myst-parser # sphinx # sphinx-autoapi # sphinx-jinja2-compat @@ -154,14 +152,19 @@ jsonschema-specifications==2025.9.1 # via jsonschema librt==0.11.0 # via mypy -markdown-it-py==4.2.0 - # via rich +markdown-it-py==3.0.0 + # via + # mdit-py-plugins + # myst-parser + # rich markupsafe==3.0.3 # via # jinja2 # sphinx-jinja2-compat mccabe==0.7.0 # via flake8 +mdit-py-plugins==0.6.1 + # via myst-parser mdurl==0.1.2 # via markdown-it-py msgpack==1.2.1 @@ -170,6 +173,8 @@ mypy==1.20.2 # via labthings-fastapi mypy-extensions==1.1.0 # via mypy +myst-parser==4.0.1 + # via labthings-fastapi natsort==8.4.0 # via domdf-python-tools numpy==2.2.6 @@ -233,6 +238,7 @@ python-multipart==0.0.32 pyyaml==6.0.3 # via # fastapi + # myst-parser # sphinx-autoapi # uvicorn referencing==0.37.0 @@ -281,6 +287,7 @@ sphinx==8.1.3 # via # autodocsumm # labthings-fastapi + # myst-parser # sphinx-autoapi # sphinx-autodoc-typehints # sphinx-prompt @@ -318,22 +325,14 @@ sphinxcontrib-serializinghtml==2.0.0 # via sphinx sphobjinv==2.4 # via labthings-fastapi +standard-imghdr==3.10.14 + # via sphinx-jinja2-compat starlette==1.3.1 # via fastapi tabulate==0.10.0 # via sphinx-toolbox tinycss2==1.5.1 # via dict2css -tomli==2.4.1 - # via - # coverage - # fastapi-cli - # flake8-pyproject - # labthings-fastapi - # mypy - # pydoclint - # pytest - # sphinx typer==0.26.7 # via # fastapi-cli @@ -342,23 +341,17 @@ types-jsonschema==4.26.0.20260518 # via labthings-fastapi typing-extensions==4.15.0 # via - # anyio - # astroid # beautifulsoup4 # domdf-python-tools - # exceptiongroup # fastapi # labthings-fastapi # mypy # pydantic # pydantic-core # pydantic-extra-types - # referencing # rich-toolkit # sphinx-toolbox - # starlette # typing-inspection - # uvicorn typing-inspection==0.4.2 # via # fastapi diff --git a/docs/source/_windows_arm_note.rst b/docs/source/_windows_arm_note.rst new file mode 100644 index 00000000..9fb2c390 --- /dev/null +++ b/docs/source/_windows_arm_note.rst @@ -0,0 +1,6 @@ +.. note:: + **Windows Installations on devices with ARM Processors** + + Installing on Windows devices with ARM processors requires `Visual Studio`_ with the **"Desktop development with C++"** workload enabled. This is necessary because ``pydantic`` relies on Rust_, which in turn requires C++ build tools to compile. + + *If you are using a centrally managed machine, you will need administrator privileges to install these system-level dependencies.* \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index 9af5f824..44df21ee 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -27,8 +27,11 @@ "autoapi.extension", "sphinx_rtd_theme", "sphinx_toolbox.decorators", + "myst_parser", ] +myst_heading_anchors = 3 + templates_path = ["_templates"] exclude_patterns = [] diff --git a/docs/source/contributing.md b/docs/source/contributing.md new file mode 100644 index 00000000..b2d2646a --- /dev/null +++ b/docs/source/contributing.md @@ -0,0 +1 @@ +```{include} ../../CONTRIBUTING.md diff --git a/docs/source/index.rst b/docs/source/index.rst index a7a1001f..6ddf88a6 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -5,6 +5,7 @@ Documentation for LabThings-FastAPI :maxdepth: 2 :caption: Contents: + contributing.md quickstart/quickstart.rst tutorial/index.rst structure.rst @@ -50,6 +51,10 @@ Installation ``pip install labthings-fastapi`` +``labthings-fastapi`` supports **Python 3.10, 3.11, 3.12, and 3.13**. The upper limit is strictly capped at 3.13 due to current ``pydantic-core`` dependencies. + +.. include:: _windows_arm_note.rst + Indices and tables ================== @@ -59,4 +64,6 @@ Indices and tables .. _python-labthings: https://github.com/labthings/python-labthings/ .. _FastAPI: https://fastapi.tiangolo.com/ -.. _pydantic: https://pydantic-docs.helpmanual.io/ \ No newline at end of file +.. _pydantic: https://pydantic-docs.helpmanual.io/ +.. _Visual Studio: https://visualstudio.microsoft.com/ +.. _Rust: https://www.rust-lang.org/ \ No newline at end of file diff --git a/docs/source/tutorial/installing_labthings.rst b/docs/source/tutorial/installing_labthings.rst index fc82302f..d73d9a01 100644 --- a/docs/source/tutorial/installing_labthings.rst +++ b/docs/source/tutorial/installing_labthings.rst @@ -25,4 +25,14 @@ then install labthings with: It is also possible to install LabThings from source, by cloning the GitHub repository and running ``pip install -e .[dev]``, but this is only recommended if you intend to alter the LabThings-FastAPI library; it is best to use the published package unless you have a good reason not to. -.. _PyPI: https://pypi.org/project/labthings-fastapi/ \ No newline at end of file + +Installation Notes +++++++++++++++++++ + +``labthings-fastapi`` supports **Python 3.10, 3.11, 3.12, and 3.13**. The upper limit is strictly capped at 3.13 due to current ``pydantic-core`` dependencies. + +.. include:: ../_windows_arm_note.rst + +.. _PyPI: https://pypi.org/project/labthings-fastapi/ +.. _Visual Studio: https://visualstudio.microsoft.com/ +.. _Rust: https://www.rust-lang.org/ \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 155a0425..dd1ffdca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,6 +42,7 @@ dev = [ "sphinx-autoapi", "sphinx-toolbox", "sphobjinv", + "myst-parser<5", "tomli; python_version < '3.11'", "codespell", ] @@ -70,6 +71,7 @@ addopts = [ "--cov-report=xml:coverage.xml", "--cov-report=html:htmlcov", "--cov-report=lcov", + "--cov=src" ] markers = [ "slow: marks tests as slow (deselect with '-m \"not slow\"')",