allow all origins for cors

This commit is contained in:
Automated Action 2025-05-31 14:19:00 +00:00
parent 8db0013f26
commit 6a5649a49c
3 changed files with 299 additions and 60 deletions

View File

@ -1,16 +1,38 @@
import os
from pathlib import Path from pathlib import Path
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
# Get the project root directory # Get the project root directory (using an absolute path)
PROJECT_ROOT = Path(__file__).parent.parent.parent.absolute() PROJECT_ROOT = Path(__file__).parent.parent.parent.absolute()
# Create the directory for the SQLite database if it doesn't exist try:
DB_DIR = PROJECT_ROOT / "app" / "storage" / "db" # Create the directory for the SQLite database if it doesn't exist
DB_DIR.mkdir(parents=True, exist_ok=True) DB_DIR = PROJECT_ROOT / "app" / "storage" / "db"
DB_DIR.mkdir(parents=True, exist_ok=True)
SQLALCHEMY_DATABASE_URL = f"sqlite:///{DB_DIR}/db.sqlite"
# Ensure the directory is writable
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}) test_file = DB_DIR / ".test_write_access"
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) with open(test_file, "w") as f:
f.write("test")
os.remove(test_file)
# Use a simplified database path for better compatibility
DB_FILE = DB_DIR / "db.sqlite"
SQLALCHEMY_DATABASE_URL = f"sqlite:///{DB_FILE}"
print(f"Database URL: {SQLALCHEMY_DATABASE_URL}")
print(f"Database directory: {DB_DIR}")
engine = create_engine(
SQLALCHEMY_DATABASE_URL,
connect_args={"check_same_thread": False},
# Echo SQL for debugging (remove in production)
echo=False,
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
except Exception as e:
print(f"Error setting up database connection: {e}")
raise

164
debug_app.py Executable file
View File

@ -0,0 +1,164 @@
#!/usr/bin/env python
"""
Debug script to diagnose FastAPI application startup issues.
This script checks for common issues that might prevent the app from starting.
"""
import importlib
import os
import sys
import traceback
from pathlib import Path
# Configure the Python path
current_dir = Path(__file__).parent.absolute()
sys.path.insert(0, str(current_dir))
def check_import(module_name):
"""Try to import a module and report any errors."""
try:
importlib.import_module(module_name)
print(f"✅ Successfully imported {module_name}")
return True
except Exception as e:
print(f"❌ Failed to import {module_name}: {e}")
print("Traceback:")
traceback.print_exc()
return False
def check_file_exists(file_path):
"""Check if a file exists."""
path = Path(file_path)
if path.exists():
print(f"✅ File exists: {file_path}")
return True
else:
print(f"❌ File does not exist: {file_path}")
return False
def check_directory_exists(dir_path):
"""Check if a directory exists and try to create it if it doesn't."""
path = Path(dir_path)
if path.exists() and path.is_dir():
print(f"✅ Directory exists: {dir_path}")
return True
else:
print(f"❌ Directory does not exist: {dir_path}")
try:
path.mkdir(parents=True, exist_ok=True)
print(f"✅ Created directory: {dir_path}")
return True
except Exception as e:
print(f"❌ Failed to create directory {dir_path}: {e}")
return False
def check_directory_writable(dir_path):
"""Check if a directory is writable."""
path = Path(dir_path)
if not path.exists():
print(f"❌ Directory does not exist: {dir_path}")
return False
try:
test_file = path / "write_test_file.txt"
with open(test_file, "w") as f:
f.write("Test write access")
test_file.unlink() # Remove the test file
print(f"✅ Directory is writable: {dir_path}")
return True
except Exception as e:
print(f"❌ Directory is not writable: {dir_path}: {e}")
return False
def check_database():
"""Check database configuration and connectivity."""
try:
from app.db.session import SQLALCHEMY_DATABASE_URL, engine
print(f"✅ Database URL: {SQLALCHEMY_DATABASE_URL}")
# Check the database directory
db_path = Path(SQLALCHEMY_DATABASE_URL.replace("sqlite:///", ""))
db_dir = db_path.parent
check_directory_exists(db_dir)
check_directory_writable(db_dir)
# Try to connect to the database
try:
conn = engine.connect()
conn.close()
print("✅ Successfully connected to the database")
except Exception as e:
print(f"❌ Failed to connect to the database: {e}")
traceback.print_exc()
except Exception as e:
print(f"❌ Error checking database: {e}")
traceback.print_exc()
def check_app_startup():
"""Try to import the FastAPI app and check for errors."""
try:
# First check if we can import FastAPI
import fastapi
print(f"✅ FastAPI version: {fastapi.__version__}")
# Then try to import the app
from main import app
print("✅ Successfully imported the FastAPI app")
# Check app configuration
print(f"✅ App title: {app.title}")
print(f"✅ App version: {app.version}")
print(f"✅ OpenAPI URL: {app.openapi_url}")
return True
except Exception as e:
print(f"❌ Error during app startup: {e}")
traceback.print_exc()
return False
def main():
"""Run all checks."""
print("\n=== Python Environment ===")
print(f"Python version: {sys.version}")
print(f"Python executable: {sys.executable}")
print(f"Current directory: {os.getcwd()}")
print("\n=== Checking Critical Imports ===")
check_import("fastapi")
check_import("uvicorn")
check_import("sqlalchemy")
check_import("pydantic")
check_import("alembic")
print("\n=== Checking App Imports ===")
check_import("app")
check_import("app.api")
check_import("app.core")
check_import("app.db")
check_import("app.models")
check_import("app.schemas")
print("\n=== Checking Critical Files ===")
check_file_exists("main.py")
check_file_exists("app/core/config.py")
check_file_exists("app/db/session.py")
print("\n=== Checking Storage Directories ===")
project_root = Path(__file__).parent.absolute()
app_storage_dir = project_root / "app" / "storage" / "db"
check_directory_exists(app_storage_dir)
check_directory_writable(app_storage_dir)
print("\n=== Checking Database ===")
check_database()
print("\n=== Testing App Startup ===")
check_app_startup()
print("\n=== Debug Complete ===")
if __name__ == "__main__":
main()

155
main.py
View File

@ -1,100 +1,153 @@
import os
import sys import sys
import time import time
import traceback import traceback
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from pathlib import Path
import uvicorn import uvicorn
from fastapi import FastAPI, Request from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from loguru import logger from loguru import logger
from app.api.v1.api import api_router # Print current directory and Python path for debugging
from app.core.config import settings print(f"Current directory: {os.getcwd()}")
from app.core.logging import setup_logging print(f"Python path: {sys.path}")
# Ensure app is in Python path
PROJECT_ROOT = Path(__file__).parent.absolute()
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
print(f"Added {PROJECT_ROOT} to Python path")
try:
from app.api.v1.api import api_router
from app.core.config import settings
from app.core.logging import setup_logging
print("Successfully imported application modules")
except Exception as e:
print(f"Error importing application modules: {e}")
traceback.print_exc()
sys.exit(1)
# Simplified lifespan to prevent startup errors
@asynccontextmanager @asynccontextmanager
async def lifespan(app: FastAPI): async def lifespan(app: FastAPI):
""" """
Context manager for FastAPI app lifespan events. Context manager for FastAPI app lifespan events.
Simplified to prevent startup errors.
Startup and shutdown events run on application startup and shutdown.
""" """
# Setup logging on startup print("Starting application lifespan...")
try: # Don't use complex startup logic that might fail
setup_logging() yield
logger.info(f"Starting up {settings.PROJECT_NAME}") print("Application shutdown...")
# Verify imports and application setup
logger.info("Application initialized successfully")
yield # Run the application
# Clean up resources on shutdown
logger.info(f"Shutting down {settings.PROJECT_NAME}")
except Exception as e:
logger.error(f"Error during application startup: {e}")
traceback.print_exc()
sys.exit(1)
# Create the FastAPI application with a simplified configuration
app = FastAPI( app = FastAPI(
title=settings.PROJECT_NAME, title=settings.PROJECT_NAME,
openapi_url="/openapi.json", openapi_url="/openapi.json",
version=settings.VERSION, version=settings.VERSION,
lifespan=lifespan,
docs_url="/docs", docs_url="/docs",
redoc_url="/redoc", redoc_url="/redoc",
) )
# Set up basic logging
try:
setup_logging()
logger.info(f"Starting up {settings.PROJECT_NAME}")
except Exception as e:
print(f"Error setting up logging: {e}")
# Continue without logging rather than failing startup
# Add middleware
# Simple process time middleware with error handling
@app.middleware("http") @app.middleware("http")
async def add_process_time_header(request: Request, call_next): async def add_process_time_header(request: Request, call_next):
""" """
Middleware to add X-Process-Time header to response. Middleware to add X-Process-Time header to response.
Includes error handling.
""" """
start_time = time.time() start_time = time.time()
response = await call_next(request) try:
process_time = time.time() - start_time response = await call_next(request)
response.headers["X-Process-Time"] = str(process_time) process_time = time.time() - start_time
response.headers["X-Process-Time"] = str(process_time)
# Log request details (using print as a fallback if logger fails)
try:
logger.info(
f"{request.method} {request.url.path} "
f"Status: {response.status_code} "
f"Process Time: {process_time:.4f}s"
)
except Exception:
print(
f"{request.method} {request.url.path} "
f"Status: {response.status_code} "
f"Process Time: {process_time:.4f}s"
)
return response
except Exception as e:
process_time = time.time() - start_time
print(f"Error processing request {request.url.path}: {e}")
return JSONResponse(
status_code=500,
content={"detail": "Internal server error"},
)
# Log request details
logger.info( # Simple CORS middleware
f"{request.method} {request.url.path} " try:
f"Status: {response.status_code} " # Set all CORS enabled origins
f"Process Time: {process_time:.4f}s" app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Allow all origins
allow_credentials=True,
allow_methods=["*"], # Allow all methods
allow_headers=["*"], # Allow all headers
) )
print("CORS middleware added")
return response except Exception as e:
print(f"Error adding CORS middleware: {e}")
# Set all CORS enabled origins # Try to include API router
app.add_middleware( try:
CORSMiddleware, app.include_router(api_router, prefix=settings.API_V1_STR)
allow_origins=["*"], # Allow all origins print(f"API router added with prefix: {settings.API_V1_STR}")
allow_credentials=True, except Exception as e:
allow_methods=["*"], # Allow all methods print(f"Error including API router: {e}")
allow_headers=["*"], # Allow all headers # Add a fallback router if the main one fails
) fallback_router = FastAPI()
app.include_router(fallback_router)
app.include_router(api_router, prefix=settings.API_V1_STR)
# Basic health check endpoint
@app.get("/health", tags=["health"]) @app.get("/health", tags=["health"])
async def health_check(): async def health_check():
""" """
Health check endpoint to verify the API is running. Health check endpoint to verify the API is running.
""" """
logger.debug("Health check endpoint called") try:
logger.debug("Health check endpoint called")
except Exception:
pass
return {"status": "healthy"} return {"status": "healthy"}
# Simple root endpoint
@app.get("/", tags=["root"])
async def root():
"""
Root endpoint for quick testing.
"""
return {"message": "Manga Inventory API is running"}
if __name__ == "__main__": if __name__ == "__main__":
try: # Simplified server startup
logger.info("Starting server with uvicorn...") print("Starting server with uvicorn...")
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True) uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
except Exception as e:
logger.error(f"Failed to start server: {e}")
traceback.print_exc()
sys.exit(1)