Skip to content

Technology Stack

Every technology choice in Valter, with versions, purpose, and why it was chosen.

Valter is written in Python >=3.12 (production uses the 3.12-slim Docker image). Python was chosen for three reasons:

  1. ML ecosystem — sentence-transformers, cross-encoders, and NLP libraries for legal text processing are Python-native. There is no viable alternative in other languages for Legal-BERTimbau embeddings.
  2. Async performance — Python 3.12 with asyncio, asyncpg, and uvicorn delivers throughput sufficient for the expected load (single-digit concurrent users during early adoption).
  3. Rich typing — type hints with mypy --strict and Pydantic v2 validation catch errors at development time that would otherwise surface as runtime bugs in legal data processing, where correctness is paramount.

All public functions require type hints. This is enforced by mypy in CI and by convention in CLAUDE.md.

FastAPI >=0.115.0 with Uvicorn >=0.34.0 serves as the HTTP layer.

FastAPI was chosen because it aligns with every architectural constraint in the project:

  • Async-first — every I/O operation in Valter (database queries, vector search, graph traversal, LLM calls) is async/await. FastAPI is built on Starlette’s async foundation.
  • Pydantic v2 integration — request and response validation uses the same Pydantic models that define domain entities, eliminating translation layers.
  • OpenAPI auto-generation — the REST API produces a complete OpenAPI spec from type annotations, which is consumed by external integrators.
  • Depends() DI — FastAPI’s dependency injection system powers the protocol-based architecture. Stores are wired in api/deps.py and injected into route handlers without the core layer knowing about concrete implementations.

Valter uses four specialized databases, each chosen for a specific workload:

StoreVersionRoleData VolumeWhy This Store
PostgreSQL16 (Alpine)Documents, features, STJ metadata, ingestion jobs, workflow state, session memory, API keys, audit logs~23,441 docs, 2,119 features, 810,225 metadata recordsRelational integrity for legal documents, JSONB for flexible metadata, mature async support via asyncpg, Alembic migrations
QdrantlatestSemantic vector search~3,673 vectors (768-dim, cosine similarity)Purpose-built vector database with payload filtering, native cosine similarity, and sub-second query latency for legal embeddings
Neo4j5.x / AuraKnowledge graph (FRBR ontology)~28,482 nodes, ~207,163 edgesNative graph traversal for multi-hop queries (citation chains, divergence detection, community discovery), Cypher query language, managed Aura option for production
Redis7 (Alpine)Cache, rate limiting, job queueEphemeralSub-millisecond latency for query cache (180s TTL), native TTL for rate limiting sliding windows, ARQ integration for background job queues

All production dependencies with their purpose, grouped by function:

PackageVersionPurpose
fastapi>=0.115.0Web framework, routing, DI, OpenAPI generation
uvicorn[standard]>=0.34.0ASGI server with HTTP/1.1 and WebSocket support
httpx>=0.28.0Async HTTP client for bridge calls (MCP remote to API, Railway encoder)
PackageVersionPurpose
pydantic>=2.10.0Domain models, request/response schemas, runtime validation
pydantic-settings>=2.7.0Environment variable parsing into typed settings objects
PackageVersionPurpose
sqlalchemy[asyncio]>=2.0.36Async ORM and query builder for PostgreSQL
asyncpg>=0.30.0High-performance async PostgreSQL driver
alembic>=1.14.0Database migration management
qdrant-client>=1.12.0Qdrant vector database client
neo4j>=5.27.0Neo4j graph database driver (async bolt protocol)
redis>=5.2.0Redis client for cache, rate limiting, and ARQ
PackageVersionPurpose
rank-bm25>=0.2.2BM25 scoring for keyword-based search
sentence-transformers>=3.3.0Legal-BERTimbau embedding model (768-dim) and cross-encoder reranking
PackageVersionPurpose
structlog>=24.4.0Structured JSON logging with trace_id per request
prometheus-client>=0.21.030+ Prometheus metrics (latency, error rates, cache hits)
opentelemetry-api>=1.29.0Distributed tracing API
opentelemetry-sdk>=1.29.0OpenTelemetry SDK for trace export
opentelemetry-instrumentation-fastapi>=0.50b0Auto-instrumentation of FastAPI routes
PackageVersionPurpose
arq>=0.26.1Async job queue backed by Redis (ingestion workflow)
aioboto3>=13.3.0Async S3-compatible client for Cloudflare R2 artifact storage
PackageVersionPurpose
pdfplumber>=0.11.0PDF text extraction for legal documents
pypdf>=5.0.0PDF reading and metadata extraction
PackageVersionPurpose
mcp>=1.3.0Model Context Protocol SDK for stdio and HTTP/SSE transport

Development tools are installed via pip install -e ".[dev]":

PackageVersionPurpose
pytest>=8.0.0Test framework
pytest-asyncio>=0.24.0Async test support (auto mode)
pytest-cov>=6.0.0Coverage reporting
ruff>=0.8.0Linter and formatter (replaces flake8 + isort + black)
mypy>=1.13.0Static type checker

Optional OCR dependencies (for scanned PDF processing):

PackageVersionPurpose
pytesseract>=0.3.13OCR via Tesseract engine
pdf2image>=1.17.0PDF to image conversion for OCR pipeline

Valter integrates with several external services, most of which are optional for local development:

ServicePurposeRequired?Notes
Groq APILLM for document classification, factual extraction, query expansionOptionalEnables AI-powered features (21 fields per decision). Without it, these features are unavailable but the system still works.
Cloudflare R2Artifact storage (PDFs, JSON analysis files)OptionalCanary rollout at 0%. Local filesystem is the default.
RailwayProduction/staging deploymentProduction onlyHosts API, MCP remote, and ARQ worker as separate services.
Neo4j AuraManaged graph databaseStaging/prodLocal Neo4j 5.x for development. PRs touching graph code must pass Aura validation in CI.
HuggingFaceEmbedding model hostingOne-time downloadmake download-model fetches rufimelo/Legal-BERTimbau-sts-base (or the model specified by VALTER_EMBEDDING_MODEL).
ToolPurpose
makeCanonical command interface. All common operations have make targets. Direct commands (pytest, uvicorn) only for debugging.
uv / pipDependency management. uv preferred for speed; pip as fallback.
Docker + docker-composeLocal development stack (PostgreSQL, Qdrant, Redis). Neo4j can run locally or via Aura.
AlembicPostgreSQL schema migrations with upgrade/downgrade support.
GitHub ActionsCI/CD pipeline: make lint + make test + Aura validation for graph-related PRs.
RailwayProduction deployment via railway.json and Dockerfile. Supports multi-service deploy (API, Worker, MCP remote).
HatchlingPython build backend (configured in pyproject.toml).