- Backend: Python 3.12 with FastAPI, SQLAlchemy, boto3 - Frontend: React 18 with TypeScript, Vite build tooling - Updated Dockerfile for multi-stage Node + Python build - Updated CI pipeline for Python backend - Removed old Go code (cmd/, internal/, go.mod, go.sum) - Updated README with new tech stack documentation
55 lines
1.6 KiB
Python
55 lines
1.6 KiB
Python
from fastapi import FastAPI
|
|
from fastapi.staticfiles import StaticFiles
|
|
from fastapi.responses import FileResponse
|
|
from contextlib import asynccontextmanager
|
|
import os
|
|
|
|
from .config import get_settings
|
|
from .database import init_db
|
|
from .routes import router
|
|
|
|
settings = get_settings()
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI):
|
|
# Startup: initialize database
|
|
init_db()
|
|
yield
|
|
# Shutdown: cleanup if needed
|
|
|
|
|
|
app = FastAPI(
|
|
title="Orchard",
|
|
description="Content-Addressable Storage System",
|
|
version="1.0.0",
|
|
lifespan=lifespan,
|
|
)
|
|
|
|
# Include API routes
|
|
app.include_router(router)
|
|
|
|
# Serve static files (React build) if the directory exists
|
|
static_dir = os.path.join(os.path.dirname(__file__), "..", "..", "frontend", "dist")
|
|
if os.path.exists(static_dir):
|
|
app.mount("/assets", StaticFiles(directory=os.path.join(static_dir, "assets")), name="assets")
|
|
|
|
@app.get("/")
|
|
async def serve_spa():
|
|
return FileResponse(os.path.join(static_dir, "index.html"))
|
|
|
|
# Catch-all for SPA routing (must be last)
|
|
@app.get("/{full_path:path}")
|
|
async def serve_spa_routes(full_path: str):
|
|
# Don't catch API routes
|
|
if full_path.startswith("api/") or full_path.startswith("health") or full_path.startswith("grove/"):
|
|
from fastapi import HTTPException
|
|
raise HTTPException(status_code=404, detail="Not found")
|
|
|
|
index_path = os.path.join(static_dir, "index.html")
|
|
if os.path.exists(index_path):
|
|
return FileResponse(index_path)
|
|
|
|
from fastapi import HTTPException
|
|
raise HTTPException(status_code=404, detail="Not found")
|