Backend#
The python backend monolith
Install Dependencies#
poetry install
Setup Local Git Hooks#
The repository uses pre-commit to maintain and configure the local git hooks,
but they need to be installed manually.
poetry run pre-commit install
Troubleshooting hooks#
When the pre-commit hooks fail, they typically provide enough context to let you know which plugin/rule has failed and why. The most common error will be linting/formatting which can be fixed by manually running black or ruff
poetry run ruff check .
or
poetry run black .
Running locally with Docker + Docker Compose 🐳#
We support a full-fledged API environment with pubsub emulation, github webhook proxy via smee, cloudfunction running, and our API running in development mode with hot reloads enabled.
To use this the only thing you need to do is make sure supabase is running (supabase start) as we connect to it over the host network using our api container. You must also have a .env.local file setup with your local environment information.
Then we simply build our containers then run them. You only need to rebuild if you make changes to things like packages etc. We use hot reloads with Uvicorn + volume mounts to automatically rebuild when changes are detected (you make a save to a file in your IDE for example).
Build containers#
docker compose build
Start containers#
docker compose up
The API is exposed to your host machine via localhost:8000 if you want to access endpoints directly, but the other services just talk to each other over a docker bridge network.
Rebuild images#
When dependencies change, we have to rebuild the images:
make all-up
Lightweight agent dev environment#
Running all containers can be quite heavy on resources. If you only need
the agent and the public API, you can get away with:
make agent-up
Lightweight development shell#
If you just want to open an interactive shell in the local dev environment, you can
launch a standalone container:
make ipython
or
make bash
This will run (rather than up) a container for a standalone interpreter session.
Advantages:
- This container doesn't auto-restart with file updates like e.g.
apidoes, so you
can keep your shell open as long as you want. - It has a volume that remembers your ipython command history even if you exit and re-start.
- It runs as a standalone temporary container which removes itself on shell exit.
This allows for fast interactive debugging and testing without bringing up the entire dev environment. - You can use this container as a remote interpreter for your IDE. For example...
PyCharm remote interpreter setup#
PyCharm supports using a Python interpreter inside a Docker container for code
inspection / completion. To configure it to use the interpreter in the
local-shell container:
- Open the project's Python Interpreter settings (available in the bottom status
strip or via Settings → Project: dosu → Python Interpreter). - Click the "Add Interpreter" dropdown and select "On Docker Compose..."
- Open the Configuration File picker and use the + button to add
backend/docker-compose.yaml - The service drop-down should populate. Select
local-shellas the service. - Press Next and PyCharm will do some configuration to access the service. When
it's finished, look for any errors - it should exit with status 0. Press Next again. - Set the interpreter path to
/usr/local/bin/python3.12and press "Create". - You should return to the main interpreter settings menu, where you should see
all of our project dependencies listed in the available packages. "OK" your way
out of the menu.
PyCharm will spend a few minutes in the background indexing the project and then
code inspections etc. should work as if you are inside the container environment.
It's likely that other IDEs support similar configurations, so please add instructions
if you get it working with a different one.
Directory Structure#
/core#
This is code shared between Cloud Functions and the API. We use the core as a namespace to avoid naming conflicts with pip packages.
/tests#
Python PyTest tests
To run all tests,
poetry run python -m pytest tests/
To run all a single test file,
poetry run python -m pytest tests/path_to_my_test_file.py
Troubleshooting#
Problem: Docker fails and cannot find installed packages
Solution: Make sure that there is no .venv directory in the /backend dir, Docker will copy it over and break.
Problem: Docker cannot find packages
Solution: Rebuild images (see above).