Skip to content

Dependencies

This document describes every Python dependency of the underwrite platform, where it is used in the codebase, and considerations when upgrading.


Core Dependencies

These are declared in [project.dependencies] of pyproject.toml and are always installed.

cryptography >=41.0

Detail Description
Purpose Ed25519 asymmetric key management, event signing, and signature verification.
Modules underwrite/identity.pyIdentity.create(), Identity.sign(), Identity.verify(), Identity.persist(); underwrite/authz.pyAccessControl.verify_signature()
Upgrade considerations Ed25519 API is stable across 41.x–43.x. The cryptography.hazmat.primitives.asymmetric.ed25519 module is used directly (not SigningKey from nacl). If upgrading past 43.x, check for deprecation of BestAvailableEncryption and serialization helpers.

typer >=0.12

Detail Description
Purpose CLI framework for the underwrite command-line tool.
Modules underwrite/cli.py — all CLI commands (init, run, list, identity, health, dlq, metrics, serve, migrate)
Upgrade considerations typer 0.12+ uses Click 8.x internally. Breaking changes are rare. If upgrading to typer 0.15+, verify that no_args_is_help still works and typer.Argument(...) with metavar renders correctly.

pydantic >=2.0

Detail Description
Purpose Configuration schema validation and serialisation.
Modules underwrite/config.py — all config classes (Configuration, BusConfig, StoreConfig, IdentityConfig, etc.) use BaseModel with Field, field_validator, and model_config = {"extra": "forbid"}.
Upgrade considerations pydantic v2 is required. v1 style (BaseSettings, validator) is not used. If upgrading to pydantic v3, watch for changes to model_copy(), model_dump(), and field_validator signature. The codebase uses model_copy(update=...) in Configuration.__merge which is v2-specific.

Optional Dependencies

Each group is declared in [project.optional-dependencies] and must be installed separately.

dev (development)

Dependency Version Used In Purpose
pytest >=7.4 tests/ Test framework. Configured in [tool.pytest.ini_options] with asyncio_mode = "auto".
pytest-cov >=5.0 tests/ (via tox.ini/Makefile) Coverage reporting.
hypothesis >=6.0 tests/ Property-based testing for state-machine invariants.
ruff >=0.6 Project-wide Linter and formatter. Configured in [tool.ruff] with select = ["E", "F", "I", "UP", "B"].
mypy >=1.10 Project-wide Static type checking. Configured in [tool.mypy] with ignore_missing_imports = true.
bandit >=1.7 Security scanning Also part of security extra. Configured in [tool.bandit].
pip-audit >=2.7 Security scanning Also part of security extra.
httpx >=0.27 Tests for serve Async HTTP client for testing FastAPI endpoints.

Upgrade considerations: ruff 0.6+ may introduce new lint rules; pin or update select accordingly. mypy 1.10+ is compatible with Python 3.10–3.13.

risk (risk scoring)

Dependency Version Used In Purpose
numpy >=1.26 underwrite/services/risk/model.py (transitive via sklearn) Numerical operations in risk model.
scikit-learn >=1.5 underwrite/services/risk/model.py ML model loading (joblib) and prediction via JoblibModelStrategy.

Upgrade considerations: scikit-learn 1.5+ drops Python 3.9 support (already satisfied). Joblib model serialization format is backward-compatible within the 1.x line. The JoblibModelStrategy requires UNDERWRITE_ALLOW_JOBLIB=true to activate joblib loading (see identity.py line 234–248 for the gating logic).

store (SQLite)

The store layer depends only on the Python standard library (sqlite3). No third-party database driver is required — the SQLite store uses BEGIN IMMEDIATE transactions and WAL journaling, with a configurable busy_timeout (default 30 s).

serve (HTTP gateway)

Dependency Version Used In Purpose
uvicorn[standard] >=0.24 underwrite/cli.py (serve command) ASGI server for the FastAPI app.
fastapi >=0.104 underwrite/serve.py HTTP API framework providing /v1/health, /v1/metrics, /v1/publish endpoints.

Upgrade considerations: FastAPI 0.104+ uses Pydantic v2 exclusively. The @app.on_event("startup")/("shutdown") decorators used in serve.py are deprecated in FastAPI 0.110+ in favour of the lifespan pattern (@asynccontextmanager). A migration would replace on_event with lifespan.

otlp (OpenTelemetry)

Dependency Version Used In Purpose
opentelemetry-api >=1.20 underwrite/tracer.py OTLP span exporter (OtlpSpanExporter).
opentelemetry-sdk >=1.20 underwrite/tracer.py SDK tracer provider, batch span processor.
opentelemetry-exporter-otlp-proto-grpc >=1.20 underwrite/tracer.py gRPC OTLP exporter.
opentelemetry-instrumentation-fastapi >=0.41b0 underwrite/serve.py Auto-instrumentation of FastAPI routes via FastAPIInstrumentor.

Upgrade considerations: The OTel Python SDK 1.20+ is stable. The FastAPIInstrumentor is in beta (0.41b0). When upgrading, verify that BatchSpanProcessor.force_flush() is still the recommended shutdown pattern. The Resource.create() call in _lazy_init() is the standard approach for service naming.

vault (HashiCorp Vault)

Dependency Version Used In Purpose
hvac >=2.0 underwrite/secrets.py (VaultSecretsBackend) KV v2 secret read/write against Vault.

Upgrade considerations: hvac 2.x API is stable. The code uses secrets.kv.v2.read_secret_version() and secrets.kv.v2.create_or_update_secret(). If upgrading to hvac 3.x, check for any changes to the KV v2 path resolution.

aws (AWS Secrets Manager)

Dependency Version Used In Purpose
boto3 >=1.33 underwrite/secrets.py (AwsSecretsBackend); underwrite/services/audit.py (__export_s3) AWS Secrets Manager read/write; S3 audit export.

Upgrade considerations: boto3 1.33+ follows the AWS SDK for Python (v3). The get_secret_value() and put_secret_value() APIs are stable. The S3 put_object API used in audit export is unchanged.

gcs (Google Cloud Storage)

Dependency Version Used In Purpose
google-cloud-storage >=2.10 underwrite/services/audit.py (__export_gcs) GCS audit export.

Upgrade considerations: The storage.Client() and bucket().blob().upload_from_string() API is stable across 2.x. Authentication follows Google's GOOGLE_APPLICATION_CREDENTIALS env var.