100 lines
3.9 KiB
Python
100 lines
3.9 KiB
Python
from contextlib import asynccontextmanager
|
|
|
|
from fastapi import FastAPI
|
|
from starlette.datastructures import Headers
|
|
from starlette.middleware.sessions import SessionMiddleware
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from starlette.middleware.base import BaseHTTPMiddleware
|
|
|
|
class ForceHTTPSMiddleware(BaseHTTPMiddleware):
|
|
async def dispatch(self, request, call_next):
|
|
# บังคับให้ FastAPI มองว่า Request ที่เข้ามาเป็น HTTPS เสมอ
|
|
# เพื่อให้ url_for() เจนลิงก์ CSS/JS เป็น https://
|
|
request.scope["scheme"] = "https"
|
|
response = await call_next(request)
|
|
return response
|
|
|
|
|
|
class ForwardedProtoMiddleware:
|
|
def __init__(self, app):
|
|
self.app = app
|
|
|
|
async def __call__(self, scope, receive, send):
|
|
if scope["type"] in {"http", "websocket"}:
|
|
headers = Headers(scope=scope)
|
|
forwarded_proto = headers.get("x-forwarded-proto")
|
|
if forwarded_proto:
|
|
proto = forwarded_proto.split(",", 1)[0].strip()
|
|
if proto:
|
|
new_scope = dict(scope)
|
|
new_scope["scheme"] = proto
|
|
return await self.app(new_scope, receive, send)
|
|
|
|
return await self.app(scope, receive, send)
|
|
|
|
|
|
# class RootPathStripMiddleware:
|
|
# def __init__(self, app, prefix: str):
|
|
# self.app = app
|
|
# self.prefix = (prefix or "").rstrip("/")
|
|
|
|
# async def __call__(self, scope, receive, send):
|
|
# if scope["type"] in {"http", "websocket"} and self.prefix:
|
|
# path = scope.get("path") or ""
|
|
# new_scope = dict(scope)
|
|
# new_scope["root_path"] = self.prefix
|
|
|
|
# if path == self.prefix or path.startswith(self.prefix + "/"):
|
|
# new_path = path[len(self.prefix) :]
|
|
# new_scope["path"] = new_path if new_path else "/"
|
|
|
|
# return await self.app(new_scope, receive, send)
|
|
|
|
# return await self.app(scope, receive, send)
|
|
|
|
from app.admin import mount_admin
|
|
from app.api.v1.routes import router as v1_router
|
|
from app.core.config import settings
|
|
from app.db.init_db import init_db
|
|
from fastapi.staticfiles import StaticFiles
|
|
from sqladmin import Admin
|
|
import os
|
|
import sqladmin
|
|
|
|
# รายชื่อ Origins ที่อนุญาตให้ยิง API มาหาเราได้
|
|
origins = [
|
|
"http://localhost:80400", # สำหรับตอนพัฒนา Frontend
|
|
"https://ai.sriphat.com", # Domain หลักของคุณ
|
|
"http://ai.sriphat.com",
|
|
]
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(_: FastAPI):
|
|
init_db()
|
|
yield
|
|
|
|
print(settings.ROOT_PATH, flush=True)
|
|
|
|
sqladmin_dir = os.path.dirname(sqladmin.__file__)
|
|
statics_path = os.path.join(sqladmin_dir, "statics")
|
|
|
|
app = FastAPI(title=settings.APP_NAME, root_path=settings.ROOT_PATH, lifespan=lifespan)
|
|
#if settings.ROOT_PATH:
|
|
# app.add_middleware(RootPathStripMiddleware, prefix=settings.ROOT_PATH)
|
|
app.add_middleware(ForceHTTPSMiddleware)
|
|
app.add_middleware(SessionMiddleware, secret_key=settings.ADMIN_SECRET_KEY)
|
|
app.add_middleware(ForwardedProtoMiddleware)
|
|
app.include_router(v1_router)
|
|
app.mount("/admin/statics", StaticFiles(directory=statics_path), name="admin_statics")
|
|
app.mount("/apiservice/admin/statics", StaticFiles(directory=statics_path), name="proxy_admin_statics")
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=origins, # หรือ ["*"] ถ้าต้องการอนุญาตทั้งหมด (ไม่แนะนำใน production)
|
|
allow_credentials=True, # สำคัญมาก! ต้องเป็น True ถ้าหน้า Admin/API มีการใช้ Cookies/Sessions
|
|
allow_methods=["*"], # อนุญาตทุก HTTP Method (GET, POST, PUT, DELETE, etc.)
|
|
allow_headers=["*"], # อนุญาตทุก Headers
|
|
)
|
|
|
|
mount_admin(app)
|
|
|