Files
resumeformatter/backend/app/main.py
2025-10-14 19:51:35 +05:30

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)