File size: 3,029 Bytes
fe56754
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from contextlib import asynccontextmanager
import os
from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware
from slowapi import _rate_limit_exceeded_handler
from slowapi.errors import RateLimitExceeded
from app.api.user_routes import router as user_router
from app.api.auth_routes import router as auth_router
from app.api.profile_routes import router as profile_router
from app.api.file_routes import router as file_router
from app.api.feedback_routes import router as feedback_router
from app.api.admin_routes import router as admin_router
from app.api.metric_routes import router as metrics_router
from app.api.user_issue_routes import router as user_issue_router
from app.core.logging_middleware import APILoggingMiddleware
from app.core.limiter import limiter
from app.middleware.security_headers import SecurityHeadersMiddleware
from starlette.middleware.sessions import SessionMiddleware

@asynccontextmanager
async def lifespan(app: FastAPI):
    # Auto-create any missing tables (e.g. audit_logs) without dropping existing data
    from app.db.database import Base, engine
    import app.models.audit_model  # noqa: ensure AuditLog is registered with Base
    import app.models.user_model   # noqa
    import app.models.file_model   # noqa
    Base.metadata.create_all(bind=engine, checkfirst=True)
    yield

is_production = os.environ.get("ENVIRONMENT", "development") == "production"

app = FastAPI(
    title="Spotix",
    lifespan=lifespan,
    docs_url=None if is_production else "/docs",
    redoc_url=None if is_production else "/redoc",
    openapi_url=None if is_production else "/openapi.json"
)

app.add_middleware(ProxyHeadersMiddleware, trusted_hosts=["*"])

app.add_middleware(
    SessionMiddleware, 
    secret_key=os.environ.get("SESSION_SECRET_KEY", "neural-vault-oauth-session-secret-9912"),
    https_only=is_production
)

frontend_url = os.environ.get("FRONTEND_URL", "http://localhost:3000")
origins = [frontend_url]
if frontend_url != "http://localhost:3000":
    origins.append("http://localhost:3000")

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Trigger reload
app.mount("/static", StaticFiles(directory="."), name="static")

app.state.limiter = limiter
app.include_router(profile_router)
app.include_router(user_router)
app.include_router(auth_router)
app.include_router(file_router)
app.include_router(feedback_router)
app.include_router(admin_router)
app.include_router(metrics_router)
app.include_router(user_issue_router)
app.add_middleware(APILoggingMiddleware)
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
app.add_middleware(SecurityHeadersMiddleware)

@app.get("/")
def home():
    return {"message": "Backend running successfully"}