SSE实现
import pandas as pd from fastapi import FastAPI, Request, Query, HTTPException from sse_starlette import EventSourceResponse import aiohttp import uvicorn from starlette.middleware.cors import CORSMiddleware import io import json import re import os app = FastAPI() # 添加 CORS 中间件 app.add_middleware( CORSMiddleware, allow_origins=["*"], # 允许所有来源,或根据需要指定来源 allow_credentials=True, allow_methods=["*"], # 允许所有方法 allow_headers=["*"], # 允许所有头部 ) DEEPSEEK_API_KEY = "你自己的key" # 全局变量用于存储读取的数据和数据描述信息 df = None df_info = None def generate_df_info(df): """ 动态生成 DataFrame 的信息字符串,类似于 df.info() 输出。 """ buf = io.StringIO() df.info(buf=buf) return buf.getvalue() ##可以改成文件上传逻辑 def load_data(): """ 读取 Excel 文件并初始化全局变量 df 和 df_info。 """ global df, df_info # 假设 Excel 文件路径是固定的,可以修改为你的实际路径 file_path = "你自己的文件路径" # 读取 Excel 文件并转换为 DataFrame df = pd.read_excel(file_path, sheet_name=None) df = pd.concat(df.values(), ignore_index=True) # 合并所有工作表 # 生成 DataFrame 的描述信息 df_info = generate_df_info(df) print("数据加载完成,DataFrame 信息如下:") print(df_info) # 原始 prompt_data 函数,用于生成 prompt 内容 def generate_prompt_python(content, df_info): system_prompt_t = f"""- Role: 数据分析师和编程专家 - Background: 用户需要基于数据信息和全局变量df中的pandas数据框架进行数据分析,并将统计结果存储在变量result_data中。 - Profile: 你是一位经验丰富的数据分析师,擅长使用pandas进行高效数据处理和分析。你具备深厚的编程技能和对数据的敏锐洞察力。 - Skills: 你精通Python编程语言,特别是pandas库的使用,能够编写高效、可读性强的代码来处理复杂的数据集。 - Goals: 利用pandas库对全局变量df中的数据进行查询和统计,并将结果存储在变量result_data中。 - Constrains: 必须使用pandas库进行数据处理,统计结果的变量名必须是result_data,且在未指定查询字段时需查询全部数据。 - OutputFormat: 代码块,其中包含数据处理和统计的完整代码,以及将结果赋值给result_data的语句。 - Workflow: 1. 导入pandas库并确认全局变量df的数据结构。 2. 根据用户需求,编写代码查询df中的全部或指定字段。 3. 执行统计分析,并将结果存储在变量result_data中。 - Examples: - 例子1:查询今天产油大于5吨的井 ```python import pandas as pd df['日期'] = pd.to_datetime(df['日期']) # 过滤出今天的数据 today_data = df[df['日期'] == df['日期'].max()] result_data = today_data[today_data['日油'] > 5] ``` 数据信息:{df_info} """ prompt = [ {'role': 'system', 'content': system_prompt_t}, {'role': 'user', 'content': content} ] return prompt async def fetch_streaming_response_python(prompt): """ 核心功能函数:从 Deepseek API 获取响应并以事件流的方式返回数据。 """ async with aiohttp.ClientSession() as session: async with session.post( 'https://api.deepseek.com/chat/completions', ##可以更换其他模型 headers={ "Content-Type": "application/json", "Authorization": f"Bearer {DEEPSEEK_API_KEY}" }, json={ "model": "deepseek-coder", "messages": prompt, "stream": True } ) as resp: if resp.status != 200: yield json.dumps({"error": f"Failed to fetch data: {resp.status}"}) # 逐行读取流式响应 async for line in resp.content: decoded_line = line.decode('utf-8') if decoded_line.strip(): # 过滤掉空行 yield decoded_line from io import StringIO import contextlib @app.get("/data_analysis/stream") async def stream_deepseek_data_analysis( request: Request, user_content: str = Query(..., description="The user's question or input.") ): """ 接口函数:处理 HTTP 请求,调用核心功能函数。 """ try: # 使用全局变量 df 和 df_info if df is None or df_info is None: raise HTTPException(status_code=500, detail="Data is not loaded.") # 生成 prompt prompt = generate_prompt_python(user_content, df_info) # 返回流式输出 return EventSourceResponse(fetch_streaming_response_python(prompt)) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) if __name__ == '__main__': # 启动服务前加载数据 load_data() uvicorn.run(app, host="0.0.0.0", port=7075)
http://127.0.0.1:7075/docs
没有代码解释器,可以自己写一个tool实现代码运行,返回查询结果
编写前端文件 ,测试流失输出效果: