Backend of the leading political information chatbot for the German federal elections 2025.
Application URL: https://wahl.chat/
About page: https://wahl.chat/about-us
The aim of wahl.chat is to enable users to engage in a contemporary way with the positions of political parties and to receive answers to individual questions that can be substantiated with sources.
We appreciate contributions from our community. Please take a look at the open issues, if you are interested.
If you are unsure where to start, please contact [email protected].
Further specifications coming soon.
This project is source-available under the PolyForm Noncommercial 1.0.0 license.
- Free for non-commercial use (see LICENSE for permitted purposes)
- Share the license text and any
Required Notice:lines when distributing - Please contact us at [email protected] to a. Inform us about your use case b. Get access to assets required for a reference to wahl.chat on your project page
- Do not use the wahl.chat name or logo in your project without our permission
This project was initially implemented for the German political system. To adapt it for use in other countries, you will need to adjust the prompts and data schemas to fit the target locale and political context.
ℹ️ Need help? If you have any remaining setup questions, please contact us at [email protected].
- Install poetry using the official installer using python 3.10-3.12 (
curl -sSL https://install.python-poetry.org | python3 -) - Run
poetry installin the root directory of this repository (runpoetry install --with devto install with dev dependencies)
poetry run pre-commit install
Create a .env file with the environment variables as defined in .env.example.
Regarding the Langchain API key you have 3 Options (it is needed for langchain tracing on smith.langchain.com)
- Set up your own project and API key at smith.langchain.com
- Set
LANGCHAIN_TRACING_V2=falseto deactivate tracing.
Run gcloud auth application-default login and authenticate with your Google Cloud account that has access to the Firebase wahl-chat-dev project. Make sure to set the project your Firebase wahl-chat-dev project in the gcloud CLI with gcloud config set project wahl-chat-dev.
Add a file named wahl-chat-dev-firebase-adminsdk.json to the root directory of this repository. This file can be generated at https://console.firebase.google.com/u/0/project/wahl-chat-dev/settings/serviceaccounts/adminsdk
poetry run python -m src.aiohttp_app --debug
-
Build the image
docker build -t wahl-chat:latest . -
Run using a Firebase Admin SDK service account file (dev/prod)
-
Prerequisites:
.envin the project root (see.env.example)- For dev:
wahl-chat-dev-firebase-adminsdk.jsonin the project root before building the image (download from the Firebase console as described above). - For prod:
wahl-chat-firebase-adminsdk.jsonin the project root before building the image.
-
Run (dev):
docker run --env-file .env -p 8080:8080 wahl-chat:latest
With
ENV=devin.env, the backend will usewahl-chat-dev-firebase-adminsdk.jsoninside the container if present; otherwise it falls back to Application Default Credentials. -
Run (prod):
docker run --env-file .env -p 8080:8080 wahl-chat:latest
With
ENV=prodin.env, the backend will usewahl-chat-firebase-adminsdk.jsoninside the container if present; otherwise it falls back to Application Default Credentials.
-
-
Run using Google Application Default Credentials (gcloud ADC)
-
Prerequisites:
gcloud auth application-default loginhas been run locally.- Your ADC file exists at
~/.config/gcloud/application_default_credentials.json.
-
Command:
ADC=~/.config/gcloud/application_default_credentials.json && \ docker run --env-file .env \ -e GOOGLE_APPLICATION_CREDENTIALS=/tmp/keys/application_default_credentials.json \ -e GOOGLE_CLOUD_PROJECT=wahl-chat-dev \ -v ${ADC}:/tmp/keys/application_default_credentials.json:ro \ -p 8080:8080 \ wahl-chat:latest
In this setup,
wahl-chat-*-firebase-adminsdk.jsonfile is not required in the image. Firebase Admin will use the mounted ADC credentials instead. Make sure to set theGOOGLE_CLOUD_PROJECTenvironment variable to the project ID of the Firebase project you want to use.
-
Prerequisite: run the backend locally
All websocket tests: poetry run pytest tests/test_websocket_app.py -s
Specific websocket test: poetry run pytest tests/test_websocket_app.py -k test_get_chat_answer -s
Note: the following commands are to be run in the firebase directory of this repository.
Firebase CLI: npm install -g firebase-tools & firebase login
node-firestore-import-export: npm install -g node-firestore-import-export
- Select the project you want to deploy to:
firebase use devorfirebase use prod - Deploying the Firestore Rules:
firebase deploy --only firestore:rules - Deploying the Storage Rules:
firebase deploy --only storage - Deploying the Firestore Indexes:
firebase deploy --only firestore:indexes - Deploying the Firebase Functions:
firebase deploy --only functions - Deploying a specific function:
firebase deploy --only functions:FUNCTION_NAME
- Export the parties from the dev-database:
firestore-export --accountCredentials ../wahl-chat-dev-firebase-adminsdk.json --backupFile firestore_data/dev/parties.json --nodePath parties -p - Copy
firestore_data/dev/parties.jsontofirestore_data/prod/parties.json - IMPORTANT: Replace Firebase-Storage dev-URLs with prod-URLs (e.g. https://storage.googleapis.com/wahl-chat-dev.firebasestorage.app/public/bsw/Kurzwahlprogramm%20BTW25_2024-12-21.pdf --> https://storage.googleapis.com/wahl-chat.firebasestorage.app/public/bsw/Kurzwahlprogramm%20BTW25_2024-12-21.pdf): ctrl-f for
https://storage.googleapis.com/wahl-chat-dev.firebasestorage.appand replace withhttps://storage.googleapis.com/wahl-chat.firebasestorage.app - Import the parties to the prod-database:
firestore-import --accountCredentials ../wahl-chat-firebase-adminsdk.json --backupFile firestore_data/prod/parties.json --nodePath parties
- Export from the party where the questions already exist
firestore-export --accountCredentials ../wahl-chat-dev-firebase-adminsdk.json --backupFile firestore_data/proposed_questions_afd_questions.json --nodePath proposed_questions/afd/questions -p - Import to the party where the questions should be added
firestore-import --accountCredentials ../wahl-chat-dev-firebase-adminsdk.json --backupFile firestore_data/proposed_questions_afd_questions.json --nodePath proposed_questions/bsw/questions
- Export the proposed_questions collection from dev:
firestore-export --accountCredentials ../wahl-chat-dev-firebase-adminsdk.json --backupFile firestore_data/proposed_questions.json --nodePath proposed_questions -p - Modify the
firestore_data/proposed_questions.jsonfile - Import the proposed_questions collection to dev:
firestore-import --accountCredentials ../wahl-chat-dev-firebase-adminsdk.json --backupFile firestore_data/proposed_questions.json --nodePath proposed_questions
- Export the proposed_questions collection from dev:
firestore-export --accountCredentials ../wahl-chat-dev-firebase-adminsdk.json --backupFile firestore_data/proposed_questions.json --nodePath proposed_questions -p - Import the proposed_questions collection to prod:
firestore-import --accountCredentials ../wahl-chat-firebase-adminsdk.json --backupFile firestore_data/proposed_questions.json --nodePath proposed_questions