allow all origins for cors
This commit is contained in:
parent
8db0013f26
commit
6a5649a49c
@ -1,16 +1,38 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
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()
|
||||
|
||||
# Create the directory for the SQLite database if it doesn't exist
|
||||
DB_DIR = PROJECT_ROOT / "app" / "storage" / "db"
|
||||
DB_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
SQLALCHEMY_DATABASE_URL = f"sqlite:///{DB_DIR}/db.sqlite"
|
||||
|
||||
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
|
||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
try:
|
||||
# Create the directory for the SQLite database if it doesn't exist
|
||||
DB_DIR = PROJECT_ROOT / "app" / "storage" / "db"
|
||||
DB_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Ensure the directory is writable
|
||||
test_file = DB_DIR / ".test_write_access"
|
||||
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
164
debug_app.py
Executable 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
155
main.py
@ -1,100 +1,153 @@
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import traceback
|
||||
from contextlib import asynccontextmanager
|
||||
from pathlib import Path
|
||||
|
||||
import uvicorn
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import JSONResponse
|
||||
from loguru import logger
|
||||
|
||||
from app.api.v1.api import api_router
|
||||
from app.core.config import settings
|
||||
from app.core.logging import setup_logging
|
||||
# Print current directory and Python path for debugging
|
||||
print(f"Current directory: {os.getcwd()}")
|
||||
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
|
||||
async def lifespan(app: FastAPI):
|
||||
"""
|
||||
Context manager for FastAPI app lifespan events.
|
||||
|
||||
Startup and shutdown events run on application startup and shutdown.
|
||||
Simplified to prevent startup errors.
|
||||
"""
|
||||
# Setup logging on startup
|
||||
try:
|
||||
setup_logging()
|
||||
logger.info(f"Starting up {settings.PROJECT_NAME}")
|
||||
|
||||
# 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)
|
||||
print("Starting application lifespan...")
|
||||
# Don't use complex startup logic that might fail
|
||||
yield
|
||||
print("Application shutdown...")
|
||||
|
||||
|
||||
# Create the FastAPI application with a simplified configuration
|
||||
app = FastAPI(
|
||||
title=settings.PROJECT_NAME,
|
||||
openapi_url="/openapi.json",
|
||||
version=settings.VERSION,
|
||||
lifespan=lifespan,
|
||||
docs_url="/docs",
|
||||
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")
|
||||
async def add_process_time_header(request: Request, call_next):
|
||||
"""
|
||||
Middleware to add X-Process-Time header to response.
|
||||
Includes error handling.
|
||||
"""
|
||||
start_time = time.time()
|
||||
response = await call_next(request)
|
||||
process_time = time.time() - start_time
|
||||
response.headers["X-Process-Time"] = str(process_time)
|
||||
try:
|
||||
response = await call_next(request)
|
||||
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(
|
||||
f"{request.method} {request.url.path} "
|
||||
f"Status: {response.status_code} "
|
||||
f"Process Time: {process_time:.4f}s"
|
||||
|
||||
# Simple CORS middleware
|
||||
try:
|
||||
# Set all CORS enabled origins
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["*"], # Allow all origins
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"], # Allow all methods
|
||||
allow_headers=["*"], # Allow all headers
|
||||
)
|
||||
|
||||
return response
|
||||
print("CORS middleware added")
|
||||
except Exception as e:
|
||||
print(f"Error adding CORS middleware: {e}")
|
||||
|
||||
|
||||
# Set all CORS enabled origins
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["*"], # Allow all origins
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"], # Allow all methods
|
||||
allow_headers=["*"], # Allow all headers
|
||||
)
|
||||
|
||||
app.include_router(api_router, prefix=settings.API_V1_STR)
|
||||
# Try to include API router
|
||||
try:
|
||||
app.include_router(api_router, prefix=settings.API_V1_STR)
|
||||
print(f"API router added with prefix: {settings.API_V1_STR}")
|
||||
except Exception as e:
|
||||
print(f"Error including API router: {e}")
|
||||
# Add a fallback router if the main one fails
|
||||
fallback_router = FastAPI()
|
||||
app.include_router(fallback_router)
|
||||
|
||||
|
||||
# Basic health check endpoint
|
||||
@app.get("/health", tags=["health"])
|
||||
async def health_check():
|
||||
"""
|
||||
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"}
|
||||
|
||||
|
||||
# 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__":
|
||||
try:
|
||||
logger.info("Starting server with uvicorn...")
|
||||
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)
|
||||
# Simplified server startup
|
||||
print("Starting server with uvicorn...")
|
||||
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
|
||||
|
Loading…
x
Reference in New Issue
Block a user