Skip to content

Contributing to Korobka¤

Thank you for your interest in contributing. Before starting, please take a moment to read our Code of Conduct.

Overview¤

This project uses GitHub Flow for collaboration.

  • Poetry — dependency management and packaging
  • pre-commit — formatting and linting hooks (ruff, mypy, codespell)
  • pytest — unit and integration tests
  • MkDocs — API documentation generated from docstrings
  • GitHub Actions — runs tests and checks on every pull request

Initial setup¤

  1. Install Poetry for your OS.

  2. Clone the repository and enter the directory:

bash git clone https://github.com/imperial-college-london/korobka.git cd korobka

  1. Install all dependencies, including dev and docs groups:

bash poetry install --with dev,docs

  1. Activate the virtual environment (or prefix every command with poetry run):

bash eval $(poetry env activate)

  1. Install the git hooks:

bash pre-commit install


Contribution workflow¤

1. Create a branch¤

Work on a dedicated branch so your changes are isolated until they are ready to review.

git checkout -b <branch-name>

[!TIP] Use short, descriptive names: add-sartorius-balance, fix-dobot-timeout, refactor-serial-base.

2. Make changes¤

  • Commit often — small, self-contained commits are easier to review and revert.
  • Write clear commit messages — say why, not just what.
  • Push regularly — keeps your work backed up and visible to collaborators.

Pre-commit hooks¤

The hooks run automatically on git commit and will fix many formatting issues in place. When they do, stage the changes and commit again:

git add -u
git commit

When a hook cannot auto-fix an issue it will print an error. Read the output, fix the problem manually, then stage and commit.

You can also run the hooks manually at any time:

pre-commit run --all-files

3. Open a pull request¤

Push your branch and open a pull request (PR) against main:

git push origin <branch-name>

Your PR description should explain what changed and why. Link to any relevant issues. GitHub Actions will run the full test suite automatically — all checks must pass before merging.

[!TIP] Open a draft PR early if you want feedback before the work is finished.

4. Address review comments¤

At least one approval from a maintainer is required before merging. Reviewers may leave comments on the whole PR or on specific lines. Push additional commits to address feedback — the PR updates automatically.

5. Merge and clean up¤

Once approved and green, merge the PR. Delete the branch afterwards — there is a button for this in the GitHub interface, or do it locally:

git checkout main
git pull
git branch -d <branch-name>

Code style¤

Code style is enforced automatically by ruff (formatting, linting, import sorting) and mypy (type checking). The key conventions are:

  • Line length: 120 characters.
  • Docstrings: Google style — every public module, class, and method must have one.
  • Type annotations: Required on all function signatures. mypy is set to disallow_untyped_defs = true.
  • Python version: 3.12+. Use modern syntax (X | Y unions, match statements, etc.) where it improves clarity.

Adding support for new hardware¤

Korobka's hardware drivers follow a consistent pattern. To add a new device:

  1. Choose the right base class from korobka/connections/:
  2. BaseSerial — RS-232 serial devices
  3. BaseModbus — Modbus RTU devices (RS-485)
  4. BaseTCPIP — TCP/IP socket devices

  5. Create a new module in the relevant category directory (e.g. korobka/balances/balance_sartorius.py).

  6. Implement a class that inherits from the base and adds device-specific methods. Look at an existing driver (e.g. balance_ohaus.py) as a template.

  7. Write tests in the corresponding tests/ subdirectory. Mock the underlying serial/network connection — no physical hardware should be required to run tests (see Testing below).

  8. Add a docstring to every public method with Args, Returns, and Raises sections.

  9. Export the class from the package's __init__.py if appropriate.


Testing¤

All tests live in tests/, mirroring the package structure. Run the full suite with:

poetry run pytest

Run a specific module:

poetry run pytest tests/test_balances/

Mocking hardware¤

Korobka's devices communicate over serial ports and network sockets. Tests should never require physical hardware. Use pytest-mock to patch the low-level communication layer. For example, to test a serial device:

def test_weigh(mocker):
    mock_serial = mocker.patch("korobka.connections.base_serial.serial.Serial")
    mock_serial.return_value.read_until.return_value = b"     12.345 g\r\n"

    balance = Balance(port="/dev/ttyUSB0")
    result = balance.weigh()

    assert result == pytest.approx(12.345)

For sequential responses (e.g. a door open/close sequence), use side_effect:

mock_serial.return_value.read_until.side_effect = [b"D  \r\n", b"D O\r\n"]

Coverage¤

The test run generates an HTML coverage report in htmlcov/. Open htmlcov/index.html in a browser to see line-by-line coverage.


Documentation¤

API docs are generated from docstrings with MkDocs. To preview them locally:

poetry run mkdocs serve

Navigate to http://127.0.0.1:8000. The docs rebuild automatically when you save changes.

To build the static site:

poetry run mkdocs build

Running individual tools¤

# Type checking
poetry run mypy korobka/

# Linting and formatting
poetry run ruff check korobka/
poetry run ruff format korobka/

# Spell checking
poetry run codespell korobka/