|
|
|
|
|
|
|
|
import traceback |
|
|
import time |
|
|
from typing import Optional, List, Dict, Any |
|
|
|
|
|
from fastapi import FastAPI, Request, HTTPException, Depends, Header |
|
|
|
|
|
from app.core.config import settings |
|
|
from app.providers.text_provider import TextProvider |
|
|
|
|
|
app = FastAPI( |
|
|
title=settings.APP_NAME, |
|
|
version=settings.APP_VERSION, |
|
|
description=settings.DESCRIPTION |
|
|
) |
|
|
|
|
|
|
|
|
text_provider = TextProvider() |
|
|
|
|
|
|
|
|
|
|
|
async def verify_api_key(authorization: Optional[str] = Header(None)): |
|
|
""" |
|
|
检查 API 密钥的依赖项。 |
|
|
如果设置了 API_MASTER_KEY,则请求头中必须包含正确的密钥。 |
|
|
""" |
|
|
|
|
|
if not settings.API_MASTER_KEY: |
|
|
print("警告:未配置 API_MASTER_KEY,服务将对所有请求开放。") |
|
|
return |
|
|
|
|
|
|
|
|
if authorization is None: |
|
|
raise HTTPException( |
|
|
status_code=401, |
|
|
detail="Unauthorized: Missing Authorization header.", |
|
|
) |
|
|
|
|
|
|
|
|
try: |
|
|
scheme, token = authorization.split() |
|
|
if scheme.lower() != "bearer": |
|
|
raise ValueError("Invalid scheme") |
|
|
except ValueError: |
|
|
raise HTTPException( |
|
|
status_code=401, |
|
|
detail="Invalid authentication scheme. Use 'Bearer <your_api_key>'.", |
|
|
) |
|
|
|
|
|
|
|
|
if token != settings.API_MASTER_KEY: |
|
|
raise HTTPException( |
|
|
status_code=403, |
|
|
detail="Forbidden: Invalid API Key.", |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.post("/v1/chat/completions", dependencies=[Depends(verify_api_key)]) |
|
|
async def chat_completions(request: Request): |
|
|
""" |
|
|
终极路由:所有请求都交给全能的 TextProvider 处理。 |
|
|
在处理前会先通过 verify_api_key 进行认证。 |
|
|
""" |
|
|
try: |
|
|
request_data = await request.json() |
|
|
print("接收到聊天请求,认证通过,路由到全能的 TextProvider...") |
|
|
return await text_provider.chat_completion(request_data, request) |
|
|
except Exception as e: |
|
|
traceback.print_exc() |
|
|
raise HTTPException(status_code=500, detail=f"主路由发生内部服务器错误: {str(e)}") |
|
|
|
|
|
|
|
|
|
|
|
@app.get("/v1/models", dependencies=[Depends(verify_api_key)]) |
|
|
async def list_models(): |
|
|
""" |
|
|
新增的接口,用于返回兼容OpenAI格式的模型列表。 |
|
|
它会读取 config.py 中的 SUPPORTED_MODELS 列表。 |
|
|
""" |
|
|
print("接收到模型列表请求,认证通过...") |
|
|
|
|
|
|
|
|
model_names: List[str] = settings.SUPPORTED_MODELS |
|
|
|
|
|
|
|
|
model_data: List[Dict[str, Any]] = [] |
|
|
for name in model_names: |
|
|
model_data.append({ |
|
|
"id": name, |
|
|
"object": "model", |
|
|
"created": int(time.time()), |
|
|
"owned_by": "system" |
|
|
}) |
|
|
|
|
|
return { |
|
|
"object": "list", |
|
|
"data": model_data |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@app.get("/") |
|
|
def root(): |
|
|
"""根路由,提供服务基本信息,无需认证。""" |
|
|
return {"message": f"Welcome to {settings.APP_NAME}", "version": settings.APP_VERSION} |