openflexure-microscope-server/CONTRIBUTING.md
Julian Stirling cef3c9f40d Apply suggestions from code review of branch update-readme-and-contributing
Co-authored-by: Joe Knapper <joe.knapper@glasgow.ac.uk>
2025-07-11 16:14:03 +00:00

4.7 KiB

Contributing to the OpenFlexure Microscope Server

All contributions to the OpenFlexure project should follow our project contributions guidelines.

Any contributions to any of our projects should follow our code of conduct.

If you are interested in contributing to the OpenFlexure project, and do not know where to start, we recommend you visit our forum.

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.

Python Development

For installation, see the project README.

Core packages and concepts

The OpenFlexure Microscope server is built in the LabThings-FastAPI framework. This provides a convenient way to expose laboratory hardware over HTTP via a FastAPI server.

The core elements of the server code are Things. A Thing creates a W3C Web of Things compliant HTTP interface for hardware interactions and other server functionality.

The project also makes use of the following libraries:

  • Pydantic - For serialising/deserialising data being saved to disk or sent over HTTP.
  • OpenFlexure Stitching - Our own library for creating composite microscope images from a scan.
  • OpenCV and Picamera2 - For controlling cameras, and simulating cameras for tests.
  • Pillow - For image manipulation and saving.
  • NumPy and SciPy - 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)

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 is used both for linting and formatting the codebase. Our custom linter rules are in our pyproject.toml. As we improve the codebase, more rules are being added to the linter; see ruff-increased-checking.toml for checks that we plan to get passing.

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.

#!/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, and process them with pydoctor.

For function arguments, return values, and exceptions we use the following style recognised by reStructuredText:

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. 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.