Files
Mist/backend/src/mist/api/app.py
T
goddard bfd6771a9a
admin-web / build (push) Successful in 22s
backend / test (push) Failing after 52s
mistpipe / test (push) Successful in 10s
admin-web / build-and-push (push) Failing after 5s
backend / build-and-push (push) Has been skipped
Initial Mist scaffold
Successor to the Josh Steam prototypes. Single-VM Docker Compose stack with
the load-bearing core/ logic ported from JoshSteam CDN with bug fixes.

Contents:
- backend/  FastAPI + Celery (same image, two entrypoints)
            core/  hdiff, librsync, chain_replay, manifest, compression,
                   discord, steam, unrealpak, paths
            api/   auth, catalog, admin, builds (skeletons) + downloads (real)
            worker/  Celery factory replacing the missing prototype Tasks/__init__.py
            db/    SQLAlchemy models + Alembic initial migration
- admin-web/  SvelteKit + Tailwind skeleton
- client/    Tauri 2 + Svelte skeleton (Mist placeholder UI)
- mistpipe/  click-based admin CLI with subcommand stubs
- docs/      ARCHITECTURE, DECISIONS (9 ADRs), RUNBOOK
- docker-compose.yml + dev overlay + .github/workflows

Bugs fixed during port:
- Routes/download.py:2 stray backslash on import line
- Utils/celery.py inspect.reserved() missing parens + double active() typo
- Hardcoded OneDrive/Desktop paths replaced with pydantic-settings config
- Discord webhook URL + RabbitMQ password moved to env vars
- Missing Tasks/__init__.py reconstructed as worker/__init__.py

Out of scope for this commit: route bodies, UI screens, mistpipe subcommand
bodies, real image builds.
2026-06-07 19:39:25 -04:00

61 lines
1.7 KiB
Python

"""FastAPI app factory.
Run with: `uvicorn mist.api.app:app --host 0.0.0.0 --port 8000`
"""
from __future__ import annotations
import logging
from contextlib import asynccontextmanager
from collections.abc import AsyncIterator
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from mist.api import admin, auth, builds, catalog, downloads
from mist.config import settings
from mist.core import paths as core_paths
log = logging.getLogger(__name__)
@asynccontextmanager
async def lifespan(_: FastAPI) -> AsyncIterator[None]:
logging.basicConfig(level=settings.log_level)
log.info("Mist API starting; environment=%s", settings.environment)
core_paths.ensure_dirs()
yield
log.info("Mist API stopping")
def create_app() -> FastAPI:
app = FastAPI(title="Mist API", version="0.1.0", lifespan=lifespan)
app.add_middleware(
CORSMiddleware,
allow_origins=settings.cors_origins or ["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(auth.router, prefix="/auth", tags=["auth"])
app.include_router(catalog.router, prefix="/catalog", tags=["catalog"])
app.include_router(admin.router, prefix="/admin", tags=["admin"])
app.include_router(builds.router, prefix="/builds", tags=["builds"])
app.include_router(downloads.router, prefix="/download", tags=["downloads"])
@app.get("/healthz", tags=["health"])
def healthz() -> dict[str, bool]:
return {"ok": True}
@app.get("/readyz", tags=["health"])
def readyz() -> dict[str, bool]:
# TODO: actually check db / redis / rabbitmq reachability
return {"ok": True}
return app
app = create_app()