apikey in header
This commit is contained in:
parent
4ba950a1ea
commit
d123a67da1
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
|||||||
projects/*
|
projects/*
|
||||||
workspace
|
workspace
|
||||||
__pycache__
|
__pycache__
|
||||||
|
public
|
||||||
|
|||||||
@ -29,16 +29,17 @@ COPY . .
|
|||||||
|
|
||||||
# 创建必要的目录
|
# 创建必要的目录
|
||||||
RUN mkdir -p /app/projects
|
RUN mkdir -p /app/projects
|
||||||
|
RUN mkdir -p /app/public
|
||||||
|
|
||||||
# 设置权限
|
# 设置权限
|
||||||
RUN chmod +x /app/mcp/json_reader_server.py
|
RUN chmod +x /app/mcp/json_reader_server.py
|
||||||
|
|
||||||
# 暴露端口
|
# 暴露端口
|
||||||
EXPOSE 8000
|
EXPOSE 8001
|
||||||
|
|
||||||
# 健康检查
|
# 健康检查
|
||||||
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
|
||||||
CMD curl -f http://localhost:8000/ || exit 1
|
CMD curl -f http://localhost:8001/ || exit 1
|
||||||
|
|
||||||
# 启动命令
|
# 启动命令
|
||||||
CMD ["python", "fastapi_app.py"]
|
CMD ["python", "fastapi_app.py"]
|
||||||
|
|||||||
@ -5,7 +5,7 @@ services:
|
|||||||
build: .
|
build: .
|
||||||
container_name: qwen-agent-api
|
container_name: qwen-agent-api
|
||||||
ports:
|
ports:
|
||||||
- "8000:8000"
|
- "8001:8001"
|
||||||
environment:
|
environment:
|
||||||
# 应用配置
|
# 应用配置
|
||||||
- PYTHONPATH=/app
|
- PYTHONPATH=/app
|
||||||
@ -14,10 +14,11 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
# 挂载项目数据目录
|
# 挂载项目数据目录
|
||||||
- ./projects:/app/projects
|
- ./projects:/app/projects
|
||||||
|
- ./public:/app/public
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:8000/"]
|
test: ["CMD", "curl", "-f", "http://localhost:8001/"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import os
|
|||||||
from typing import AsyncGenerator, Dict, List, Optional, Union
|
from typing import AsyncGenerator, Dict, List, Optional, Union
|
||||||
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from fastapi import FastAPI, HTTPException
|
from fastapi import FastAPI, HTTPException, Depends, Header
|
||||||
from fastapi.responses import StreamingResponse, HTMLResponse, FileResponse
|
from fastapi.responses import StreamingResponse, HTMLResponse, FileResponse
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
@ -51,6 +51,9 @@ agent_manager = init_global_agent_manager(max_cached_agents=max_cached_agents)
|
|||||||
|
|
||||||
app = FastAPI(title="Database Assistant API", version="1.0.0")
|
app = FastAPI(title="Database Assistant API", version="1.0.0")
|
||||||
|
|
||||||
|
# 挂载public文件夹为静态文件服务
|
||||||
|
app.mount("/public", StaticFiles(directory="public"), name="static")
|
||||||
|
|
||||||
# 添加CORS中间件,支持前端页面
|
# 添加CORS中间件,支持前端页面
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
@ -69,7 +72,6 @@ class Message(BaseModel):
|
|||||||
class ChatRequest(BaseModel):
|
class ChatRequest(BaseModel):
|
||||||
messages: List[Message]
|
messages: List[Message]
|
||||||
model: str = "qwen3-next"
|
model: str = "qwen3-next"
|
||||||
api_key: Optional[str] = None
|
|
||||||
model_server: Optional[str] = None
|
model_server: Optional[str] = None
|
||||||
zip_url: Optional[str] = None
|
zip_url: Optional[str] = None
|
||||||
generate_cfg: Optional[Dict] = None
|
generate_cfg: Optional[Dict] = None
|
||||||
@ -156,18 +158,28 @@ async def generate_stream_response(agent, messages, request) -> AsyncGenerator[s
|
|||||||
yield f"data: {json.dumps(error_data, ensure_ascii=False)}\n\n"
|
yield f"data: {json.dumps(error_data, ensure_ascii=False)}\n\n"
|
||||||
|
|
||||||
|
|
||||||
@app.post("/chat/completions")
|
@app.post("/api/v1/chat/completions")
|
||||||
async def chat_completions(request: ChatRequest):
|
async def chat_completions(request: ChatRequest, authorization: Optional[str] = Header(None)):
|
||||||
"""
|
"""
|
||||||
Chat completions API similar to OpenAI, supports both streaming and non-streaming
|
Chat completions API similar to OpenAI, supports both streaming and non-streaming
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
request: ChatRequest containing messages, model, zip_url, etc.
|
request: ChatRequest containing messages, model, zip_url, etc.
|
||||||
|
authorization: Authorization header containing API key (Bearer <API_KEY>)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Union[ChatResponse, StreamingResponse]: Chat completion response or stream
|
Union[ChatResponse, StreamingResponse]: Chat completion response or stream
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
# 从Authorization header中提取API key
|
||||||
|
api_key = None
|
||||||
|
if authorization:
|
||||||
|
# 移除 "Bearer " 前缀
|
||||||
|
if authorization.startswith("Bearer "):
|
||||||
|
api_key = authorization[7:]
|
||||||
|
else:
|
||||||
|
api_key = authorization
|
||||||
|
|
||||||
# 从最外层获取zip_url参数
|
# 从最外层获取zip_url参数
|
||||||
zip_url = request.zip_url
|
zip_url = request.zip_url
|
||||||
|
|
||||||
@ -191,7 +203,7 @@ async def chat_completions(request: ChatRequest):
|
|||||||
zip_url=zip_url,
|
zip_url=zip_url,
|
||||||
files=document_files,
|
files=document_files,
|
||||||
model_name=request.model,
|
model_name=request.model,
|
||||||
api_key=request.api_key,
|
api_key=api_key,
|
||||||
model_server=request.model_server,
|
model_server=request.model_server,
|
||||||
generate_cfg=request.generate_cfg
|
generate_cfg=request.generate_cfg
|
||||||
)
|
)
|
||||||
@ -258,14 +270,6 @@ async def chat_completions(request: ChatRequest):
|
|||||||
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
|
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
|
||||||
async def root():
|
|
||||||
"""Chat page endpoint"""
|
|
||||||
return FileResponse("chat.html", media_type="text/html")
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/api/health")
|
@app.get("/api/health")
|
||||||
async def health_check():
|
async def health_check():
|
||||||
"""Health check endpoint"""
|
"""Health check endpoint"""
|
||||||
@ -353,4 +357,4 @@ async def remove_project_cache(zip_url: str):
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
uvicorn.run(app, host="0.0.0.0", port=8000)
|
uvicorn.run(app, host="0.0.0.0", port=8001)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user