#!/usr/bin/env python # -*- coding: utf-8 -*- """ Dify API 中转服务 提供REST API端点,转发请求到Dify API """ import os import json import logging from typing import Dict, Any, Optional from fastapi import FastAPI, Header, Request, HTTPException, Response from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel import uvicorn import configparser from dify_api_client import DifyAPIClient, setup_logging # 检查是否在Hugging Face环境中 is_hf_space = os.environ.get('SPACE_ID') is not None # 创建FastAPI应用 app = FastAPI( title="Dify API 中转服务", description="提供REST API端点,转发请求到Dify API", version="1.0.0" ) # 添加CORS中间件 app.add_middleware( CORSMiddleware, allow_origins=["*"], # 允许所有来源 allow_credentials=True, allow_methods=["*"], # 允许所有方法 allow_headers=["*"], # 允许所有头 ) # 配置日志 - 在Hugging Face环境中禁用文件日志 setup_logging(debug=False, disable_file_logging=is_hf_space) # 请求模型 class QueryRequest(BaseModel): query: str conversation_id: Optional[str] = None user: Optional[str] = "user" response_mode: Optional[str] = "blocking" # 'blocking' 或 'streaming' # 健康检查端点 @app.get("/") @app.get("/health") def health_check(): return {"status": "ok"} # Dify API中转端点 @app.post("/dify_api") async def dify_api( request: Request, query_request: QueryRequest, dify_url: Optional[str] = Header(None), dify_key: Optional[str] = Header(None) ): # 检查必要的头信息 if not dify_url: raise HTTPException(status_code=400, detail="缺少必要的请求头: dify_url") if not dify_key: raise HTTPException(status_code=400, detail="缺少必要的请求头: dify_key") logging.info(f"接收到API请求,目标URL: {dify_url}") try: # 创建Dify客户端 client = DifyAPIClient(api_key=dify_key, base_url=dify_url) # 根据请求模式处理 if query_request.response_mode == "streaming": # 对于流式响应,我们需要使用StreamingResponse # 但由于原始客户端不支持异步流式返回,这里我们先返回完整响应 # 在实际生产环境中,应该重构客户端代码以支持异步流式响应 response_text = client.send_request_streaming( content=query_request.query, conversation_id=query_request.conversation_id, user=query_request.user ) return {"answer": response_text} else: # 阻塞模式 response_data = client.send_request_blocking( content=query_request.query, conversation_id=query_request.conversation_id, user=query_request.user ) return response_data except Exception as e: logging.error(f"处理请求时出错: {str(e)}") raise HTTPException(status_code=500, detail=f"处理请求时出错: {str(e)}") # 主函数 def main(): # 在本地运行时使用 uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=True) if __name__ == "__main__": main()