Skip to Content
ContributeBackendDevelopment Workflow

Development Workflow

Day-to-day commands for backend contributors. To run the server locally, see the Backend Overview.

Formatting and linting

From apps/backend:

format-and-lint.sh
make format      # auto-format and fix all Python files
make lint        # check formatting without modifying files

Both targets run ruff  via uvx. Diff-scoped variants run only against files changed relative to main:

format-and-lint-diff.sh
make format_diff
make lint_diff

Type hints are encouraged for readability and IDE support; enforcement is not strict everywhere.

Tests

Tests live in tests/backend/, wired through the backend pyproject.toml. Run them from apps/backend. Postgres and Redis are started automatically via Testcontainers  — Docker must be running, but there’s no container setup step.

Full suitemake test runs pytest on ../../tests/backend (see the Makefile for flags).

Single test or file:

run-specific-test.sh
uv run --extra cpu pytest ../../tests/backend/models/test_foo.py::TestClass::test_name -v

Your usual dev database containers are not used; each test run gets its own ephemeral Postgres and Redis instance.

Database changes

For a schema change:

  1. Edit the SQLAlchemy model in app/models/ and import it in app/models/__init__.py.
  2. Generate a migration: alembic revision --autogenerate -m "Description of changes".
  3. Review the generated file under alembic/versions/, then apply it: alembic upgrade head.

New models usually need matching Pydantic schemas in app/schemas/ and CRUD helpers in app/crud.py.

Adding endpoints and tasks

  • Endpoints — add or edit a router in app/routers/ and register it in app/routers/__init__.py.
  • Celery tasks — add the task under tasks/ and register it in tasks/__init__.py. Run a worker with ./rh dev worker to exercise it (see Background tasks).

Debugging

Log through the application logger so output is redacted and formatted consistently (see Architecture):

logging-example.py
from rhesis.backend.logging import logger

logger.debug("Debug message")
logger.info("Info message")

Common local issues: wrong DB_HOST/APP_DB_PASS or Postgres not running, missing .env keys, or JWT/auth misconfiguration. Check logs and Environment configuration.

Before opening a PR

Tests green, ruff clean, env-var and migration changes reviewed. See the repository contribution rules for commit and PR conventions, and Deployment for release steps.