Local Setup
Local development setup
This guide walks you through running the backend directly on your machine (without Docker).
This guide assumes you have the main prerequisites installed:
- Python 3.12+
- MongoDB
- (Optional) Docker & Docker Compose for containerized setup: see Docker setup for install instructions
If you need help installing Python or MongoDB, see the Detailed installation commands for prerequisites section at the bottom of this page.
1. Clone the repository
git clone https://github.com/eve-esa/backend.git
cd backend
2. Create and activate a virtual environment
macOS / Linux:
python3 -m venv venv
source venv/bin/activate
Windows (PowerShell):
python -m venv venv
.\venv\Scripts\activate
3. Configure environment variables
-
Copy the example file:
bash cp .env.example .env -
Edit
.envand at minimum configure values for:- **Qdrant / vector store** - `QDRANT_URL` - `QDRANT_API_KEY` (can be empty for local/self‑hosted Qdrant without auth) - **LLM endpoints** - `MAIN_MODEL_URL` - `MAIN_MODEL_API_KEY` - **Embeddings** - `EMBEDDING_URL` (has a sensible default) - `EMBEDDING_API_KEY` - **MongoDB** - `MONGO_HOST` (usually `localhost`) - `MONGO_PORT` (usually `27017`) - `MONGO_DATABASE` (for example `eve-backend`) - **Auth (OIDC)** - `AUTH_ISSUER` (`http://localhost:8080/realms/eve`) - `AUTH_CLIENT_ID` (`eve-frontend`) - `AUTH_DISCOVERY_URL` (only when the backend reaches the provider at another address than the issuer) - `AUTH_ALLOW_INSECURE_HTTP=true` (local only, the realm is served over plain http)
QDRANT_URL, QDRANT_API_KEY, AUTH_ISSUER and AUTH_CLIENT_ID are read at import: the names must exist in .env, or the backend fails to start. An empty value is allowed for QDRANT_API_KEY.
Sign-in goes through an OIDC provider; the backend has no login endpoint of its own. Locally the provider is Keycloak, started by docker compose up -d keycloak with the realm eve from infra/identity/keycloak/realm/eve-realm.json (client eve-frontend). Sign in at the frontend as dev@eve.example.com / eve-dev-password.
Other variables in the table in the Environment variable reference section below are optional for basic local development and can be configured later as you enable more features (SMTP, Satcom, external rerankers, etc.).
4. Install dependencies
With the virtual environment activated:
pip install -r requirements-dev.txt
requirements-dev.txt adds the test suite and the docs toolchain to requirements.txt, which is
all the production image installs.
5. Run MongoDB (local)
Make sure MongoDB is running:
- macOS (Homebrew):
brew services start mongodb-community@7.0 - Ubuntu:
sudo systemctl start mongod - Windows: MongoDB service usually starts automatically after installation
6. Start the backend
chmod +x start.sh
./start.sh
The API and interactive docs should now be available at:
http://localhost:8000/docs
To run the test suite, give the free tier a token budget, otherwise the rate limit tests fail and reach the real model:
FREE_TOKENS=100 FREE_PERIOD_MONTHS=1 pytest -m "not e2e"
In the Docker setup: docker compose exec -T -e FREE_TOKENS=100 -e FREE_PERIOD_MONTHS=1 backend pytest -m "not e2e".
7. Environment variable reference
Below is a more complete example of .env and a description of the most important variables. This applies to both local development and Docker-based setups.
PORT=8000 # for docker
WORKERS=2 # for docker
# QDRANT Configuration
QDRANT_URL=
QDRANT_API_KEY=
# LLM Model URLs (OpenAI-compatible format)
MAIN_MODEL_URL=https://api.runpod.ai/v2/2f9o93xc90871m/openai/v1
FALLBACK_MODEL_URL=https://api.mistral.ai/v1
# Optional: Override model names (defaults from config.yaml)
MAIN_MODEL_NAME=
FALLBACK_MODEL_NAME=
MAIN_MODEL_API_KEY=
FALLBACK_MODEL_API_KEY=
MODEL_TIMEOUT=13
EMBEDDING_URL=https://api.deepinfra.com/v1/openai
EMBEDDING_API_KEY=
# MongoDB Configuration
MONGO_HOST=localhost
MONGO_PORT=27017
MONGO_USERNAME=root
MONGO_PASSWORD=
MONGO_DATABASE=eve-backend
MONGO_PARAMS=
# Identity provider (local Keycloak, realm "eve")
AUTH_ISSUER=http://localhost:8080/realms/eve
AUTH_DISCOVERY_URL=http://keycloak:8080/realms/eve/.well-known/openid-configuration
AUTH_CLIENT_ID=eve-frontend
AUTH_ALLOW_INSECURE_HTTP=true
# SMTP
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=
SMTP_PASSWORD=
EMAIL_FROM_ADDRESS=
EMAIL_FROM_NAME=EVE
# CORS (comma separated list)
CORS_ALLOWED_ORIGINS=http://localhost:5173
DEEPINFRA_API_TOKEN=
SCRAPING_DOG_API_KEY=
SATCOM_SMALL_MODEL_NAME=esa-sceva/satcom-chat-8b
SATCOM_LARGE_MODEL_NAME=esa-sceva/satcom-chat-70b
SATCOM_LARGE_BASE_URL=https://api.runpod.ai/v2/zyy9iu4i7vmcxc/openai/v1
SATCOM_SMALL_BASE_URL=https://api.runpod.ai/v2/ucttr8up9sxh0k/openai/v1
SATCOM_RUNPOD_API_KEY=
REDIS_URL=redis://127.0.0.1:6379/0
APP_ENVIRONMENT=dev
# Test gate only: a token budget for the free tier
# FREE_TOKENS=100
# FREE_PERIOD_MONTHS=1
| Variable | Required | Description / Default |
|---|---|---|
PORT |
Yes (for docker) | Backend PORT (default: 8000) |
WORKERS |
Yes (for docker) | Gunicorn worker count (default 2). |
QDRANT_URL |
Yes | Base URL for the primary Qdrant instance. |
QDRANT_API_KEY |
Yes | API key for the primary Qdrant instance. |
MAIN_MODEL_URL |
Yes | OpenAI-compatible URL for the main LLM model (e.g., https://api.runpod.ai/v2/{endpoint_id}/openai/v1 or http://localhost:8000/v1). |
FALLBACK_MODEL_URL |
Yes | OpenAI-compatible URL for the fallback LLM model (e.g., https://api.mistral.ai/v1 or any OpenAI-compatible endpoint). |
MAIN_MODEL_NAME |
No | Model name for the main model (defaults to value in config.yaml). |
FALLBACK_MODEL_NAME |
No | Model name for the fallback model (defaults to value in config.yaml). |
MAIN_MODEL_API_KEY |
No | API key for the main model. |
FALLBACK_MODEL_API_KEY |
No | API key for the fallback model. |
MODEL_TIMEOUT |
No | Timeout in seconds for model calls (default 13). |
EMBEDDING_URL |
Yes | Main Embedding Model(Qwen/Qwen3-Embedding-4B) provider url, OpenAI capatible (e.g., https://api.deepinfra.com/v1/openai) |
EMBEDDING_API_KEY |
Yes | Main Embedding Model provider API token |
DEEPINFRA_API_TOKEN |
Yes | DeepInfra API token for embedding and reranking retrieved documents (recommended for best retrieval quality, but backend still works without it). |
MONGO_HOST |
Yes | MongoDB host (default localhost or mongo in docker). |
MONGO_PORT |
Yes | MongoDB port (default 27017). |
MONGO_USERNAME |
No | MongoDB username (empty allowed for local). |
MONGO_PASSWORD |
No | MongoDB password. |
MONGO_DATABASE |
Yes | MongoDB database name (default eve-backend). |
MONGO_PARAMS |
No | Extra Mongo connection params (default ?authSource=admin). |
AUTH_ISSUER |
Yes | OIDC issuer, exactly as it appears in the token iss claim. Locally http://localhost:8080/realms/eve. |
AUTH_CLIENT_ID |
Yes | OIDC client the frontend signs in with. Locally eve-frontend. |
AUTH_DISCOVERY_URL |
No | Discovery document URL when the backend reaches the provider at another address than the issuer (in compose: http://keycloak:8080/realms/eve/.well-known/openid-configuration). Defaults to the issuer's discovery URL. |
AUTH_ALLOW_INSECURE_HTTP |
No | true accepts an http issuer. Local only; every deployed environment uses https. |
AUTH_AUDIENCE |
No | Expected token audience (default AUTH_CLIENT_ID). |
SMTP_HOST |
No | SMTP host (default smtp.gmail.com). |
SMTP_PORT |
No | SMTP port (default 587). |
SMTP_USERNAME |
No | SMTP username. |
SMTP_PASSWORD |
No | SMTP password. |
SMTP_FROM_ADDRESS |
No | From header on the SMTP path only; blank falls back to EMAIL_FROM_ADDRESS. |
MAIL_CANARY_TAG |
No | With MAIL_TRANSPORT=ses, recipients whose local part contains this tag go through SMTP; blank matches nobody. |
MAIL_FALLBACK_TRANSPORT |
No | ses resends through SES, from EMAIL_FROM_ADDRESS, a message the SMTP path failed on; blank (default) means no fallback. |
EMAIL_FROM_ADDRESS |
No | Sender email address. |
EMAIL_FROM_NAME |
No | Sender display name (default EVE). |
CORS_ALLOWED_ORIGINS |
No | Comma-separated list of allowed origins (default http://localhost:5173). |
SCRAPING_DOG_API_KEY |
No | API key for ScrapingDog service, used as fallback of retrieval. |
SATCOM_SMALL_MODEL_NAME |
No | Model name for Satcom small LLM. |
SATCOM_LARGE_MODEL_NAME |
No | Model name for Satcom large LLM. |
SATCOM_SMALL_BASE_URL / SATCOM_LARGE_BASE_URL |
No | OpenAI-compatible URLs of the Satcom small and large endpoints. |
SATCOM_RUNPOD_API_KEY |
No | API key for Satcom Runpod workloads. |
EVE_JSC_BASE_URL |
No | OpenAI-compatible URL for the EVE-JSC model (required when llm_type is eve_jsc). |
EVE_JSC_MODEL_NAME |
No | Model name for EVE-JSC (default alias-eve). |
EVE_JSC_API_KEY |
No | API key for EVE-JSC, issued by Jülich (required when llm_type is eve_jsc or a model is called with the jsc/ prefix; a blank value counts as unset). |
OPENAI_PROXY_UPSTREAM_URL |
No | OpenAI-compatible URL the /v1/* proxy forwards eve/runpod models to. Setting this or EVE_JSC_BASE_URL enables the proxy. |
OPENAI_PROXY_API_KEY |
No | API key for that upstream (falls back to MAIN_MODEL_API_KEY, which is the same RunPod endpoint). |
REDIS_URL |
Yes | Redis connection string for pub/sub and cancellations (optional; if not set, in-process cancellation is used)(default redis://127.0.0.1:6379/0). |
APP_ENVIRONMENT |
No | dev, staging or prod. Selects the public collections, the default model and the private collection name; anything else reads as non-production. |
LOG_LEVEL |
No | Root log level: DEBUG, INFO, WARNING or ERROR (default INFO). DEBUG gives the verbose output the server used to run with. httpx, httpcore, urllib3, pymongo, botocore, boto3, openai and mcp stay at WARNING at every level, since they log request URLs and query bodies. |
OTEL_EXPORTER_OTLP_ENDPOINT |
No | OTLP HTTP collector base URL, e.g. http://otel-collector:4318 with the stack clickstack profile. Unset or empty keeps telemetry off: no SDK import, no exporter thread, no middleware. |
OTEL_EXPORTER_OTLP_HEADERS |
No | Secret. Headers for the collector, authorization=<ingest key>. |
OTEL_EXPORTER_OTLP_PROTOCOL |
No | http/protobuf, the only protocol shipped. |
OTEL_RESOURCE_ATTRIBUTES |
No | Extra resource attributes; deployment.environment.name=<env> names the environment, otherwise APP_ENVIRONMENT is used. service.name is always eve-backend. |
OTEL_TRACES_SAMPLER / OTEL_TRACES_SAMPLER_ARG |
No | Sampler, e.g. parentbased_traceidratio and 1.0. SDK default parentbased_always_on. |
OTEL_SDK_DISABLED |
No | true turns telemetry off even with an endpoint set. |
OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT |
No | Longest span attribute value (default 4096). |
EVE_OTEL_CAPTURE_CONTENT |
No | Prompts, answers and tool arguments on GenAI spans. true only on dev and local. |
FEATURE_LANGFUSE_SCORES |
No | true posts thumbs feedback to Langfuse as scores on the message trace (thumbs-<message_id>, hallucination-<message_id>). Default false. Needs the three variables below and a message with trace_id. |
LANGFUSE_HOST |
No | Langfuse base URL for POST /api/public/scores, e.g. http://langfuse-web:3000 inside the stack compose. |
LANGFUSE_PUBLIC_KEY / LANGFUSE_SECRET_KEY |
No | Secret. Langfuse project keys, sent as Basic auth. Only used for scores; traces reach Langfuse through the collector. |
API_KEY_MAX_ACTIVE_PER_USER |
No | Max active self-service API keys per user (default 10). 0 disables key creation. |
API_KEY_DEFAULT_EXPIRES_IN_DAYS |
No | Expiry applied when a create request omits it (default 90). |
API_KEY_CREATE_MAX_PER_HOUR |
No | Rolling-hour cap on key creations per user (default 30); 0 disables the throttle. |
FEATURE_BUG_REPORT_RATE_LIMIT |
No | Bug report rate limit (default true). false or 0 lets POST /bug-reports take any number of reports and ignores BUG_REPORT_MAX_PER_HOUR; local compose and dev set it to false. |
BUG_REPORT_MAX_PER_HOUR |
No | Rolling-hour cap on bug reports per user while FEATURE_BUG_REPORT_RATE_LIMIT is on (default 5); 0 or negative means unlimited. |
FREE_TOKENS / FREE_PERIOD_MONTHS |
No | Token budget and period of the free tier, overriding config.yaml. The test gate sets 100 and 1. |
8. Detailed installation commands for prerequisites (optional)
If you prefer copy‑pasteable installation commands, the following sections provide example steps for Python and MongoDB on common platforms. For Docker and Docker Compose, see Docker setup. Always cross‑check with the official documentation for the latest instructions.
Python 3.12+
Ubuntu:
# Update package list
sudo apt update
# Install Python 3.12 and pip
sudo apt install python3.12 python3.12-venv python3-pip
# Verify installation
python3.12 --version
macOS (Homebrew):
- Install Homebrew if you don't have it yet (see brew.sh).
- Install Python:
brew install python@3.12
- Verify installation:
python3 --version
Windows:
- Download Python 3.12+ from the official Python website
- Run the installer and check "Add Python to PATH"
- Verify installation:
python --version
Reference: Python Installation Guide
MongoDB
Ubuntu:
# Import MongoDB public GPG key
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
# Add MongoDB repository
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
# Update package list and install MongoDB
sudo apt update
sudo apt install -y mongodb-org
# Start MongoDB service
sudo systemctl start mongod
sudo systemctl enable mongod
macOS (Homebrew):
# Tap the official MongoDB Homebrew repo
brew tap mongodb/brew
# Install MongoDB Community Edition
brew install mongodb-community@7.0
# Start MongoDB as a background service
brew services start mongodb-community@7.0
Windows:
- Download MongoDB Community Server from the official MongoDB website
- Run the installer and follow the setup wizard
- MongoDB will be installed as a Windows service and start automatically
Reference: - MongoDB Installation Guide - Ubuntu - MongoDB Installation Guide - macOS - MongoDB Installation Guide - Windows