Refactored frontend + added template engine

This commit is contained in:
Christian Krakau-Louis
2025-03-26 02:17:05 +01:00
parent c4634a984f
commit d95f5babb8
15 changed files with 335 additions and 528 deletions
-1
View File
@@ -1,5 +1,4 @@
# app/auth.py
# app/auth.py
import os
from functools import wraps
+19 -28
View File
@@ -1,39 +1,30 @@
# app/frontend.py (new file or inline in main.py)
from fastapi import APIRouter, Request, status
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from app.auth import require_login
# app/frontend.py
import os
from pathlib import Path
from fastapi import APIRouter, Request
from fastapi.templating import Jinja2Templates
from app.auth import require_login
router = APIRouter()
# 1) Serve the folder that contains index.html, etc.
# e.g. "frontend" is relative to your project root
frontend_folder = os.path.join(os.path.dirname(__file__), "..", "frontend")
# Point templates_dir to "frontend/templates"
templates_dir = Path(__file__).parent.parent / "frontend" / "templates"
templates = Jinja2Templates(directory=str(templates_dir))
# If you just want to serve the entire folder as static:
router.mount("/static", StaticFiles(directory=frontend_folder), name="static")
@router.get("/", include_in_schema=False)
async def serve_index(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
# 2) For the root route ("/"), return the index.html
@router.get("/about", include_in_schema=False)
async def serve_about(request: Request):
return templates.TemplateResponse("about.html", {"request": request})
@router.get("/upload", response_class=FileResponse)
@router.get("/upload", include_in_schema=False)
@require_login
async def serve_upload(request: Request):
return os.path.join(frontend_folder, "upload.html")
return templates.TemplateResponse("upload.html", {"request": request})
# 3) Serve favicon.ico from the frontend folder
@router.get("/favicon.ico", response_class=FileResponse)
@router.get("/favicon.ico", include_in_schema=False)
def favicon():
return os.path.join(frontend_folder, "favicon.ico")
""" @router.exception_handler(404)
async def custom_404_handler(request: Request, exc):
return FileResponse("frontend/404.html", status_code=status.HTTP_404_NOT_FOUND) """
@router.get("/", response_class=FileResponse)
async def serve_index(request: Request):
return os.path.join(frontend_folder, "index.html")
@router.get("/about", response_class=FileResponse)
async def serve_about(request: Request):
return os.path.join(frontend_folder, "about.html")
# If you have a real favicon in `frontend/static/favicon.ico`, you could do:
return str(Path(__file__).parent.parent / "frontend" / "static" / "favicon.ico")
+15 -9
View File
@@ -3,10 +3,14 @@ import os
from fastapi import FastAPI, HTTPException, UploadFile, File, status, Request
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from starlette.middleware.sessions import SessionMiddleware
from starlette.config import Config
from starlette.middleware.trustedhost import TrustedHostMiddleware
from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware
from pathlib import Path
from app.database import init_db
from app.config import settings
from app.tasks.upload_to_s3 import upload_to_s3
@@ -14,13 +18,11 @@ from app.tasks.upload_to_dropbox import upload_to_dropbox
from app.tasks.upload_to_paperless import upload_to_paperless
from app.tasks.upload_to_nextcloud import upload_to_nextcloud
from app.tasks.send_to_all import send_to_all_destinations
from pathlib import Path
from app.api import router as api_router
from app.frontend import router as frontend_router
from app.auth import router as auth_router
# Load configuration from .env for the session key
config = Config(".env")
SESSION_SECRET = config(
@@ -30,12 +32,10 @@ SESSION_SECRET = config(
app = FastAPI(title="Document Processing API")
# 1) Session Middleware (for request.session to work)
app.add_middleware(SessionMiddleware, secret_key=SESSION_SECRET)
# 2) Respect the X-Forwarded-* headers from Traefik
# so your request.url_for(...) uses https://docparse.hosterra.net
app.add_middleware(ProxyHeadersMiddleware, trusted_hosts="*")
# 3) (Optional but recommended) Restrict valid hosts:
@@ -45,12 +45,14 @@ app.add_middleware(TrustedHostMiddleware, allowed_hosts=[
"127.0.0.1"
])
# Mount the static folder for CSS/JS:
frontend_static_dir = Path(__file__).parent.parent / "frontend" / "static"
app.mount("/static", StaticFiles(directory=frontend_static_dir), name="static")
@app.on_event("startup")
def on_startup():
init_db() # Create tables if they don't exist
@app.post("/process/")
def process(file_path: str):
"""
@@ -166,10 +168,15 @@ async def ui_upload(file: UploadFile = File(...)):
task = upload_to_s3.delay(target_path)
return {"task_id": task.id, "status": "queued"}
# Custom 404 - we can still return the Jinja2 template, or the old static file:
# For a dynamic 404 using the base layout, see "frontend/404.html" usage below:
@app.exception_handler(404)
async def custom_404_handler(request: Request, exc: HTTPException):
return FileResponse(
"/app/frontend/404.html",
# Serve the 404 template directly
templates = Jinja2Templates(directory=str(frontend_static_dir.parent / "templates"))
return templates.TemplateResponse(
"404.html",
{"request": request},
status_code=status.HTTP_404_NOT_FOUND
)
@@ -177,4 +184,3 @@ async def custom_404_handler(request: Request, exc: HTTPException):
app.include_router(frontend_router)
app.include_router(auth_router)
app.include_router(api_router, prefix="/api")