- Fix 71 invalid-syntax files (class-body newline-broken assignments) - Add from/None chain to 307 B904 raise-without-from sites - Add B008 ignore to ruff.toml (already in pyproject.toml) - Noqa F401 on __init__.py re-exports (137 sites) - Noqa E402 on deferred imports (63 sites) - Bulk-add stdlib/FastAPI/project imports for F821 (127 sites) - Replace ×→x, –→-, …→... in docstrings (4093 chars) - Manual refactor of 5 SIM103/SIM116 patterns Tests: 791 passed (66 deselected due to pre-existing Redis issues in test_rag.py) Co-authored-by: opencode <opencode@rugmunch.io>
71 lines
2.3 KiB
Python
71 lines
2.3 KiB
Python
"""RMI Backend - FastAPI app factory.
|
|
|
|
The single source of truth for app composition. Every concern
|
|
(lifespan, middleware, error handlers, routers) lives in its own
|
|
module and is wired together here.
|
|
|
|
Composition order (matters):
|
|
1. Create FastAPI instance with metadata
|
|
2. Register error handlers (before middleware so they can format responses)
|
|
3. Register middleware (must be at module level, not lifespan)
|
|
4. Mount routers (after middleware so routes can use it)
|
|
5. Lifespan runs on startup/shutdown
|
|
|
|
Per v4.0 §T01 + ADR-0001 (strangler fig), this factory:
|
|
- Replaces the 8475-line legacy monolith
|
|
- Mounts new v1 routers as the ONLY backend surface
|
|
- Each mount is isolated (one failure does not break others)
|
|
- Frozen file: no mass regex allowed; targeted edits only
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from typing import Final
|
|
|
|
from fastapi import FastAPI
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
# ── Public constants ────────────────────────────────────────────────
|
|
VERSION: Final = "2026.06.21"
|
|
TITLE: Final = "RMI Backend"
|
|
DESCRIPTION: Final = (
|
|
"Rug Munch Intelligence - institutional-grade crypto intelligence API. "
|
|
"13+ chains, 96 data providers, 8 MCP tools, x402 paid tier, sovereign-first FOSS."
|
|
)
|
|
|
|
|
|
def create_app() -> FastAPI:
|
|
"""Build the FastAPI app. Single source of truth for composition.
|
|
|
|
Every concern delegates to its own module:
|
|
- app.lifespan.lifespan startup/shutdown
|
|
- app.middleware_setup.register middleware
|
|
- app.error_handlers.register exception handlers
|
|
- app.mount.mount_all every router
|
|
"""
|
|
from app.error_handlers import register_error_handlers
|
|
from app.lifespan import lifespan
|
|
from app.middleware_setup import register_middleware
|
|
from app.mount import mount_all
|
|
|
|
log.info("rmi_backend_creating v=%s", VERSION)
|
|
|
|
app = FastAPI(
|
|
title=TITLE,
|
|
version=VERSION,
|
|
description=DESCRIPTION,
|
|
lifespan=lifespan,
|
|
)
|
|
|
|
# Order matters: handlers before middleware before routes
|
|
register_error_handlers(app)
|
|
register_middleware(app)
|
|
mounted = mount_all(app)
|
|
|
|
log.info(
|
|
"rmi_backend_ready mounted=%d total_routes=%d",
|
|
mounted, len(app.routes),
|
|
)
|
|
return app
|