Files
sriphat-dataplatform/03-apiservice-v0.1/app/main.py
2026-02-24 22:33:37 +07:00

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)