Skip to content

Settings & Configuration Files

Valter centralizes all configuration in a single Pydantic Settings class that loads values from environment variables and .env files. This page explains the configuration architecture, runtime modes, feature flags, and the project’s configuration files.

The Settings class in src/valter/config.py extends pydantic_settings.BaseSettings and serves as the single source of truth for all application configuration. It uses the VALTER_ prefix for environment variable resolution.

from pydantic_settings import BaseSettings
class Settings(BaseSettings):
ENV: str = "development"
DATABASE_URL: str = "postgresql+asyncpg://valter:valter_dev@localhost:5432/valter"
# ... 50+ fields with sensible defaults
model_config = {
"env_prefix": "VALTER_",
"env_file": ".env",
}

Values are resolved in this order (first match wins):

  1. Shell environment variables — highest priority, always override
  2. .env file — convenient for local development
  3. Field defaults — defined in the Settings class itself

A singleton instance is created at module level:

settings = Settings()

This instance is imported wherever configuration is needed and injected via FastAPI’s Depends() where appropriate.

The Settings class includes a @model_validator that runs after all fields are loaded. When VALTER_ENV is production or prod, it validates security-critical constraints and raises a ValueError at startup if any are violated. See Environment Variables > Production Guardrails for the full list.

Several configuration values are derived from raw settings via @property methods:

PropertyComputation
max_upload_bytesMAX_UPLOAD_MB * 1024 * 1024
is_productionENV.strip().lower() in {"production", "prod"}
r2_endpoint_urlUses R2_ENDPOINT_URL if set, otherwise constructs from R2_ACCOUNT_ID
r2_canary_percentClamps R2_CANARY_PERCENT to 0-100 range
arq_redis_urlReplaces the DB number in REDIS_URL with ARQ_REDIS_DB
metrics_ip_allowlistParses comma-separated string into a list[str]

The VALTER_RUNTIME variable determines which process starts. The routing logic lives in scripts/start-command.sh, which is the container entrypoint.

ModeValueProcessPort
REST APIapiuvicorn valter.main:app8000
Background workerworkerpython -m valter.workersN/A
MCP remote servermcp-remotepython -m valter.mcp.remote_server8001
MCP stdio servermcp-stdiopython -m valter.mcp.remote_server (stdio transport)N/A

Each mode initializes different components. The API mode starts FastAPI with middleware, routes, and database connections. The worker mode starts the ARQ job processor for background ingest tasks. The MCP modes start a Model Context Protocol server that bridges LLM tool calls to the REST API.

For local development, you typically start each mode separately:

Terminal window
make dev # Starts API mode on port 8000
make worker-ingest # Starts ARQ worker
make mcp-remote # Starts MCP HTTP server on port 8001

In Railway deployments, each mode runs as a separate service with VALTER_RUNTIME set in the service environment.

Several boolean or numeric variables act as feature flags, enabling functionality that is off by default:

FlagDefaultWhat it enables
VALTER_GROQ_ENABLEDfalseGroq LLM features: factual extraction (POST /v1/factual/extract), query expansion in hybrid search. Requires VALTER_GROQ_API_KEY.
VALTER_AUTH_ENABLEDfalseAPI key authentication on REST endpoints. Must be true in production.
VALTER_KG_BOOST_BATCH_ENABLEDtrueBatch knowledge graph boosting in the hybrid retriever. Enriches vector search results with graph context from Neo4j.
VALTER_R2_CANARY_PERCENT0Percentage of artifact uploads routed to Cloudflare R2. At 0, all artifacts are stored locally. Increase for gradual R2 migration.
VALTER_WORKFLOW_STRICT_INFRA_REQUIREDtrueWhen true, workflows fail immediately if required infrastructure is unavailable. When false, they degrade gracefully.

Beyond environment variables, Valter uses several configuration files:

FilePurpose
pyproject.tomlProject metadata, dependencies, and tool configuration (ruff, pytest, mypy, hatch)
docker-compose.ymlLocal development database stack (PostgreSQL 16, Qdrant, Redis 7)
DockerfileProduction container image
railway.jsonRailway.app deployment configuration
MakefileCanonical command interface for all development and operational tasks
.envLocal environment variable overrides (gitignored)
migrations/alembic.iniAlembic database migration configuration

For local development, create a .env file at the project root. Most variables have sensible defaults that work with the docker-compose.yml stack, so only a minimal .env is needed:

Terminal window
# .env (local development)
# These defaults work with docker-compose.yml — only override what you need.
# Optional: enable Groq LLM features
# VALTER_GROQ_API_KEY=gsk_your_key_here
# VALTER_GROQ_ENABLED=true
# Optional: Neo4j Aura for graph features
# VALTER_NEO4J_URI=neo4j+s://xxxxx.databases.neo4j.io
# VALTER_NEO4J_USERNAME=neo4j
# VALTER_NEO4J_PASSWORD=your_aura_password
# Optional: remote embedding service (skips local model download)
# VALTER_EMBEDDING_SERVICE_URL=https://your-railway-service.up.railway.app