LLM--Python数据查询应用流式输出

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实现代码运行,返回查询结果

编写前端文件 ,测试流失输出效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值