fire-planner/pyproject.toml
Viktor Barzin ee6ed1d3c4
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
api: expand FastAPI surface for scenarios, networth, life-events, goals, simulate
Adds the read+write endpoints the frontend needs to drive a
ProjectionLab-style UX on top of the existing engine.

- /networth, /networth/history    — NW total + per-account from
                                     account_snapshot (frontend chart)
- /scenarios CRUD + projection    — list/get/create/patch/delete user
                                     scenarios; cartesian read-only
- /scenarios/{id}/life-events     — life event CRUD nested under scenario
- /life-events/{id}               — patch + delete by id
- /scenarios/{id}/goals,
  /goals/{id}                     — retirement goal CRUD
- /simulate, /compare             — sync, no-DB-write what-if endpoints

Auth: Bearer-token dependency on writes + simulate when API_BEARER_TOKEN
is set; reads always open (lock down via Authentik-fronted ingress in
prod). Existing /recompute keeps its bearer auth.

CORS middleware reads FRONTEND_ORIGINS (comma-separated) for the dev
SPA. Lifespan now provisions the SQLAlchemy engine + session_factory
on app.state and disposes them on shutdown.

40 new tests covering happy paths and validation. 172 tests total.
mypy strict + ruff clean (B008 ignore added — Depends() in defaults
is the canonical FastAPI pattern, not a bug).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 21:48:36 +00:00

64 lines
1.6 KiB
TOML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[tool.poetry]
name = "fire-planner"
version = "0.1.0"
description = "Risk-adjusted, tax-minimised FIRE retirement planner — Monte Carlo simulator over jurisdictions, withdrawal strategies, and UK-departure years."
authors = ["Viktor Barzin <viktorbarzin@meta.com>"]
readme = "README.md"
packages = [{ include = "fire_planner" }]
[tool.poetry.dependencies]
python = ">=3.12,<3.13"
fastapi = "^0.115"
uvicorn = "^0.32"
httpx = "^0.27"
pydantic = "^2.9"
sqlalchemy = { extras = ["asyncio"], version = "^2.0" }
asyncpg = "^0.29"
alembic = "^1.13"
click = "^8.1"
numpy = "^2.1"
pandas = "^2.2"
prometheus-fastapi-instrumentator = "^7.0"
[tool.poetry.group.dev.dependencies]
pytest = "^8.3"
pytest-asyncio = "^0.23"
hypothesis = "^6.115"
mypy = "^1.11"
ruff = "^0.6"
yapf = "^0.43"
respx = "^0.21"
aiosqlite = "^0.20"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests"]
[tool.mypy]
python_version = "3.12"
strict = true
files = ["fire_planner", "tests"]
[[tool.mypy.overrides]]
module = ["respx.*", "pandas.*"]
ignore_missing_imports = true
[tool.ruff]
line-length = 100
target-version = "py312"
[tool.ruff.lint]
select = ["E", "F", "W", "I", "UP", "B", "SIM", "RUF"]
# RUF002 / RUF003 flag ambiguous unicode characters (×, —, etc.) in
# docstrings and comments — we use them intentionally for readability.
# B008 trips on `Depends(...)` in argument defaults — that's the
# idiomatic FastAPI pattern, not a bug.
ignore = ["RUF002", "RUF003", "B008"]
[tool.yapf]
based_on_style = "pep8"
column_limit = 100