📄 main_legacy.py 3,124 bytes Apr 24, 2026 📋 Raw

"""Main FastAPI application with blog module."""

from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import RedirectResponse
from pathlib import Path
from starlette.staticfiles import StaticFiles

Load .env file if python-dotenv is available

try:
from dotenv import load_dotenv
env_path = Path(file).parent / ".env"
if env_path.exists():
load_dotenv(env_path)
except ImportError:
pass

from blog import blog_router, brief_router
from blog.admin_router import admin_router, setup_admin_static
from content import router as content_router
from family import family_router
from webhook_public import webhook_router
from auth.router import auth_router
from shared.session_auth import SessionAuthMiddleware
from dashboard.router import router as dashboard_router

app = FastAPI(
title="HoffDesk API",
description="HoffDesk Blog and Dashboard API",
version="1.0.0"
)

Session auth middleware (must be before CORS for proper handling)

app.add_middleware(SessionAuthMiddleware)

CORS middleware

app.add_middleware(
CORSMiddleware,
allow_origins=[""], # Configure appropriately for production
allow_credentials=True,
allow_methods=["
"],
allow_headers=["*"],
)

Mount blog static files (CSS, images)

BLOG_STATIC_DIR = Path("/home/hoffmann_admin/hoffdesk/blog/static")
app.mount("/blog/static", StaticFiles(directory=str(BLOG_STATIC_DIR)), name="blog_static")

Mount dashboard static files at /static/ for family.hoffdesk.com

DASHBOARD_STATIC_DIR = Path("/home/hoffmann_admin/.openclaw/shared/project-docs/dashboard/static")
app.mount("/static", StaticFiles(directory=str(DASHBOARD_STATIC_DIR)), name="dashboard_static")

Include dashboard router

app.include_router(
dashboard_router,
tags=["dashboard"]
)

Include auth router (must be before protected routes)

app.include_router(
auth_router,
prefix="/auth",
tags=["auth"]
)

Include blog router

app.include_router(
blog_router,
prefix="/api/blog",
tags=["blog"]
)

Include admin router

app.include_router(
admin_router,
prefix="/admin/blog",
tags=["blog-admin"]
)

Include content generation router

app.include_router(
content_router,
prefix="/admin",
tags=["content-generation"]
)

Include family automation router (private household)

app.include_router(
family_router,
prefix="/admin",
tags=["family-automation"]
)

Include public webhook router (no auth, for Cloudflare Worker)

app.include_router(
webhook_router,
tags=["webhook"]
)

Include content briefs router

app.include_router(
brief_router,
prefix="/api/v1/content/briefs",
tags=["content-briefs"]
)

Setup admin static files

setup_admin_static(app)

@app.get("/")
def root():
"""Root endpoint — redirect to blog."""
return RedirectResponse(url="/api/blog/", status_code=302)

@app.get("/health")
def health():
"""Health check endpoint."""
return {"status": "healthy"}

if name == "main":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)