95 lines
No EOL
3.8 KiB
Markdown
95 lines
No EOL
3.8 KiB
Markdown
# Python Server Development
|
|
|
|
## Overview
|
|
|
|
|
|
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))
|
|
|
|
|
|
## 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:` 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.
|
|
|
|
Please run:
|
|
|
|
* `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
|
|
* `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`.
|
|
|
|
|
|
```python
|
|
#!/bin/bash
|
|
|
|
set -e
|
|
|
|
function angrymessage()
|
|
{
|
|
RED='\033[1;31m'
|
|
NC='\033[0m' # No Color
|
|
printf "\n${RED}Not committing as ruff or spellcheck failed${NC}\n\n"
|
|
}
|
|
|
|
trap angrymessage ERR
|
|
|
|
ruff format --check
|
|
ruff check
|
|
codespell .
|
|
```
|
|
|
|
|
|
## 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. |