121 lines
4.3 KiB
Python
121 lines
4.3 KiB
Python
from fastapi import FastAPI, Request, Response
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from fastapi.staticfiles import StaticFiles
|
|
from contextlib import asynccontextmanager
|
|
import time
|
|
import logging
|
|
import json
|
|
import os
|
|
|
|
from database import engine, Base
|
|
from routers import auth, users, projects, episodes, assets, shots, tasks, reviews, files, developer, settings, notifications, activities, admin, data_consistency
|
|
# Import models to ensure they are registered with SQLAlchemy
|
|
import models
|
|
|
|
# # Configure logging
|
|
# logging.basicConfig(
|
|
# level=logging.DEBUG,
|
|
# format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
# )
|
|
# logger = logging.getLogger("vfx_api")
|
|
# # logger = logging.getLogger("uvicorn")
|
|
# logger.setLevel(logging.DEBUG)
|
|
|
|
# # Also set the auth logger to debug
|
|
# auth_logger = logging.getLogger("vfx_auth")
|
|
# auth_logger.setLevel(logging.DEBUG)
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI):
|
|
# Create database tables
|
|
Base.metadata.create_all(bind=engine)
|
|
yield
|
|
|
|
|
|
app = FastAPI(
|
|
title="LinkDesk API",
|
|
description="A comprehensive project management system for animation and VFX production",
|
|
version="1.0.0",
|
|
lifespan=lifespan
|
|
)
|
|
|
|
# Configure CORS
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=["http://localhost:5173", "http://localhost:5174"], # Vue.js dev server
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
# Add logging middleware
|
|
# @app.middleware("http")
|
|
# async def log_requests(request: Request, call_next):
|
|
# """Log all HTTP requests and responses."""
|
|
|
|
# start_time = time.time()
|
|
# # Log request
|
|
# client_ip = request.client.host if request.client else "unknown"
|
|
# auth_header = request.headers.get("authorization", "none")
|
|
|
|
# # Mask the token for security
|
|
# if auth_header and auth_header.startswith("Bearer "):
|
|
# auth_display = f"Bearer {auth_header[7:15]}..."
|
|
# else:
|
|
# auth_display = auth_header
|
|
|
|
# log_message = f"🔵 {request.method} {request.url.path} from {client_ip} | Auth: {auth_display}"
|
|
# logger.info(log_message)
|
|
# print(log_message) # Also print to console for debugging
|
|
|
|
# # Process the request
|
|
# try:
|
|
# response = await call_next(request)
|
|
# process_time = time.time() - start_time
|
|
|
|
# # Log response
|
|
# status_emoji = "🟢" if response.status_code < 400 else "🔴" if response.status_code >= 500 else "🟡"
|
|
# response_message = f"{status_emoji} {response.status_code} - {process_time:.3f}s"
|
|
# logger.info(response_message)
|
|
# print(response_message) # Also print to console for debugging
|
|
|
|
# return response
|
|
|
|
# except Exception as e:
|
|
# process_time = time.time() - start_time
|
|
# logger.error(f"🔴 ERROR: {str(e)} - {process_time:.3f}s")
|
|
# raise
|
|
|
|
# Mount static files for uploads
|
|
uploads_dir = os.path.join(os.path.dirname(__file__), "uploads")
|
|
if not os.path.exists(uploads_dir):
|
|
os.makedirs(uploads_dir)
|
|
app.mount("/uploads", StaticFiles(directory=uploads_dir), name="uploads")
|
|
|
|
# Include routers
|
|
app.include_router(auth.router, prefix="/auth", tags=["authentication"])
|
|
app.include_router(users.router, prefix="/users", tags=["users"])
|
|
app.include_router(projects.router, prefix="/projects", tags=["projects"])
|
|
app.include_router(episodes.router, prefix="/episodes", tags=["episodes"])
|
|
app.include_router(assets.router, prefix="/assets", tags=["assets"])
|
|
app.include_router(shots.router, prefix="/shots", tags=["shots"])
|
|
app.include_router(tasks.router, prefix="/tasks", tags=["tasks"])
|
|
app.include_router(reviews.router, prefix="/reviews", tags=["reviews"])
|
|
app.include_router(files.router, prefix="/files", tags=["files"])
|
|
app.include_router(developer.router, prefix="/developer", tags=["developer"])
|
|
app.include_router(settings.router, prefix="/settings", tags=["settings"])
|
|
app.include_router(notifications.router, tags=["notifications"])
|
|
app.include_router(activities.router, tags=["activities"])
|
|
app.include_router(admin.router, prefix="/admin", tags=["admin"])
|
|
app.include_router(data_consistency.router, prefix="/data-consistency", tags=["data-consistency"])
|
|
|
|
|
|
@app.get("/")
|
|
async def root():
|
|
return {"message": "VFX Project Management System API"}
|
|
|
|
|
|
@app.get("/health")
|
|
async def health_check():
|
|
return {"status": "healthy"} |