当前位置: 首页 > news >正文

让Trae写一个AI的api中继服务

g4f的1337端口的api服务用起来有时候不太方便,这时候就

代码

from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import StreamingResponse
from g4f.client import Client
import json
import osapp = FastAPI(title="G4F本地模型中继服务")# 允许跨域请求
app.add_middleware(CORSMiddleware,allow_origins=["*"],allow_credentials=True,allow_methods=["*"],allow_headers=["*"],
)# 初始化G4F客户端
client = Client()@app.post("/v1/chat/completions")
async def chat_completions(request: Request):try:# 1. 解析 OpenAI 格式的请求data = await request.json()print(f"==== 收到请求: {data}")# 提取消息内容messages = data.get("messages", [])if not messages:raise HTTPException(status_code=400, detail="No messages provided")# 2. 使用G4F客户端进行本地模型调用stream = data.get("stream", False)# 构建G4F调用参数g4f_params = {"messages": messages,"temperature": data.get("temperature", 0.7),"max_tokens": data.get("max_tokens", 500)}# 如果指定了模型,则使用指定模型,否则使用默认模型model = data.get("model")if model and model != "default":g4f_params["model"] = model# 3. 调用G4F模型if stream:# 流式响应处理async def generate_stream():try:response = client.chat.completions.create(**g4f_params, stream=True)for chunk in response:if hasattr(chunk, 'choices') and chunk.choices:content = chunk.choices[0].delta.content# 只有当内容不为None时才发送if content is not None:yield f"data: {json.dumps({'choices': [{'delta': {'content': content}}]})}\n\n"# 流结束时发送[DONE]信号yield "data: [DONE]\n\n"except Exception as e:yield f"data: {json.dumps({'error': str(e)})}\n\n"return StreamingResponse(generate_stream(),media_type="text/event-stream",headers={"Cache-Control": "no-cache","Connection": "keep-alive",})else:# 非流式响应response = client.chat.completions.create(**g4f_params)# 转换为OpenAI兼容格式return {"id": "chatcmpl-g4f-local","object": "chat.completion","created": 0,"model": model or "g4f-default","choices": [{"index": 0,"message": {"role": "assistant","content": response.choices[0].message.content},"finish_reason": "stop"}],"usage": {"prompt_tokens": 0,"completion_tokens": 0,"total_tokens": 0}}except Exception as e:raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")@app.get("/")
async def root():return {"message": "星河社区大模型中继服务","status": "running","endpoint": "/v1/chat/completions"}@app.get("/health")
async def health_check():return {"status": "healthy"}if __name__ == "__main__":import uvicornuvicorn.run(app, host="0.0.0.0", port=8000)

http://www.dtcms.com/a/391223.html

相关文章:

  • 跨国制造业SD-WAN:延迟下降78%,运维成本下降53%
  • MySQL服务启动不成功的可能解决方法
  • 硬解码出现画面回退分析
  • P1068 [NOIP 2009 普及组] 分数线划定-普及-
  • 用python语言如何排大小
  • pycharm连接GitHub,怎么配置 SSH 密钥并改用 SSH 连接
  • ​​[硬件电路-265]:电源系统要考虑的因素包括:不同的输出电压、隔离防干扰、防反、防浪涌、电压可调、电源开关、电池、可充电、低纹波、低噪声、防波动等
  • 【开题答辩全过程】以 基于Python的电影推荐系统为例,包含答辩的问题和答案
  • 格拉姆角场(Gramian Angular Field, GAF)详解
  • 前端开发工具Vue有哪些?常用Vue前端开发工具推荐、Vue开发工具对比与最佳实践分享
  • 基于vue的幼儿园健康管理系统0fz0y(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • 第69课 分类任务: 基于BERT训练情感分类与区别二分类本质思考
  • Mysql杂志(二十)——MyISAM索引结构与B树B+树
  • Java 大视界 -- 基于 Java 的大数据实时流处理在金融高频交易数据分析中的应用
  • BonkFun 推出 USD1:Meme 币玩法的新入口
  • flutter在包含ListVIew的滚动列表页面中监听手势
  • Redis 三种集群模式详解
  • 打开hot100
  • Ant-Design Table中使用 AStatisticCountdown倒计时,鼠标在表格上移动时倒计时被重置
  • Linux crontab 定时任务工具使用
  • 阿里云RDS mysql8数据本地恢复,与本地主从同步(容器中)
  • 记录一次mysql启动失败问题解决
  • LeetCode算法练习:35.搜索插入位置
  • (1) 为什么推荐tauri框架
  • 嵌入式面试高频(八)!!!C++语言(嵌入式八股文,嵌入式面经)
  • Spring AI开发指导-工具调用
  • Linux 基本命令超详细解释第二期 | touch | cat | more | cp | mv | rm | which | find
  • [x-cmd] 安装指南
  • Altium Designer(AD24)原理图Move移动功能详细介绍图文教程
  • 部署java程序,服务器报403 Forbidden 问题的终极解决方案