File size: 4,310 Bytes
58de15f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# main.py

import logging # Standard import

# --- Setup Logging FIRST ---
# Apply the configuration defined in logging_config.py
from app.core.logging_config import setup_logging
setup_logging()
# --- Logging setup complete ---

# --- Now other imports ---
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

# Import settings and the V2 API router
from app.core.config import settings
from app.api import v2_endpoints # This imports the router defined in that file

# --- DB imports for table creation ---
# Import engine and Base from your database setup
from app.db.database import engine, Base
# --- Make sure models are imported so Base knows about them for create_all ---
# This line ensures SQLAlchemy's Base registry is aware of your table models
from app.db import models

# Get logger instance *after* setup_logging() has run
# This logger is specifically for messages generated directly in main.py
logger = logging.getLogger(__name__)

# --- Function to create database tables ---
# Defines the function to be called on startup
def create_db_tables():
    logger.info("Attempting to create V2 database tables (if they don't exist)...")
    try:
        # Base.metadata contains registry of all tables defined using the Base declarative class
        Base.metadata.create_all(bind=engine)
        logger.info("V2 Database tables checked/created successfully.")
    except Exception as e:
        # Log the full error trace if table creation fails
        logger.exception(f"CRITICAL: Failed to create V2 database tables: {e}")
        # Depending on requirements, you might want to raise an error
        # to stop the application from starting if the DB is essential.
        # raise RuntimeError("Failed to create V2 database tables.") from e

# --- Initialize FastAPI app ---
# Creates the main application instance
app = FastAPI(
    title=settings.PROJECT_NAME,
    description="Chatbot Backend V2 using FastAPI and GNN-based Retrieval",
    version="2.0.0", # Indicate V2
    # Define the URL for the OpenAPI docs (Swagger UI) under the API prefix
    openapi_url=f"{settings.API_V2_PREFIX}/openapi.json",
    # Define the URL for the Swagger UI itself
    docs_url=f"{settings.API_V2_PREFIX}/docs",
    redoc_url=f"{settings.API_V2_PREFIX}/redoc" # Optional: Define ReDoc URL
)

# --- Add CORS middleware ---
# This must be added BEFORE including routers
logger.info("Adding CORSMiddleware with HARDCODED origins for debugging...")
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:5173"], # Directly specify the frontend origin
    # allow_origins=["*"], # Or try allowing all origins temporarily
    allow_credentials=True,
    allow_methods=["*"], # Allow all methods
    allow_headers=["*"], # Allow all headers
)

# --- Include the V2 API router ---
# Mounts all the endpoints defined in v2_endpoints.py under the specified prefix
logger.info(f"Including V2 API router with prefix: {settings.API_V2_PREFIX}")
app.include_router(v2_endpoints.router, prefix=settings.API_V2_PREFIX)

# --- Root endpoint (optional) ---
# A simple endpoint at the base URL ("/") to check if the API is running
@app.get("/", tags=["Root"])
async def read_root():
    """Basic health check endpoint."""
    logger.info("Root endpoint '/' accessed.")
    return {"message": f"Welcome to {settings.PROJECT_NAME}. API V2 is available at {settings.API_V2_PREFIX}"}


# --- Application Startup Event ---
@app.on_event("startup")
async def startup_event():
    """
    Actions to perform when the application starts up.
    - Creates database tables.
    - Note: The router's specific startup event (for loading models/data)
      runs automatically AFTER this app-level event.
    """
    # Logging is configured before this runs by the setup_logging() call
    logger.info("Executing application startup event...")
    # Create database tables (idempotent - won't recreate if they exist)
    create_db_tables()
    logger.info("Application startup event completed.")

# --- Application Shutdown Event (optional) ---
@app.on_event("shutdown")
async def shutdown_event():
    """Actions to perform when the application shuts down."""
    logger.info("Application shutting down...")
    # Add any cleanup logic here if needed (e.g., closing external connections)