196 lines
6.8 KiB
Python
196 lines
6.8 KiB
Python
from fastapi import FastAPI, Request
|
|
from fastapi.staticfiles import StaticFiles
|
|
from fastapi.responses import FileResponse, HTMLResponse, RedirectResponse
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
import os
|
|
import pathlib
|
|
from dotenv import load_dotenv
|
|
|
|
from app.api.api import api_router
|
|
from app.core.config import settings
|
|
from app.db.session import engine
|
|
from app.db.base import Base
|
|
|
|
# Load environment variables
|
|
load_dotenv()
|
|
|
|
# Create tables in the database
|
|
Base.metadata.create_all(bind=engine)
|
|
|
|
app = FastAPI(
|
|
title=settings.PROJECT_NAME,
|
|
openapi_url=f"{settings.API_V1_STR}/openapi.json",
|
|
docs_url=f"{settings.API_V1_STR}/docs",
|
|
redoc_url=f"{settings.API_V1_STR}/redoc"
|
|
)
|
|
|
|
# Set up CORS
|
|
if settings.BACKEND_CORS_ORIGINS:
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS],
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
# Include API router
|
|
app.include_router(api_router, prefix=settings.API_V1_STR)
|
|
|
|
# Check if dist directory exists - use absolute path
|
|
dist_path = pathlib.Path("/app/dist")
|
|
if dist_path.exists():
|
|
# Mount static files from the dist directory if it exists
|
|
assets_path = dist_path / "assets"
|
|
if assets_path.exists():
|
|
# Mount assets with APP_NAME prefix
|
|
app.mount(f"/{settings.APP_NAME}/assets", StaticFiles(directory=str(assets_path)), name="assets")
|
|
print(f"Successfully mounted assets from {assets_path} at /{settings.APP_NAME}/assets")
|
|
else:
|
|
print(f"Warning: Dist directory {dist_path} does not exist")
|
|
# Try local development path with frontend folder
|
|
local_dist_path = pathlib.Path("frontend/dist")
|
|
if local_dist_path.exists():
|
|
local_assets_path = local_dist_path / "assets"
|
|
if local_assets_path.exists():
|
|
# Mount assets with APP_NAME prefix
|
|
app.mount(f"/{settings.APP_NAME}/assets", StaticFiles(directory=str(local_assets_path)), name="assets")
|
|
print(f"Successfully mounted assets from {local_assets_path} at /{settings.APP_NAME}/assets")
|
|
|
|
|
|
@app.get("/api/health")
|
|
async def health_check():
|
|
return {"status": "ok"}
|
|
|
|
|
|
# Redirect root to APP_NAME
|
|
@app.get("/")
|
|
async def redirect_to_app():
|
|
return RedirectResponse(f"/{settings.APP_NAME}")
|
|
|
|
|
|
# Handle index.css request
|
|
@app.get("/index.css")
|
|
async def serve_css():
|
|
# Try to serve from /app/dist (container path)
|
|
css_path = pathlib.Path("/app/dist/index.css")
|
|
if css_path.exists():
|
|
return FileResponse(css_path)
|
|
|
|
# Try to serve from frontend/dist (local development path)
|
|
local_css_path = pathlib.Path("frontend/dist/index.css")
|
|
if local_css_path.exists():
|
|
return FileResponse(local_css_path)
|
|
|
|
return {"error": "CSS file not found"}
|
|
|
|
|
|
# Handle vite.svg request
|
|
@app.get("/vite.svg")
|
|
async def serve_favicon():
|
|
# Try to serve from /app/dist (container path)
|
|
favicon_path = pathlib.Path("/app/dist/vite.svg")
|
|
if favicon_path.exists():
|
|
return FileResponse(favicon_path)
|
|
|
|
# Try to serve from frontend/dist (local development path)
|
|
local_favicon_path = pathlib.Path("frontend/dist/vite.svg")
|
|
if local_favicon_path.exists():
|
|
return FileResponse(local_favicon_path)
|
|
|
|
return {"error": "Favicon not found"}
|
|
|
|
|
|
# Serve index.html for the APP_NAME route
|
|
@app.get("/{app_name}")
|
|
async def serve_app(app_name: str):
|
|
if app_name != settings.APP_NAME:
|
|
return {"error": "App not found"}
|
|
|
|
# Try to serve from /app/dist (container path)
|
|
index_path = pathlib.Path("/app/dist/index.html")
|
|
if index_path.exists():
|
|
return FileResponse(index_path)
|
|
|
|
# Try to serve from frontend/dist (local development path)
|
|
local_index_path = pathlib.Path("frontend/dist/index.html")
|
|
if local_index_path.exists():
|
|
return FileResponse(local_index_path)
|
|
|
|
# If neither exists, return a simple HTML response
|
|
html_content = """
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Profile Linker API</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; margin: 40px; line-height: 1.6; }
|
|
h1 { color: #333; }
|
|
.container { max-width: 800px; margin: 0 auto; }
|
|
.message { background-color: #f8f9fa; border-left: 4px solid #007bff; padding: 15px; }
|
|
code { background-color: #f1f1f1; padding: 2px 5px; border-radius: 3px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h1>FastAPI Server Running</h1>
|
|
<div class="message">
|
|
<p>The FastAPI server is running correctly, but the frontend build files are not available.</p>
|
|
<p>To see the frontend, make sure to build it first with <code>npm run build</code>.</p>
|
|
<p>API endpoints are available at <a href="/docs">/docs</a>.</p>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
"""
|
|
return HTMLResponse(content=html_content, status_code=200)
|
|
|
|
|
|
# Serve index.html for all other routes to support SPA routing
|
|
@app.get("/{app_name}/{full_path:path}")
|
|
async def serve_spa(app_name: str, full_path: str):
|
|
if app_name != settings.APP_NAME:
|
|
return {"error": "App not found"}
|
|
|
|
# Check if the path is an API route
|
|
if full_path.startswith("api/"):
|
|
return {"error": "API route not found"}
|
|
|
|
# Try to serve from /app/dist (container path)
|
|
index_path = pathlib.Path("/app/dist/index.html")
|
|
if index_path.exists():
|
|
return FileResponse(index_path)
|
|
|
|
# Try to serve from frontend/dist (local development path)
|
|
local_index_path = pathlib.Path("frontend/dist/index.html")
|
|
if local_index_path.exists():
|
|
return FileResponse(local_index_path)
|
|
|
|
# If neither exists, return a simple HTML response
|
|
html_content = """
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Profile Linker API</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; margin: 40px; line-height: 1.6; }
|
|
h1 { color: #333; }
|
|
.container { max-width: 800px; margin: 0 auto; }
|
|
.message { background-color: #f8f9fa; border-left: 4px solid #007bff; padding: 15px; }
|
|
code { background-color: #f1f1f1; padding: 2px 5px; border-radius: 3px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<h1>FastAPI Server Running</h1>
|
|
<div class="message">
|
|
<p>The FastAPI server is running correctly, but the frontend build files are not available.</p>
|
|
<p>To see the frontend, make sure to build it first with <code>npm run build</code>.</p>
|
|
<p>API endpoints are available at <a href="/docs">/docs</a>.</p>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
"""
|
|
return HTMLResponse(content=html_content, status_code=200)
|