87 lines
2.2 KiB
Python
87 lines
2.2 KiB
Python
"""
|
||
Weibo-HotSign API Service
|
||
Main FastAPI application entry point — account management, task config, signin logs.
|
||
"""
|
||
|
||
import logging
|
||
|
||
from fastapi import FastAPI, Request
|
||
from fastapi.exceptions import RequestValidationError
|
||
from fastapi.middleware.cors import CORSMiddleware
|
||
from starlette.exceptions import HTTPException as StarletteHTTPException
|
||
|
||
from shared.response import success_response, error_response
|
||
from api_service.app.routers import accounts, tasks, signin_logs
|
||
|
||
|
||
# 过滤 /health 的 access log,避免日志刷屏
|
||
class _HealthFilter(logging.Filter):
|
||
def filter(self, record: logging.LogRecord) -> bool:
|
||
msg = record.getMessage()
|
||
return "/health" not in msg
|
||
|
||
logging.getLogger("uvicorn.access").addFilter(_HealthFilter())
|
||
|
||
app = FastAPI(
|
||
title="Weibo-HotSign API Service",
|
||
version="1.0.0",
|
||
docs_url="/docs",
|
||
redoc_url="/redoc",
|
||
)
|
||
|
||
# CORS
|
||
app.add_middleware(
|
||
CORSMiddleware,
|
||
allow_origins=["http://localhost:3000", "http://localhost:80"],
|
||
allow_credentials=True,
|
||
allow_methods=["*"],
|
||
allow_headers=["*"],
|
||
)
|
||
|
||
|
||
# ---- Global exception handlers (unified response format) ----
|
||
|
||
@app.exception_handler(StarletteHTTPException)
|
||
async def http_exception_handler(request: Request, exc: StarletteHTTPException):
|
||
return error_response(
|
||
exc.detail,
|
||
f"HTTP_{exc.status_code}",
|
||
status_code=exc.status_code,
|
||
)
|
||
|
||
|
||
@app.exception_handler(RequestValidationError)
|
||
async def validation_exception_handler(request: Request, exc: RequestValidationError):
|
||
details = [
|
||
{"field": e["loc"][-1] if e["loc"] else "unknown", "message": e["msg"]}
|
||
for e in exc.errors()
|
||
]
|
||
return error_response(
|
||
"Validation failed",
|
||
"VALIDATION_ERROR",
|
||
details=details,
|
||
status_code=400,
|
||
)
|
||
|
||
|
||
# ---- Routers ----
|
||
|
||
app.include_router(accounts.router)
|
||
app.include_router(tasks.router)
|
||
app.include_router(signin_logs.router)
|
||
|
||
|
||
# ---- Health / root ----
|
||
|
||
@app.get("/")
|
||
async def root():
|
||
return success_response(
|
||
{"service": "Weibo-HotSign API Service", "version": "1.0.0"},
|
||
"Service is running",
|
||
)
|
||
|
||
|
||
@app.get("/health")
|
||
async def health_check():
|
||
return success_response({"status": "healthy"})
|