import sqlite3 from contextlib import asynccontextmanager from pathlib import Path from urllib.parse import urlsplit from fastapi import FastAPI, Request from fastapi.responses import HTMLResponse from fastapi.staticfiles import StaticFiles from database import initialize from routes import dashboard, income, export @asynccontextmanager async def lifespan(app): initialize() yield app = FastAPI(title='Finance Dashboard', lifespan=lifespan) app.mount('/static', StaticFiles(directory=Path(__file__).parent / 'static'), name='static') app.include_router(dashboard.router) app.include_router(income.router) app.include_router(export.router) @app.middleware('http') async def protect_forms(request: Request, call_next): if request.method == 'POST': origin = request.headers.get('origin') if request.headers.get('sec-fetch-site') == 'cross-site' or (origin and urlsplit(origin).netloc != request.headers.get('host')): return HTMLResponse('Fremder Formularursprung ist nicht erlaubt.', status_code=403) return await call_next(request) @app.exception_handler(sqlite3.OperationalError) async def database_error(request, error): return HTMLResponse('
Bitte in einigen Sekunden erneut versuchen.
Zum Dashboard', status_code=503, headers={'Retry-After': '5'}) @app.get('/health') def health(): return {'status': 'ok'}