101 lines
4.6 KiB
Markdown
101 lines
4.6 KiB
Markdown
# 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/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.
|