From 1fa9e0b7724ed81dd7868a1998ef5f4a33a05179 Mon Sep 17 00:00:00 2001 From: Julian Stirling Date: Sat, 7 Mar 2026 18:56:44 +0000 Subject: [PATCH 1/7] Move more development information to the dev docs to minimise repitition and getting out of sync --- CONTRIBUTING.md | 94 +------------ README.md | 133 +----------------- apidocs/dev/README.md | 108 +++++++++++++- apidocs/dev/_sidebar.md | 8 +- .../dev/assets}/ofm_microscope_ui_scan.jpeg | Bin .../dev/assets}/ofm_microscope_ui_view.jpeg | Bin .../dev/assets}/ofm_sim_ui_scan.jpg | Bin .../dev/assets}/ofm_sim_ui_view.jpg | Bin apidocs/dev/contributing.md | 36 +++++ apidocs/dev/python.md | 92 ++++++++++++ .../dev/simulation_guide.md | 2 +- webapp/README.md => apidocs/dev/webapp.md | 34 ++--- 12 files changed, 255 insertions(+), 252 deletions(-) rename {docs/images => apidocs/dev/assets}/ofm_microscope_ui_scan.jpeg (100%) rename {docs/images => apidocs/dev/assets}/ofm_microscope_ui_view.jpeg (100%) rename {docs/images => apidocs/dev/assets}/ofm_sim_ui_scan.jpg (100%) rename {docs/images => apidocs/dev/assets}/ofm_sim_ui_view.jpg (100%) create mode 100644 apidocs/dev/contributing.md create mode 100644 apidocs/dev/python.md rename simulation_guide.md => apidocs/dev/simulation_guide.md (98%) rename webapp/README.md => apidocs/dev/webapp.md (58%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a108e8c9..076fc7d7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,96 +6,4 @@ Any contributions to any of our projects should follow [our code of conduct](htt If you are interested in contributing to the OpenFlexure project, and do not know where to start, we recommend you visit [our forum](https://openflexure.discourse.group/). -**The rest of this page details contribution guidelines that are specific to this repository.** - -This page generally focusses on the back-end of the server, not the front-end webapp. For more details on the webapp development see the [webapp's README](./webapp/README.md). - -## Python Development - -For installation, see the [project README](./README.md). - -### Core packages and concepts - -The OpenFlexure Microscope server is built in the [LabThings-FastAPI framework](https://labthings-fastapi.readthedocs.io/en/latest/). This provides a convenient way to expose laboratory hardware over HTTP via a [FastAPI server](https://fastapi.tiangolo.com/). - -The core elements of the server code are `Things`. A `Thing` creates a [W3C Web of Things](https://www.w3.org/TR/wot-architecture) compliant HTTP interface for hardware interactions and other server functionality. - -The project also makes use of the following libraries: - -* [Pydantic](https://docs.pydantic.dev/latest/) - For serialising/deserialising data being saved to disk or sent over HTTP. -* [OpenFlexure Stitching](https://gitlab.com/openflexure/openflexure-stitching) - Our own library for creating composite microscope images from a scan. -* [OpenCV](https://opencv.org/) and [Picamera2](https://github.com/raspberrypi/picamera2/) - For controlling cameras, and simulating cameras for tests. -* [Pillow](https://pillow.readthedocs.io) - For image manipulation and saving. -* [NumPy](https://numpy.org/) and [SciPy](https://scipy.org/) - For mathematical calculations. - -*The list above is not exhaustive!* - -## Programming style - -Ideally, python code should be: - -* Broken up into small, clear, testable functions. -* Documented with docstrings (For conventions see below). -* Type hinted -* Covered by unit tests (using [pytest](https://docs.pytest.org)) - -The server code is going through significant flux during the transition from v2 to v3, so currently our test coverage is being rebuilt and type checking does not yet pass. - -[Ruff](https://docs.astral.sh/ruff/) is used both for linting and formatting the codebase. Our custom linter rules are in our `pyproject.toml`. - -Run `ruff format` to format the code in a way that will pass on our CI. - -Run `ruff check` to check for linter errors. Any contributions that don't pass both of these checks will be automatically rejected by our pipeline. - -To check your code before each commit we recommend putting the following script in tour `.git/hooks` directory with the filename `pre-commit`. - - -```python -#!/bin/bash - -set -e - -function angrymessage() -{ - RED='\033[1;31m' - NC='\033[0m' # No Color - printf "\n${RED}Not committing as ruff failed${NC}\n\n" -} - -trap angrymessage ERR - -ruff format --check -ruff check -``` - - -## Docstrings conventions. - -We write docstrings in [reStructuredText](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html), and process them with [pydoctor](https://pydoctor.readthedocs.io/). - -For function arguments, return values, and exceptions we use the following style recognised by reStructuredText: - -```python -def a_function(arg1: str, arg2: int) -> tuple[float, int]: - """A one sentence summary, in imperative mood, ending with punctuation. - - More detail after a blank line. This could be a whole paragraph. - - When referring to ``code`` in reStructuredText used double backticks - - :param arg1: This is the first argument, we can say everything we need to about it. - If the text wraps onto a new line, this line is indented. - :param arg2: This is the second argument. - - :returns: Say what it returns without anything within the colons. If returning - multiple values, a bulleted list is a good idea - just make sure: - - * It is indented to 1 level in - * There is a blank line before the bullets - * The bullet points are ``*`` not ``-`` - """ -``` - -+The linter rules we use for docstrings are defined by [pydocstyle](https://docs.astral.sh/ruff/rules/#pydocstyle-d). We do not use rules D203, D213, D400 for reasons explained in our `pyproject.toml` file. - -The documentation generated by pydoctor from docstrings can be viewed in any merge request (if the CI pipeline has passed) using the "View App" button. +Detailed guidelines specific to this project can be found in our [developer documentation](https://openflexure.gitlab.io/openflexure-microscope-server/dev/index.html). diff --git a/README.md b/README.md index 278598bf..ce80a5d0 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ The Python package provides a command `ofm-microscope-server` that runs the serv It is also possible to run the server in simulation mode. See Developer guidelines below. -## Settings +## Configuration and Settings The microscope is initially configured by a LabThings config file. This specifies two important things: @@ -38,133 +38,8 @@ The microscope is initially configured by a LabThings config file. This specifie By default, this configuration file should be read from `/var/openflexure/settings/ofm_config.json` when the microscope is run as a service. If it is run at the command line you should specify the configuration using the `-c` command line flag. This configuration file does not change often, and usually only needs to be updated when you change the physical hardware. It may be that this file should be made read-only, particularly in microscopes deployed for e.g. medical applications. -The settings folder is, by default, `/var/openflexure/settings/` on the SD card, or `./settings/` if run elsewhere. It can be changed in the configuration file. This holds every other persistent setting. Camera settings, calibration data, default capture settings, stream resolution and so on. There is one folder per `Thing`, each with their own file. The settings files can change very regularly, and if you need to reset your settings, it's usually these files that you should remove or reset. If you delete one settings file this should reset the corresponding `Thing`, you don't have to delete the whole folder. +The settings folder is, by default, `/var/openflexure/settings/` if running on a Raspberry Pi, or `./settings/` if run elsewhere. It can be changed in the configuration file. This holds every other persistent setting. Camera settings, calibration data, default capture settings, stream resolution and so on. There is one folder per `Thing`, each with their own file. The settings files can change very regularly, and if you need to reset your settings, it's usually these files that you should remove or reset. If you delete one settings file this should reset the corresponding `Thing`, you don't have to delete the whole folder. -# Developer guidelines +## Development -## Installation and set up - -To set up a development environment you will need Python 3.11 and the static files for the web application. - -### Installation and set up on a Raspberry Pi - -The OpenFlexure Raspberry Pi OS image comes with Python 3.11 already installed. We do not recommend trying to develop on the standard Raspberry Pi OS image. - - -* To activate the microscope virtual environment run `ofm activate` -* Navigate to the Openflexure repository with `cd /var/openflexure/application/openflexure-microscope-server` - -The Pi should already come with the static files for the web application. - -### Installation and set up on other platforms - -You should install Python 3.11. If you have a different version of python we recommend using [UV](https://docs.astral.sh/uv/) to set up a Python 3.11 virtual environment. - -You can check your Python version by running `py --version` or `python --version` in any terminal. Your Python version should be >= 3.11.0. - -* Clone the source code: `git clone https://gitlab.com/openflexure/openflexure-microscope-server.git` -* Enter the directory `cd openflexure-microscope-server` -* Create the virtual environment, for example with `uv venv --python 3.11` (or `py -m venv .venv` if not using uv) -* Activate your virtual environment with `source .venv/bin/activate` (on Linux) or `.venv\Scripts\activate.bat` (on Windows CMD) or `.venv\Scripts\activate` (on Windows Powershell) - -_Note: If you activate the venv in a CMD terminal in VSCode on Windows, the venv will not visually show as activated until you open a new powershell window._ - -* Install the application `uv pip install -e .[dev]` (or `pip install -e .[dev]` if you are not using UV) -* Run `python pull_webapp.py` to get the latest static files for the web application. - -Full video walkthroughs of the software installation process are available below: - -* [Windows Walkthrough](https://www.youtube.com/watch?v=LhnOLlIk-b8) -* [Linux Walkthrough](https://youtu.be/81jkMKOBeHQ) - -> If you are using Windows and you cannot activate your virtual environment from powershell, you probably need to change the execution policy. The official Microsoft docs have the right command in example #1: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-7.5#example-1-set-an-execution-policy. - -## Running the server - -There are two types of server available to run: - -* A live OpenFlexure Microscope Server, that runs on a Raspberry Pi within your OpenFlexure Microscope. This server processes real images from the microscope's camera. - - | ![The View Tab in the UI for the OFM Server](/docs/images/ofm_microscope_ui_view.jpeg "The View Tab in the UI for the OFM Server") | ![The Slide Scan Tab in the UI for the OFM Server](/docs/images/ofm_microscope_ui_scan.jpeg "The Slide Scan Tab in the UI for the OFM Server")| - |:---:|:---:| - -* A Simulation Server, which replicates the software functionality of the live server, but instead runs on your computer. Instead of receiving a live feed from a camera, the server 'scans' simulated data from a simulated camera. - - | ![The View Tab in the UI for the Simulated Server](/docs/images/ofm_sim_ui_view.jpg "The View Tab in the UI for the Simulated Server") | ![The Slide Scan Tab in the UI for the Simulated Server](/docs/images/ofm_sim_ui_scan.jpg "The Slide Scan Tab in the UI for the Simulated Server")| - |:---:|:---:| - - -### Running the server on a Raspberry Pi - -You can manage the server with the `ofm` command, using `ofm start`, `ofm stop`, and `ofm restart` to do the respective actions. Often, stopping the server and running it manually will make errors easier to spot. To do this, run: -``` -ofm stop -ofm activate -cd /var/openflexure -sudo -u openflexure-ws openflexure-microscope-server --fallback -c microscope_configuration.json --host 0.0.0.0 --port 5000 -``` - -### Running the simulation server on other platforms - -To start the simulation server: - -* Ensure all steps of the installation for your platform of choice are complete. -* Activate the virtual environment that was set up during installation -* Run the following command: - -`openflexure-microscope-server --fallback -c ./ofm_config_simulation.json` - -* Open the address displayed in the terminal in any browser. -* To close the simulation server, return to the terminal and press `ctrl + c`. - -> Note: If you are using Windows, we advise running this command in PowerShell. If it doesn't work this, might be a permission issue on managed machines, in which case try executing the command in a CMD terminal. - -> Note: If you receive an error saying that port 5000 is already in use, you can specify a different port to run the simulation on using `--port`: -> -> `openflexure-microscope-server --fallback --port 8081 -c ./ofm_config_simulation.json` - -A [full video walkthrough of running the simulation server](https://youtu.be/Z8verCqfj9s) is available on our YouTube Channel. - -You can find more information on using the simulation server in the [Simulation Guide](./simulation_guide.md). - - -## General development overview - -Please first read our **[project contributions guide](./CONTRIBUTING.md)** - -* We recommend all development is done on a branch. -* If you are editing the web app, please see our see the README in the [webapp](./webapp) directory. -* If you want to try a branch with webapp changes (that are already pushed to GitLab), but don't want to compile the javascript, then run `python pull_webapp.py -b ` to get the artifacts from the GitLab CI. - -**For development on a Raspberry Pi** we recommend VSCode Remote session from another computer. This allows you to use your usual developer environment to write code, but everything runs on the Raspberry Pi with real hardware. Note that the repository is cloned by default over `https`, so you will probably need to change the "remote" URL to your fork of the repository, or to SSH, before you're able to push changes. - -### Adding functionality - -The microscope comprises a number of `Thing` instances, which provide actions and properties to implement hardware control and software features. These may be imported from any Python module, using `ofm_config.json`. See the LabThings-FastAPI documentation for how to create a `Thing`. - -Currently, the camera and stage classes are provided by external libraries, `labthings-picamera2` and `labthings-sangaboard`. Replacing these is the easiest way to use alternative hardware: interfaces are defined in `openflexure_microscope_server.things.camera` and `openflexure_microscope_server.things.stage` respectively. - - -### Python: Formatting, linting, and tests - -All of the commands below assume that you are running in the OFM virtual environment, i.e. you have run `ofm activate` on an OpenFlexure SD card, or `source .venv/bin/activate` on Linux, or `.venv/Scripts/activate`on Windows Powershell, or `.venv\Scripts\activate.bat` on Windows CMD. - -**Before committing** you should lint and auto-format your code: - -* To lint run `ruff check` -* To auto-format the Python code run `ruff format` -* To auto-format the Javascript code, run - * `cd webapp` - * `npm run lint` - -**Before merging** please auto-format your code and also run the quality checks (linting, static analysis, and unit tests) - -* All commands above -* `pytest` - - -We use several code analysis and formatting libraries in this project. Our CI will check each of these automatically, so ensuring they pass locally will save you time. Currently `ruff` is used for linting/formatting and `pytest` for unit tests. `mypy` will be enabled once the codebase is ready. - -### Python environment, build, and dependencies - -As of `v3` we specify dependencies in `pyproject.toml`. These are not currently frozen due to difficulties matching versions on different platforms. On Raspberry Pi, it's best to specify `--only-binary=:all:` to ensure libraries like `numpy` and `scipy` are not compiled from source (which takes many hours, and/or fails). Pinning dependencies with `requirements.txt` and/or `requirements.in` may happen in the future. +For development please see our [developer documentation](https://openflexure.gitlab.io/openflexure-microscope-server/dev/index.html). \ No newline at end of file diff --git a/apidocs/dev/README.md b/apidocs/dev/README.md index 3498be6a..7788c072 100644 --- a/apidocs/dev/README.md +++ b/apidocs/dev/README.md @@ -2,8 +2,112 @@ This site provides information that is useful for developing the OpenFlexure Microscope. -### Viewing and Modifying Locally +## Viewing and Modifying These Docs Locally If you want to view these documents in your machine (very useful when editing them). You will need to serve the `apidocs` directory. Navigate to the `apidocs` directory and run `python -m http.server`. -All developer guidance documentation is written in markdown and then displayed with Docsify. More information on Docsify can be found at https://docsify.js.org. \ No newline at end of file +All developer guidance documentation is written in markdown and then displayed with Docsify. More information on Docsify can be found at https://docsify.js.org. + + +## Installation and set up + +To set up a development environment you will need Python 3.11 and the static files for the web application. + +### Installation and set up on a Raspberry Pi + +The OpenFlexure Raspberry Pi OS image comes with Python 3.11 already installed. We do not recommend trying to develop on the standard Raspberry Pi OS image. + + +* To activate the microscope virtual environment run `ofm activate` +* Navigate to the Openflexure repository with `cd /var/openflexure/application/openflexure-microscope-server` + +The Pi should already come with the static files for the web application. + +### Installation and set up on other platforms + +You should install Python 3.11. If you have a different version of python we recommend using [UV](https://docs.astral.sh/uv/) to set up a Python 3.11 virtual environment. + +You can check your Python version by running `py --version` or `python --version` in any terminal. Your Python version should be >= 3.11.0. + +* Clone the source code: `git clone https://gitlab.com/openflexure/openflexure-microscope-server.git` +* Enter the directory `cd openflexure-microscope-server` +* Create the virtual environment, for example with `python -m venv .venv` (or with `uv venv --python 3.11` if using uv) +* Activate your virtual environment with `source .venv/bin/activate` (on Linux) or `.venv\Scripts\activate.bat` (on Windows CMD) or `.venv\Scripts\activate` (on Windows Powershell) + +_Note: If you activate the venv in a CMD terminal in VSCode on Windows, the venv will not visually show as activated until you open a new powershell window._ + +* Install the application `pip install -e .[dev]` (or `uv pip install -e .[dev]` if you are using UV) +* Run `python pull_webapp.py` to get the latest static files for the web application. + +Full video walkthroughs of the software installation process are available below: + +* [Windows Walkthrough](https://www.youtube.com/watch?v=LhnOLlIk-b8) +* [Linux Walkthrough](https://youtu.be/81jkMKOBeHQ) + +> If you are using Windows and you cannot activate your virtual environment from powershell, you probably need to change the execution policy. The official Microsoft docs have the right command in example #1: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-7.5#example-1-set-an-execution-policy. + +## Running the server + +There are two types of server available to run: + +* A live OpenFlexure Microscope Server, that runs on a Raspberry Pi within your OpenFlexure Microscope. This server processes real images from the microscope's camera. + + | ![The View Tab in the UI for the OFM Server](/assets/ofm_microscope_ui_view.jpeg "The View Tab in the UI for the OFM Server") | ![The Slide Scan Tab in the UI for the OFM Server](/assets/ofm_microscope_ui_scan.jpeg "The Slide Scan Tab in the UI for the OFM Server")| + |:---:|:---:| + +* A Simulation Server, which replicates the software functionality of the live server, but instead runs on your computer. Instead of receiving a live feed from a camera, the server 'scans' simulated data from a simulated camera. + + | ![The View Tab in the UI for the Simulated Server](/assets/ofm_sim_ui_view.jpg "The View Tab in the UI for the Simulated Server") | ![The Slide Scan Tab in the UI for the Simulated Server](/assets/ofm_sim_ui_scan.jpg "The Slide Scan Tab in the UI for the Simulated Server")| + |:---:|:---:| + + +### Running the server on a Raspberry Pi + +You can manage the server with the `ofm` command, using `ofm start`, `ofm stop`, and `ofm restart` to do the respective actions. Often, stopping the server and running it manually will make errors easier to spot. To do this, run: +``` +ofm stop +ofm activate +cd /var/openflexure +sudo -u openflexure-ws openflexure-microscope-server --fallback -c microscope_configuration.json --host 0.0.0.0 --port 5000 +``` + +### Running the simulation server on other platforms + +To start the simulation server: + +* Ensure all steps of the installation for your platform of choice are complete. +* Activate the virtual environment that was set up during installation +* Run the following command: + +`openflexure-microscope-server --fallback -c ./ofm_config_simulation.json` + +* Open the address displayed in the terminal in any browser. +* To close the simulation server, return to the terminal and press `ctrl + c`. + +> Note: If you are using Windows, we advise running this command in PowerShell. If it doesn't work this, might be a permission issue on managed machines, in which case try executing the command in a CMD terminal. + +> Note: If you receive an error saying that port 5000 is already in use, you can specify a different port to run the simulation on using `--port`: +> +> `openflexure-microscope-server --fallback --port 8081 -c ./ofm_config_simulation.json` + +A [full video walkthrough of running the simulation server](https://youtu.be/Z8verCqfj9s) is available on our YouTube Channel. + +You can find more information on using the simulation server in the [Simulation Guide](simulation_guide). + + +## General development overview + +Please first read our **[project contributions guide](contributing)** + +* We recommend all development is done on a branch. +* If you are editing the web app, please see our see the README in the [webapp](webapp) directory. +* If you want to try a branch with webapp changes (that are already pushed to GitLab), but don't want to compile the javascript, then run `python pull_webapp.py -b ` to get the artifacts from the GitLab CI. + +**For development on a Raspberry Pi** we recommend VSCode Remote session from another computer. This allows you to use your usual developer environment to write code, but everything runs on the Raspberry Pi with real hardware. Note that the repository is cloned by default over `https`, so you will probably need to change the "remote" URL to your fork of the repository, or to SSH, before you're able to push changes. + +### Adding functionality + +The microscope comprises a number of `Thing` instances, which provide actions and properties to implement hardware control and software features. These may be imported from any Python module, using `ofm_config.json`. See the LabThings-FastAPI documentation for how to create a `Thing`. + +Currently, the camera and stage classes are provided by external libraries, `labthings-picamera2` and `labthings-sangaboard`. Replacing these is the easiest way to use alternative hardware: interfaces are defined in `openflexure_microscope_server.things.camera` and `openflexure_microscope_server.things.stage` respectively. + diff --git a/apidocs/dev/_sidebar.md b/apidocs/dev/_sidebar.md index df1ea285..a3db62e5 100644 --- a/apidocs/dev/_sidebar.md +++ b/apidocs/dev/_sidebar.md @@ -5,5 +5,9 @@

Developer Guidance

- [Home](README) -- [Software Architecture](architecture.md) -- [PiCamera Tuning Files](picamera-tuning-files.md) \ No newline at end of file +- [Contributing](contributing) +- [Python Development](python) +- [Webapp Development](webapp) +- [Running the Simulator](simulation_guide) +- [Software Architecture](architecture) +- [PiCamera Tuning Files](picamera-tuning-files) \ No newline at end of file diff --git a/docs/images/ofm_microscope_ui_scan.jpeg b/apidocs/dev/assets/ofm_microscope_ui_scan.jpeg similarity index 100% rename from docs/images/ofm_microscope_ui_scan.jpeg rename to apidocs/dev/assets/ofm_microscope_ui_scan.jpeg diff --git a/docs/images/ofm_microscope_ui_view.jpeg b/apidocs/dev/assets/ofm_microscope_ui_view.jpeg similarity index 100% rename from docs/images/ofm_microscope_ui_view.jpeg rename to apidocs/dev/assets/ofm_microscope_ui_view.jpeg diff --git a/docs/images/ofm_sim_ui_scan.jpg b/apidocs/dev/assets/ofm_sim_ui_scan.jpg similarity index 100% rename from docs/images/ofm_sim_ui_scan.jpg rename to apidocs/dev/assets/ofm_sim_ui_scan.jpg diff --git a/docs/images/ofm_sim_ui_view.jpg b/apidocs/dev/assets/ofm_sim_ui_view.jpg similarity index 100% rename from docs/images/ofm_sim_ui_view.jpg rename to apidocs/dev/assets/ofm_sim_ui_view.jpg diff --git a/apidocs/dev/contributing.md b/apidocs/dev/contributing.md new file mode 100644 index 00000000..a71f745a --- /dev/null +++ b/apidocs/dev/contributing.md @@ -0,0 +1,36 @@ +# Contributing to the OpenFlexure Microscope Server + +All contributions to the OpenFlexure project should follow our [project contributions guidelines](https://openflexure.org/contribute). + +Any contributions to any of our projects should follow [our code of conduct](https://openflexure.org/conduct). + +If you are interested in contributing to the OpenFlexure project, and do not know where to start, we recommend you visit [our forum](https://openflexure.discourse.group/). + +**The rest of this page details contribution guidelines that are specific to this repository.** + +This page generally focusses on the back-end of the server, not the front-end webapp. For more details on the webapp development see the [webapp's README](webapp). + +## Installation + +For installation, see the [home page](README). + +### Core packages and concepts + +The OpenFlexure Microscope server is built in the [LabThings-FastAPI framework](https://labthings-fastapi.readthedocs.io/en/latest/). This provides a convenient way to expose laboratory hardware over HTTP via a [FastAPI server](https://fastapi.tiangolo.com/). + +The core elements of the server code are `Things`. A `Thing` creates a [W3C Web of Things](https://www.w3.org/TR/wot-architecture) compliant HTTP interface for hardware interactions and other server functionality. + +The project also makes use of the following libraries: + +* [Pydantic](https://docs.pydantic.dev/latest/) - For serialising/deserialising data being saved to disk or sent over HTTP. +* [OpenFlexure Stitching](https://gitlab.com/openflexure/openflexure-stitching) - Our own library for creating composite microscope images from a scan. +* [OpenCV](https://opencv.org/) and [Picamera2](https://github.com/raspberrypi/picamera2/) - For controlling cameras, and simulating cameras for tests. +* [Pillow](https://pillow.readthedocs.io) - For image manipulation and saving. +* [NumPy](https://numpy.org/) and [SciPy](https://scipy.org/) - For mathematical calculations. + +*The list above is not exhaustive!* + +## Coding guidelines + +We have separate coding guidelines for [the Python server](python) and for the [Vue webapp](webapp). + diff --git a/apidocs/dev/python.md b/apidocs/dev/python.md new file mode 100644 index 00000000..955d0b5d --- /dev/null +++ b/apidocs/dev/python.md @@ -0,0 +1,92 @@ +# Python Server Development + +## Overview + + +Ideally, Python code should be: + +* Broken up into small, clear, testable functions. +* Documented with docstrings (For conventions see below). +* Type hinted +* Covered by unit tests (using [pytest](https://docs.pytest.org)) + +The server code is going through significant flux during the transition from v2 to v3, so currently our test coverage is being rebuilt and type checking does not yet pass. + +## Python environment, build, and dependencies + +As of `v3` we specify dependencies in `pyproject.toml`. These are not currently frozen due to difficulties matching versions on different platforms. On Raspberry Pi, it's best to specify `--only-binary=:all:` to ensure libraries like `numpy` and `scipy` are not compiled from source (which takes many hours, and/or fails). Pinning dependencies with `requirements.txt` and/or `requirements.in` may happen in the future. + + + +## Python: Formatting, linting, and tests + +[Ruff](https://docs.astral.sh/ruff/) is used both for linting and formatting the codebase. Our custom linter rules are in our `pyproject.toml`. + +> All of the commands below assume that you are running in the OFM virtual environment, i.e. you have run `ofm activate` on an OpenFlexure SD card, or `source .venv/bin/activate` on Linux, or `.venv/Scripts/activate`on Windows Powershell, or `.venv\Scripts\activate.bat` on Windows CMD. + +**Before committing** you should lint and auto-format your code: + +* To lint run `ruff check` +* To auto-format the Python code run `ruff format` + +**Before merging** please auto-format your code and also run the quality checks (linting, static analysis, and unit tests) + +* All commands above +* `pytest` + + +We use several code analysis and formatting libraries in this project. Our CI will check each of these automatically, so ensuring they pass locally will save you time. Currently `ruff` is used for linting/formatting and `pytest` for unit tests. `mypy` will be enabled once the codebase is ready. + + +To check your code before each commit we recommend putting the following script in tour `.git/hooks` directory with the filename `pre-commit`. + + +```python +#!/bin/bash + +set -e + +function angrymessage() +{ + RED='\033[1;31m' + NC='\033[0m' # No Color + printf "\n${RED}Not committing as ruff failed${NC}\n\n" +} + +trap angrymessage ERR + +ruff format --check +ruff check +``` + + +## Docstrings conventions. + +We write docstrings in [reStructuredText](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html), and process them with [pydoctor](https://pydoctor.readthedocs.io/). + +For function arguments, return values, and exceptions we use the following style recognised by reStructuredText: + +```python +def a_function(arg1: str, arg2: int) -> tuple[float, int]: + """A one sentence summary, in imperative mood, ending with punctuation. + + More detail after a blank line. This could be a whole paragraph. + + When referring to ``code`` in reStructuredText used double backticks + + :param arg1: This is the first argument, we can say everything we need to about it. + If the text wraps onto a new line, this line is indented. + :param arg2: This is the second argument. + + :returns: Say what it returns without anything within the colons. If returning + multiple values, a bulleted list is a good idea - just make sure: + + * It is indented to 1 level in + * There is a blank line before the bullets + * The bullet points are ``*`` not ``-`` + """ +``` + ++The linter rules we use for docstrings are defined by [pydocstyle](https://docs.astral.sh/ruff/rules/#pydocstyle-d). We do not use rules D203, D213, D400 for reasons explained in our `pyproject.toml` file. + +The documentation generated by pydoctor from docstrings can be viewed in any merge request (if the CI pipeline has passed) using the "View App" button. \ No newline at end of file diff --git a/simulation_guide.md b/apidocs/dev/simulation_guide.md similarity index 98% rename from simulation_guide.md rename to apidocs/dev/simulation_guide.md index 258f1e3d..cf7997ae 100644 --- a/simulation_guide.md +++ b/apidocs/dev/simulation_guide.md @@ -16,7 +16,7 @@ The simulation server GUI is a copy of the GUI you would find on the hardware wi ## Starting the Simulation Server -1. **Activate your virtual environment** (the same one created during installation, as described in the [README](./README.md)). +1. **Activate your virtual environment** (the same one created during installation, as described in the [Python documentation](python)). 2. **Run the simulation server** using the following command: ```bash diff --git a/webapp/README.md b/apidocs/dev/webapp.md similarity index 58% rename from webapp/README.md rename to apidocs/dev/webapp.md index 6b0a2f7e..37516dbd 100644 --- a/webapp/README.md +++ b/apidocs/dev/webapp.md @@ -1,18 +1,11 @@ -# OpenFlexure Microscope JS Client +# WebApp Development ## Key info -* Vue.js web application providing a graphical interface for the OFM +* Vue.js web application providing a graphical interface for the Openflexure Microscope. * Once built, will be served by the API server from the host root on port 5000 - -* See [openflexure-microscope-server/README.md](https://gitlab.com/openflexure/openflexure-microscope-server/-/blob/master/README.md) for details on local installation and building - -# Developer guidelines - -## Creating releases - * JS client is coupled to the API, and is built and distributed with the server. -* See [openflexure-microscope-server/README.md](https://gitlab.com/openflexure/openflexure-microscope-server/-/blob/master/README.md) for details on creating new releases + ## Installing @@ -23,7 +16,7 @@ _Note: If you are using a Windows OS, the following commands must be executed in * Install dependencies with `npm install` * Build the static web app with `npm run build` -# Developing +## Live Server When developing it is useful to use the development server so Vue changes happen instantly without the need to rebuild. To start the development server run: @@ -33,19 +26,10 @@ The development server is accessed on a different port from the microscope API. When the development webapp starts it cannot locate the microscope API as this is served by the microscope on port 5000. Instead it will present you with a page giving you the option to "override API origin". If you are running a development server on your computer, you should enter `http://localhost:5000/`. -## VS Code and ESLint +# Javascript: Formatting and linting -To prevent the editor from interfering with ESLint, add to your project `settings.json`: +To enforce code style we and quality we use ESLint and Prettier. Both can be run together with the same command. + +- To check the for errors and warnings run `npm run lint` +- To automatically fix errors an warnings run `npm run lint:fix` -```json -{ - "editor.tabSize": 2, - "cSpell.enabled": false, - "eslint.validate": ["vue","javascript", "javascriptreact"], - "editor.formatOnSave": false, - "vetur.validation.template": false, - "editor.codeActionsOnSave": { - "source.fixAll.eslint": true - } -} -``` From 590030683552c82aace4cc45343be2c03308afef Mon Sep 17 00:00:00 2001 From: Julian Stirling Date: Sat, 7 Mar 2026 21:12:07 +0000 Subject: [PATCH 2/7] Add developer documentation for the config file. --- README.md | 4 +- apidocs/dev/config-file.md | 101 +++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 apidocs/dev/config-file.md diff --git a/README.md b/README.md index ce80a5d0..00c3262d 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,9 @@ The microscope is initially configured by a LabThings config file. This specifie By default, this configuration file should be read from `/var/openflexure/settings/ofm_config.json` when the microscope is run as a service. If it is run at the command line you should specify the configuration using the `-c` command line flag. This configuration file does not change often, and usually only needs to be updated when you change the physical hardware. It may be that this file should be made read-only, particularly in microscopes deployed for e.g. medical applications. -The settings folder is, by default, `/var/openflexure/settings/` if running on a Raspberry Pi, or `./settings/` if run elsewhere. It can be changed in the configuration file. This holds every other persistent setting. Camera settings, calibration data, default capture settings, stream resolution and so on. There is one folder per `Thing`, each with their own file. The settings files can change very regularly, and if you need to reset your settings, it's usually these files that you should remove or reset. If you delete one settings file this should reset the corresponding `Thing`, you don't have to delete the whole folder. +In the future tool will be created for crating custom microscope configurations. Currently no custom configurations are recommended, except for development. More [information on the configuration file](https://openflexure.gitlab.io/openflexure-microscope-server/dev/index.html#config-file) can be found in the developer documentation. + +The settings folder holds the state of your microscope, including the calibrations. The settings folder is, by default, `/var/openflexure/settings/` if running on a Raspberry Pi, or `./settings/` if run elsewhere. It can be changed in the configuration file. This holds every other persistent setting. Camera settings, calibration data, default capture settings, stream resolution and so on. There is one folder per `Thing`, each with their own file. The settings files can change very regularly, and if you need to reset your settings, it's usually these files that you should remove or reset. If you delete one settings file this should reset the corresponding `Thing`, you don't have to delete the whole folder. ## Development diff --git a/apidocs/dev/config-file.md b/apidocs/dev/config-file.md new file mode 100644 index 00000000..bbda452c --- /dev/null +++ b/apidocs/dev/config-file.md @@ -0,0 +1,101 @@ +# The Configuration File + +By default, this configuration file is located at read from `/var/openflexure/settings/ofm_config.json` when the microscope is run as a service. If it is run at the command line, you should specify the configuration using the `-c` command line flag. + +The default configuration file links to the configuration file in the repository: + +``` +{ + "base_config_file": "/var/openflexure/application/openflexure-microscope-server/ofm_config_full.json" +} +``` + +## Understanding and modifying the base configuration file + +This section describes how to change the microscope configuration for development. For example, when making a Merge Request to add a new Thing to the standard microscope configuration. **Do not do this for customising a single microscope.** For customising the configuration of a single microscope see the next section. + +The specification for the configuration file is set by [LabThings FastAPI](https://labthings-fastapi.readthedocs.io/). The file is a JSON file. As such, it cannot contain comments. + +The configuration file has three keys: + +* `things` - A dictionary (Object) containing the [`Thing`s](https://labthings-fastapi.readthedocs.io/en/latest/using_things.html) that should be loaded. All instrument control and server interaction is via `Thing`s. +* `settings_folder` - The directory that LabThings will save settings for each `Thing`. +* `application_config` - A space for the OpenFlexure Microscope Server to list its custom configuration. The OpenFlexure Microscope Server has the following keys: + * `log_folder` - Where the log files are stored. + * `data_folder` - Where data is stored. + +The `things` dictionary can specify a `Thing` to be loaded into the server in two different ways. If there is no custom configuration for the `Thing` then: + +* The key is a **name** for the `Thing`, this defines the URL of its endpoints. +* The value is the Python object reference for the `Thing`. + +For example: + +``` +"autofocus": "openflexure_microscope_server.things.autofocus:AutofocusThing", +``` + +If further information needs to be supplied then the value should be a dictionary (Object) with the following keys: + +* `class` - *(Required)* The Python object reference for the `Thing`. +* `args` - *(Optional)* The positional arguments to be passed to the `Thing` when initialised. +* `kwargs` - *(Optional)* The keyword arguments to be passed to the `Thing` when initialised. +* `thing_slots` - *(Optional)* Information for how the [thing slots](https://labthings-fastapi.readthedocs.io/en/latest/thing_slots.html) of the `Thing` are populated. + +For example: + +``` +"camera": { + "class": "openflexure_microscope_server.things.camera.picamera:StreamingPiCamera2", + "kwargs": { + "camera_board": "picamera_v2" + } +} +``` + +## Customising the configuration + +To have a custom configuration for a specific microscope, we recommend editing `ofm_config.json` in the settings folder. **Avoid editing the base configuration in the repository.** This will keep your customisations that should not be pushed separate from changes to the base file. + +The customisations are performed using [**JSON merge patch** (IETF RFC 7396)](https://datatracker.ietf.org/doc/html/rfc7396) syntax. The patch should specify only the keys that are to change. The RFC documentation provides a number of examples. + +> **Note** +> If a key is set to `null` that key is deleted entirely. There is a [LabThings FastAPI issue](https://github.com/labthings/labthings-fastapi/issues/190) discussing how to handle the rare cases where a value may need to be patched to have the value `None` in Python. + +For our configuration file, an extra key `patch` is added that describes how to patch the base configuration file. + +### Configuration for the Raspberry Pi HQ Camera + +> **Note** +> HQ camera support is currently experimental in v3. While it can be used, it is not as thoroughly tested or supported as the standard v2 camera module. + +You can configure a microscope for the Raspberry Pi HQ Camera by specifying the `camera_board` keyword argument for the `camera` `Thing`. The value needs to change from `picamera_v2` to `picamera_hq`. This will load the HQ camera tuning file and configure the pipeline accordingly. + +As the only key that needs changing is `things.camera.kwargs.camera_board` the patch is: + +```json +{ + "base_config_file": "/var/openflexure/application/openflexure-microscope-server/ofm_config_full.json", + "patch": { + "things": { + "camera": { + "kwargs": { + "camera_board": "picamera_hq" + } + } + } + } +} +``` + +Note that even though the `camera` patch is specified as: + +```json +"camera": { + "kwargs": { + "camera_board": "picamera_hq" + } +} +``` + +This only affects the specified keys. So the camera class is unaffected. From e1b467424b7d75d3f103a284399e38efb44e7599 Mon Sep 17 00:00:00 2001 From: Julian Stirling Date: Sat, 7 Mar 2026 21:17:25 +0000 Subject: [PATCH 3/7] Add configuration file docs to dev docs sidebar --- apidocs/dev/_sidebar.md | 1 + 1 file changed, 1 insertion(+) diff --git a/apidocs/dev/_sidebar.md b/apidocs/dev/_sidebar.md index a3db62e5..b40cb62c 100644 --- a/apidocs/dev/_sidebar.md +++ b/apidocs/dev/_sidebar.md @@ -8,6 +8,7 @@ - [Contributing](contributing) - [Python Development](python) - [Webapp Development](webapp) +- [Configuration File](config-file) - [Running the Simulator](simulation_guide) - [Software Architecture](architecture) - [PiCamera Tuning Files](picamera-tuning-files) \ No newline at end of file From 3fee78a213426d4a98066694915d27ca15af006e Mon Sep 17 00:00:00 2001 From: Julian Stirling Date: Sun, 8 Mar 2026 18:30:17 +0000 Subject: [PATCH 4/7] Tweak css of dev docs to remove spaces between code and adjacent text. --- apidocs/dev/ofm.css | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apidocs/dev/ofm.css b/apidocs/dev/ofm.css index f3a7abae..c60cc0ca 100644 --- a/apidocs/dev/ofm.css +++ b/apidocs/dev/ofm.css @@ -833,8 +833,11 @@ body { border-radius: 2px; /*Approx the other side of the colour wheel from OFM pink.*/ color: #2fbf73; - margin: 0 2px; - padding: 3px 5px; + /*Remove the padding and margin as it spaces in-line code to much from surrounding + text and punctuation. + */ + margin: 0; + padding: 3px 0; white-space: pre-wrap } From 59eafa7802f4eda04061378178a979157f5a2e7a Mon Sep 17 00:00:00 2001 From: Julian Stirling Date: Wed, 11 Mar 2026 12:38:18 +0000 Subject: [PATCH 5/7] Apply suggestions from code review of branch move-to-dev-docs Co-authored-by: Joe Knapper --- README.md | 2 +- apidocs/dev/README.md | 6 +++--- apidocs/dev/config-file.md | 6 ++++-- apidocs/dev/ofm.css | 2 +- apidocs/dev/python.md | 6 +++--- apidocs/dev/webapp.md | 2 +- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 00c3262d..4af9d1bf 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ The microscope is initially configured by a LabThings config file. This specifie By default, this configuration file should be read from `/var/openflexure/settings/ofm_config.json` when the microscope is run as a service. If it is run at the command line you should specify the configuration using the `-c` command line flag. This configuration file does not change often, and usually only needs to be updated when you change the physical hardware. It may be that this file should be made read-only, particularly in microscopes deployed for e.g. medical applications. -In the future tool will be created for crating custom microscope configurations. Currently no custom configurations are recommended, except for development. More [information on the configuration file](https://openflexure.gitlab.io/openflexure-microscope-server/dev/index.html#config-file) can be found in the developer documentation. +In the future, a tool will be created for crating custom microscope configurations. Currently no custom configurations are recommended, except for development. More [information on the configuration file](https://openflexure.gitlab.io/openflexure-microscope-server/dev/index.html#config-file) can be found in the developer documentation. The settings folder holds the state of your microscope, including the calibrations. The settings folder is, by default, `/var/openflexure/settings/` if running on a Raspberry Pi, or `./settings/` if run elsewhere. It can be changed in the configuration file. This holds every other persistent setting. Camera settings, calibration data, default capture settings, stream resolution and so on. There is one folder per `Thing`, each with their own file. The settings files can change very regularly, and if you need to reset your settings, it's usually these files that you should remove or reset. If you delete one settings file this should reset the corresponding `Thing`, you don't have to delete the whole folder. diff --git a/apidocs/dev/README.md b/apidocs/dev/README.md index 7788c072..6ae64813 100644 --- a/apidocs/dev/README.md +++ b/apidocs/dev/README.md @@ -84,7 +84,7 @@ To start the simulation server: * Open the address displayed in the terminal in any browser. * To close the simulation server, return to the terminal and press `ctrl + c`. -> Note: If you are using Windows, we advise running this command in PowerShell. If it doesn't work this, might be a permission issue on managed machines, in which case try executing the command in a CMD terminal. +> Note: If you are using Windows, we advise running this command in PowerShell. If it doesn't work, this might be a permission issue on managed machines, in which case try executing the command in a CMD terminal. > Note: If you receive an error saying that port 5000 is already in use, you can specify a different port to run the simulation on using `--port`: > @@ -101,7 +101,7 @@ Please first read our **[project contributions guide](contributing)** * We recommend all development is done on a branch. * If you are editing the web app, please see our see the README in the [webapp](webapp) directory. -* If you want to try a branch with webapp changes (that are already pushed to GitLab), but don't want to compile the javascript, then run `python pull_webapp.py -b ` to get the artifacts from the GitLab CI. +* If you want to try a branch with webapp changes (that are already pushed to GitLab with a passing pipeline), but don't want to compile the javascript, then run `python pull_webapp.py -b ` to get the artifacts from the GitLab CI. **For development on a Raspberry Pi** we recommend VSCode Remote session from another computer. This allows you to use your usual developer environment to write code, but everything runs on the Raspberry Pi with real hardware. Note that the repository is cloned by default over `https`, so you will probably need to change the "remote" URL to your fork of the repository, or to SSH, before you're able to push changes. @@ -109,5 +109,5 @@ Please first read our **[project contributions guide](contributing)** The microscope comprises a number of `Thing` instances, which provide actions and properties to implement hardware control and software features. These may be imported from any Python module, using `ofm_config.json`. See the LabThings-FastAPI documentation for how to create a `Thing`. -Currently, the camera and stage classes are provided by external libraries, `labthings-picamera2` and `labthings-sangaboard`. Replacing these is the easiest way to use alternative hardware: interfaces are defined in `openflexure_microscope_server.things.camera` and `openflexure_microscope_server.things.stage` respectively. +All core functionality hardware control functionality is within `Thing` classes. Even the standard camera and stage classes are each a `Thing`. This means it is possible to use a different camera or stage by sub-classing the `BaseCamera` or `BaseStage` and editing the configuration file. diff --git a/apidocs/dev/config-file.md b/apidocs/dev/config-file.md index bbda452c..906aea83 100644 --- a/apidocs/dev/config-file.md +++ b/apidocs/dev/config-file.md @@ -1,6 +1,6 @@ # The Configuration File -By default, this configuration file is located at read from `/var/openflexure/settings/ofm_config.json` when the microscope is run as a service. If it is run at the command line, you should specify the configuration using the `-c` command line flag. +By default, this configuration file is read from `/var/openflexure/settings/ofm_config.json` when the microscope is run as a service. If it is run at the command line, you should specify the configuration file path using the `-c` command line flag. The default configuration file links to the configuration file in the repository: @@ -26,7 +26,7 @@ The configuration file has three keys: The `things` dictionary can specify a `Thing` to be loaded into the server in two different ways. If there is no custom configuration for the `Thing` then: -* The key is a **name** for the `Thing`, this defines the URL of its endpoints. +* The key is a **name** for the `Thing`, which defines the URL of its endpoints. * The value is the Python object reference for the `Thing`. For example: @@ -35,6 +35,8 @@ For example: "autofocus": "openflexure_microscope_server.things.autofocus:AutofocusThing", ``` +will add an autofocus Thing to the server. The Thing is located at `openflexure_microscope_server.things.autofocus:AutofocusThing`, (allowing multiple Things per Python file), and any endpoints (such as actions and properties) in that Thing will have the URL `base_url:port/autofocus/endpoint_name` + If further information needs to be supplied then the value should be a dictionary (Object) with the following keys: * `class` - *(Required)* The Python object reference for the `Thing`. diff --git a/apidocs/dev/ofm.css b/apidocs/dev/ofm.css index c60cc0ca..8fb64a72 100644 --- a/apidocs/dev/ofm.css +++ b/apidocs/dev/ofm.css @@ -833,7 +833,7 @@ body { border-radius: 2px; /*Approx the other side of the colour wheel from OFM pink.*/ color: #2fbf73; - /*Remove the padding and margin as it spaces in-line code to much from surrounding + /*Remove the padding and margin as it spaces in-line code too much from surrounding text and punctuation. */ margin: 0; diff --git a/apidocs/dev/python.md b/apidocs/dev/python.md index 955d0b5d..04caaab9 100644 --- a/apidocs/dev/python.md +++ b/apidocs/dev/python.md @@ -14,7 +14,7 @@ The server code is going through significant flux during the transition from v2 ## Python environment, build, and dependencies -As of `v3` we specify dependencies in `pyproject.toml`. These are not currently frozen due to difficulties matching versions on different platforms. On Raspberry Pi, it's best to specify `--only-binary=:all:` to ensure libraries like `numpy` and `scipy` are not compiled from source (which takes many hours, and/or fails). Pinning dependencies with `requirements.txt` and/or `requirements.in` may happen in the future. +As of `v3` we specify dependencies in `pyproject.toml`. These are not currently frozen due to difficulties matching versions on different platforms. On Raspberry Pi, it's best to specify `--only-binary=:all:` when installing packages, to ensure libraries like `numpy` and `scipy` are not compiled from source (which takes many hours, and/or fails). Pinning dependencies with `requirements.txt` and/or `requirements.in` may happen in the future. @@ -26,10 +26,10 @@ As of `v3` we specify dependencies in `pyproject.toml`. These are not currently **Before committing** you should lint and auto-format your code: -* To lint run `ruff check` +* To lint, run `ruff check` and manually fix any flagged issues * To auto-format the Python code run `ruff format` -**Before merging** please auto-format your code and also run the quality checks (linting, static analysis, and unit tests) +**Before pushing** please auto-format your code and also run the quality checks (linting, static analysis, and unit tests) * All commands above * `pytest` diff --git a/apidocs/dev/webapp.md b/apidocs/dev/webapp.md index 37516dbd..1d7d0fc2 100644 --- a/apidocs/dev/webapp.md +++ b/apidocs/dev/webapp.md @@ -31,5 +31,5 @@ When the development webapp starts it cannot locate the microscope API as this i To enforce code style we and quality we use ESLint and Prettier. Both can be run together with the same command. - To check the for errors and warnings run `npm run lint` -- To automatically fix errors an warnings run `npm run lint:fix` +- To automatically fix errors and warnings run `npm run lint:fix` From b8878d693009e322ab0315877265cfaf943ca266 Mon Sep 17 00:00:00 2001 From: Julian Stirling Date: Wed, 11 Mar 2026 12:58:35 +0000 Subject: [PATCH 6/7] Removing out of date developer doc information and improving linking --- apidocs/dev/config-file.md | 16 ++++++++-------- apidocs/dev/python.md | 12 +++++++----- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/apidocs/dev/config-file.md b/apidocs/dev/config-file.md index 906aea83..5c1e160a 100644 --- a/apidocs/dev/config-file.md +++ b/apidocs/dev/config-file.md @@ -4,7 +4,7 @@ By default, this configuration file is read from `/var/openflexure/settings/ofm_ The default configuration file links to the configuration file in the repository: -``` +```json { "base_config_file": "/var/openflexure/application/openflexure-microscope-server/ofm_config_full.json" } @@ -12,7 +12,7 @@ The default configuration file links to the configuration file in the repository ## Understanding and modifying the base configuration file -This section describes how to change the microscope configuration for development. For example, when making a Merge Request to add a new Thing to the standard microscope configuration. **Do not do this for customising a single microscope.** For customising the configuration of a single microscope see the next section. +This section describes how to change the microscope configuration for development. For example, when making a Merge Request to add a new Thing to the standard microscope configuration. **Do not do this for customising a single microscope.** For customiston please refeer to the section on [customising the configuration](#section-customise-config). The specification for the configuration file is set by [LabThings FastAPI](https://labthings-fastapi.readthedocs.io/). The file is a JSON file. As such, it cannot contain comments. @@ -31,7 +31,7 @@ The `things` dictionary can specify a `Thing` to be loaded into the server in tw For example: -``` +```json "autofocus": "openflexure_microscope_server.things.autofocus:AutofocusThing", ``` @@ -46,7 +46,7 @@ If further information needs to be supplied then the value should be a dictionar For example: -``` +```json "camera": { "class": "openflexure_microscope_server.things.camera.picamera:StreamingPiCamera2", "kwargs": { @@ -55,7 +55,8 @@ For example: } ``` -## Customising the configuration +## Customising the configuration :id=section-customise-config + To have a custom configuration for a specific microscope, we recommend editing `ofm_config.json` in the settings folder. **Avoid editing the base configuration in the repository.** This will keep your customisations that should not be pushed separate from changes to the base file. @@ -90,14 +91,13 @@ As the only key that needs changing is `things.camera.kwargs.camera_board` the p } ``` -Note that even though the `camera` patch is specified as: +This will change the camera section to: ```json "camera": { + "class": "openflexure_microscope_server.things.camera.picamera:StreamingPiCamera2", "kwargs": { "camera_board": "picamera_hq" } } ``` - -This only affects the specified keys. So the camera class is unaffected. diff --git a/apidocs/dev/python.md b/apidocs/dev/python.md index 04caaab9..7b2af3eb 100644 --- a/apidocs/dev/python.md +++ b/apidocs/dev/python.md @@ -3,14 +3,13 @@ ## Overview -Ideally, Python code should be: +Python code should be: * Broken up into small, clear, testable functions. * Documented with docstrings (For conventions see below). * Type hinted * Covered by unit tests (using [pytest](https://docs.pytest.org)) -The server code is going through significant flux during the transition from v2 to v3, so currently our test coverage is being rebuilt and type checking does not yet pass. ## Python environment, build, and dependencies @@ -28,17 +27,19 @@ As of `v3` we specify dependencies in `pyproject.toml`. These are not currently * To lint, run `ruff check` and manually fix any flagged issues * To auto-format the Python code run `ruff format` +* To check for spelling errors `codespell .` **Before pushing** please auto-format your code and also run the quality checks (linting, static analysis, and unit tests) * All commands above * `pytest` +* `mypy src` -We use several code analysis and formatting libraries in this project. Our CI will check each of these automatically, so ensuring they pass locally will save you time. Currently `ruff` is used for linting/formatting and `pytest` for unit tests. `mypy` will be enabled once the codebase is ready. +We use several code analysis and formatting libraries in this project. Our CI will check each of these automatically, so ensuring they pass locally will save you time. Currently `ruff` is used for linting/formatting and `pytest` for unit tests. -To check your code before each commit we recommend putting the following script in tour `.git/hooks` directory with the filename `pre-commit`. +To check your code before each commit we recommend putting the following script in your `.git/hooks` directory with the filename `pre-commit`. ```python @@ -50,13 +51,14 @@ function angrymessage() { RED='\033[1;31m' NC='\033[0m' # No Color - printf "\n${RED}Not committing as ruff failed${NC}\n\n" + printf "\n${RED}Not committing as ruff or spellcheck failed${NC}\n\n" } trap angrymessage ERR ruff format --check ruff check +codespell . ``` From d3b1081c9846b9548d1bdfa000982c5dfbf6b6e9 Mon Sep 17 00:00:00 2001 From: Julian Stirling Date: Wed, 11 Mar 2026 13:08:02 +0000 Subject: [PATCH 7/7] Further improve the linting and formatting section of the dev docs --- apidocs/dev/python.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/apidocs/dev/python.md b/apidocs/dev/python.md index 7b2af3eb..df9cc6a9 100644 --- a/apidocs/dev/python.md +++ b/apidocs/dev/python.md @@ -16,29 +16,30 @@ Python code should be: As of `v3` we specify dependencies in `pyproject.toml`. These are not currently frozen due to difficulties matching versions on different platforms. On Raspberry Pi, it's best to specify `--only-binary=:all:` when installing packages, to ensure libraries like `numpy` and `scipy` are not compiled from source (which takes many hours, and/or fails). Pinning dependencies with `requirements.txt` and/or `requirements.in` may happen in the future. - ## Python: Formatting, linting, and tests [Ruff](https://docs.astral.sh/ruff/) is used both for linting and formatting the codebase. Our custom linter rules are in our `pyproject.toml`. > All of the commands below assume that you are running in the OFM virtual environment, i.e. you have run `ofm activate` on an OpenFlexure SD card, or `source .venv/bin/activate` on Linux, or `.venv/Scripts/activate`on Windows Powershell, or `.venv\Scripts\activate.bat` on Windows CMD. -**Before committing** you should lint and auto-format your code: +**Before committing** you should lint and auto-format your code. -* To lint, run `ruff check` and manually fix any flagged issues -* To auto-format the Python code run `ruff format` -* To check for spelling errors `codespell .` +Please run: -**Before pushing** please auto-format your code and also run the quality checks (linting, static analysis, and unit tests) +* `ruff check` - to lint your Python code (please manually fix any flagged issues) +* `ruff format` - to automatically format your Python code +* `codespell .` - to check for spelling errors + +**Before merging** please auto-format your code and also run the quality checks (linting, static analysis, and unit tests) + +Please run: * All commands above -* `pytest` -* `mypy src` - +* `mypy src` to type check your Python code +* `pytest` to run all the unit tests in `tests/unit_tests` We use several code analysis and formatting libraries in this project. Our CI will check each of these automatically, so ensuring they pass locally will save you time. Currently `ruff` is used for linting/formatting and `pytest` for unit tests. - To check your code before each commit we recommend putting the following script in your `.git/hooks` directory with the filename `pre-commit`.