Wahlkampf-App-Backend
This is a django based web service, used as a backend to the Wahlkampf-App
of "DIE LINKE"
The document below will lead you through the setup of a local development environment.
Also see notes on infrastructure and architecture.
Usage
API Schema, ReDoc and Swagger
This project offers a auto-generated documentation page in form of a REST Swagger and ReDoc leveraging an OpenAPI 3 schema.
- /api/v1/docs <- An API Explorer powered by ReDoc
- /api/v1/swagger <- REST swagger
- /api/v1/schema <- OpenAPI3 compliant API schema
If you visit these Pages with your browser please note that you will only see endpoints you have sufficient permissions for. If you are not authenticated you will see an authentication error. To authenticate in you browser session see Session-based authentication
Authentication
Token based authentication
To authenticate against the API we use django-oauth-toolkit and provide the necessary oauth2 compliant endpoints under
/oauth2/
. See RFC6749 or the documentation of django-oauth-toolkit to
see detailed usage instructions.
Session-based authentication
Using the login form at /admin/
you can start an authenticated browser session making it easy to explore the API with the
REST swagger at /api/v1/swagger
. API Clients should use the token based authentication.
Admin interface
You can access the django admin at /admin/
. Some basic admin interfaces are enabled to create and modify data, mainly for testing and tinkering purposes.
You can log in using some example users. Their passwords can be found on our bitwarden.
DIE LINKE associations data
DIE LINKE is segmented in different organizational units that map onto different administrative units in germany: ARCHITECTURE.md#Districts_States_Associations. To have this data in your local environment import it from the fixtures:
$ python manage.py loaddata core/fixtures/associations.json
Development
Guidelines
This project mainly implements a REST API, the standards we adhere to are defined in REST.md
Setup
System dependencies
This project is compatible with python 3.9 upwards.
Using Postgres with PostGIS this project need two system level libraries installed: GDAL and postgres-lib.
In the arch package manager an install command would look like this.
$ sudo pacman -S postgresql-libs gdal python-gdal
If you are using another OS / Distribution you'll have to research how to retrieve this software.
Poetry and application dependencies
This project uses poetry for package management
To setup project make sure poetry(>=1.0.0) is installed on your computer (pip install poetry
), then:
$ poetry install
To run commands inside the poetry-created virtualenv either prepend poetry run
to your commands (i.e. poetry run python manage.py runserver
) or
enter the virtualenv with poetry shell
.
Note: You might get errors if you are missing the system dependencies
Lint
This project uses flake8
which is configured in .flake8
and invoked like this.
$ flake8
Pre-commit checks
To avoid checking in unlinted or untested code there is a .pre-commit-config.yaml
for convenience. You might install it with pre-commit
:
$ pre-commit install # install the hook
Remark
Be aware this also executes tests on committing, which requires the postgres server to run. See Database
Database
To develop or execute tests (which is highly recommended) you need a running postgres database. If you stick with the default settings you can easily create a local postgres (with postgis enabled!) instance with docker:
$ docker run -p 5432:5432 -e POSTGRES_USER=wkservice -e POSTGRES_HOST_AUTH_METHOD=trust postgis/postgis
Please not without mounting the data directory of that container all data is lost on re-instantiating/start a new container. To persist in .psql_data
use it like this:
docker run -p 5432:5432 -e POSTGRES_USER=wkservice -v `pwd`/.psql_data:/var/lib/postgresql/data -e POSTGRES_HOST_AUTH_METHOD=trust postgis/postgis
Variables might need adjustment if you altered the database settings.
DB for OSM related queries
You can create your own db filled with OSM data, see Nominatim.
Or you could use our shared one. To do so:
$ cp -n wk_app/settings/local.py.dist wk_app/settings/local.py
and fill in the PASSWORD
from shared PW store in the created local.py
.
Migrate schema
To update your development database to match current migration status run
$ python manage.py migrate
Example Data
Conveniently this repository provides some example data jumpstart development and provide some basic data to get started. To use these example data fixtures use the following command:
$ python manage.py loaddata core/fixtures/example_data.json
You will find some basic data filled for events, campaigns, oauth2 applications and users. If you don't know the credentials to these users you need to reset them via shell.
⚠️ Do not use this example data on production systems as it contains example secrets that are considered broken ⚠️
Run service
Run the service like any django project
$ python manage.py runserver
Run celery
For asynchronous tasks this project uses celery. If you work on asynchronous tasks it's advisable to actually run a celery runner. For minimal setup just start a redis server and a celery runner
$ redis-server
$ celery -A wk_app.celery worker --loglevel=INFO -B
For development disregarding the asynchronous quirks, it might also be feasible to just set CELERY_TASK_ALWAYS_EAGER
to True
in your local settings. This will lead to all normally dispatched tasks to be executed synchronously.
(Optional) Create Admin user
$ python manage.py createsuperuser
With the admin user you can login to http://127.0.0.1:8000/admin/
Hint: You can also take an user created from core/fixtures/example_data.json
. For PW check shared PW store.
Troubleshoot
Why am i getting "psycopg2.errors.InvalidCursorName: cursor "django_curs[...]" does not exist"
Probably forgot to run python run makemigrations
after altering the models
Run tests
To run the test suite you need to set the DJANGO_SETTINGS_MODULE
environment variable to the test settings path and
then run django tests as usual:
$ DJANGO_SETTINGS_MODULE=wk_app.settings.tests python manage.py test
Releasing / Versioning
The release is done as follows. Create a branch coming from develop
. It must be named according to the following
scheme:
release/MAJOR.MINOR.PATCH
E.g.:
release/0.5.1 ✓
release/0.5.1-rc.1 ✗
release/0.5 ✗
release/teststring ✗
This will update the staging environment. After merging the branch to main
, a tagged commit needs to be added to the
main branch.