Development guide¶
Hanson is written in Python and uses Postgres as its database.
Development environment¶
To enter a development environment with the right version of Postgres, Python, Python packages, and axiliary tools in scope, you can use Nix version 2.11. If you haven’t already, enable flake support by adding the following line to your ~/.config/nix/nix.conf
:
experimental-features = nix-command flakes
Then enter a development shell with
nix develop --command $SHELL
Database setup¶
The development environment includes a pinned version of Postgres. The script tools/run_postgres.py
starts a sufficiently configured Postgres process that listens on a domain socket. Start one that puts its data in run/db_dev
:
tools/run_postgres.py --force-init run/db_dev
Then in a different shell, perform the initial setup that creates the database and database users, and then run all migrations to populate the schema:
export PGHOST="$PWD/run/db_dev"
tools/migrate.py setup
tools/migrate.py migrate latest
After this you can Ctrl + C the Postgres process in the other shell. You will not need to start it manually any more, see also Running the application below.
The development shell by defaults sets the PGDATABASE
, PGUSER
, and PGPASSWORD
environment variables. If you export PGHOST=$PWD/run/db_dev
, then psql
can be used directly to inspect the database.
Migrations¶
The repository includes a simple migration tool, tools/migrate.py
. It loads migrations from the migrations
directory.
Migrations must be .sql
files whose filename starts with a 4-digit sequence number. Each constists of an upgrade and downgrade section as indicated with a comment:
-- migrate:up
CREATE TABLE "...";
-- migrate:down
DROP TABLE "...";
The migration tool stores the current schema version in the _schema_migrations
table. Run tools/migrate.py --help
for more information.
Running the application¶
The repository contains a Procfile that defines all processes needed to run Hanson (Postgres and Flask). The development environment includes Overmind which can start all processes in the Procfile, and which interleaves their output on stdout. To bring everything up:
overmind start
By default Flask listens on http://localhost:5000. However, the database does not contain any users or interesting data. To add a few users and give them some points to spend, use the admin CLI tool:
./cli.py add-user etyrell "Eldon Tyrell"
./cli.py add-user lkowalski "Leon Kowalski"
./cli.py add-user rbatty "Roy Batty"
./cli.py add-user rdeckard "Rick Deckard"
./cli.py airdrop 25.0
After this you can log in by username. In development mode Hanson does not authenticate users, the plan is to outsource this to a third-party identity provider.
Running tests¶
Run the tests:
python -m pytest tests
The tests will use an independent database at run/db_test
, so the tests do not interfere with the development database. The tests start this Postgres instance in the test fixture, so this does not depend on any daemon to be running.
Typechecking¶
Typecheck with Mypy:
mypy --strict .
Formatting¶
All code is formatted with Black:
black .