tmp
zhaoqingang
2025-02-18 a7edbb743cc26d1daafbb0c48ce584b1964a5c5f
tmp
7个文件已修改
151 ■■■■ 已修改文件
app/api/v2/chat.py 35 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/config/agent_base_url.py 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/models/base_model.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/service/v2/app_driver/chat_base.py 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/service/v2/app_driver/chat_data.py 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/service/v2/chat.py 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/api/v2/chat.py
@@ -1,7 +1,8 @@
import json
import uuid
from typing import List
from fastapi import Depends, APIRouter
from fastapi import Depends, APIRouter, File, UploadFile
from sqlalchemy.orm import Session
from starlette.responses import StreamingResponse, Response
@@ -12,12 +13,12 @@
from app.models.base_model import get_db
from app.models.v2.session_model import ChatData
from app.service.v2.chat import service_chat_dialog, get_chat_info, service_chat_basic, \
    service_chat_workflow, service_chat_parameters, service_chat_sessions
    service_chat_workflow, service_chat_parameters, service_chat_sessions, service_chat_upload
chat_router_v2 = APIRouter()
# 对话
@chat_router_v2.post("/{chatId}/dialog")
@chat_router_v2.post("/chat/{chatId}/completions")
async def api_chat_dialog(chatId:str, dialog: ChatData, current_user: UserModel = Depends(get_current_user),db: Session = Depends(get_db)): #  current_user: UserModel = Depends(get_current_user)
    chat_info = await get_chat_info(db, chatId)
    if not chat_info:
@@ -42,7 +43,7 @@
    return StreamingResponse(service_chat_dialog(db, chatId, dialog.query, session_id, current_user.id, chat_info.mode),
                             media_type="text/event-stream")
@chat_router_v2.post("/{chatId}/agent")
@chat_router_v2.post("/agent/{chatId}/completions")
async def api_chat_dialog(chatId:str, dialog: ChatData, current_user: UserModel = Depends(get_current_user),db: Session = Depends(get_db)): #  current_user: UserModel = Depends(get_current_user)
    chat_info = await get_chat_info(db, chatId)
    if not chat_info:
@@ -57,7 +58,7 @@
                             media_type="text/event-stream")
@chat_router_v2.post("/{chatId}/workflow")
@chat_router_v2.post("/workflow/{chatId}/completions")
async def api_chat_dialog(chatId:str, dialog: ChatData, current_user: UserModel = Depends(get_current_user), db: Session = Depends(get_db)): #  current_user: UserModel = Depends(get_current_user)
    chat_info = await get_chat_info(db, chatId)
    if not chat_info:
@@ -72,7 +73,7 @@
                             media_type="text/event-stream")
@chat_router_v2.post("/{chatId}/basic")
@chat_router_v2.post("/complex/{chatId}/completions")
async def api_chat_dialog(chatId:str, dialog: ChatData, current_user: UserModel = Depends(get_current_user), db: Session = Depends(get_db)): #  current_user: UserModel = Depends(get_current_user)
    chat_info = await get_chat_info(db, chatId)
    if not chat_info:
@@ -90,19 +91,21 @@
@chat_router_v2.get("/{chatId}/parameters")
async def api_chat_parameters(chatId:str, db: Session = Depends(get_db)): #  current_user: UserModel = Depends(get_current_user)
@chat_router_v2.get("/chat/{chatId}/parameters")
async def api_chat_parameters(chatId:str, current_user: UserModel = Depends(get_current_user), db: Session = Depends(get_db)): #  current_user: UserModel = Depends(get_current_user)
    status_code = http_200
    data = await service_chat_parameters(db, chatId, 1)
    data = await service_chat_parameters(db, chatId, current_user.id)
    if not data:
        status_code = http_400
        data = "{}"
    return Response(data, media_type="application/json", status_code=status_code)
# @chat_router_v2.get("/{chatId}/parameters")
# async def api_chat_parameters(chatId:str, db: Session = Depends(get_db)): #  current_user: UserModel = Depends(get_current_user)
#     status_code = http_200
#     data = await service_chat_parameters(db, chatId, 1)
#     if not data:
#         status_code = http_400
#     return Response(json.dumps(data), media_type="application/json", status_code=status_code)
@chat_router_v2.post("/{chatId}/upload")
async def api_chat_upload(chatId:str, file: List[UploadFile] = File(...), current_user: UserModel = Depends(get_current_user), db: Session = Depends(get_db)): #  current_user: UserModel = Depends(get_current_user)
    status_code = http_200
    data = await service_chat_upload(db, chatId, file, current_user.id)
    if not data:
        status_code = http_400
        data = "{}"
    return Response(data, media_type="application/json", status_code=status_code)
app/config/agent_base_url.py
@@ -13,4 +13,5 @@
DF_CHAT_PARAMETERS= "/v1/parameters"
DF_CHAT_API_KEY= "/console/api/apps/{}/api-keys"
DF_USER_LOGIN= "/console/api/login"
DF_PING = "/console/api/workspaces"
DF_PING = "/console/api/workspaces"
DF_UPLOAD_FILE = "/v1/files/upload"
app/models/base_model.py
@@ -7,7 +7,7 @@
from app.config.config import settings
DATABASE_URL =  settings.database_url
engine = create_engine(DATABASE_URL, pool_size=20, max_overflow=50)
engine = create_engine(DATABASE_URL, pool_size=20, max_overflow=50, pool_recycle=3600)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
app/service/v2/app_driver/chat_base.py
@@ -32,6 +32,13 @@
            return response
    @staticmethod
    async def http_upload_file(url, data, files, headers, timeout=300):
        async with httpx.AsyncClient(timeout=timeout) as client:
            response = await client.post(url, headers=headers, files=files, data=data)
            return response
    @staticmethod
    async def get_headers(token):
        return {
            'Content-Type': 'application/json',
app/service/v2/app_driver/chat_data.py
@@ -16,15 +16,6 @@
        else:
            return {}
    async def chat_ping(self, url, params, headers):
        res = await self.http_get(url, params, headers)
        if res.status_code != 200:
            return 0
        if res.json().get("code") == "unauthorized" or res.json().get("code") == 401:
            return 0
        return 200
    async def chat_post(self, url, data, headers):
        res = await self.http_post(url, data, headers)
@@ -32,6 +23,14 @@
            return res.json()
        else:
            return {}
    async def chat_ping(self, url, params, headers):
        res = await self.http_get(url, params, headers)
        if res.status_code != 200:
            return 0
        if res.json().get("code") == "unauthorized" or res.json().get("code") == 401:
            return 0
        return 200
    async def chat_login(self, url, data, headers):
@@ -45,6 +44,14 @@
        else:
            return {}
    async def chat_upload(self, url, files, data,  headers):
        res = await self.http_upload_file(url, headers=headers, files=files, data=data)
        if res.status_code == 200 or res.status_code == 201:
            return res.json()
        else:
            return {}
    @staticmethod
    async def password_encrypt(password):
app/service/v2/chat.py
@@ -1,8 +1,11 @@
import io
import json
import fitz
from Log import logger
from app.config.agent_base_url import RG_CHAT_DIALOG, DF_CHAT_AGENT, DF_CHAT_PARAMETERS, RG_CHAT_SESSIONS, \
    DF_CHAT_WORKFLOW
    DF_CHAT_WORKFLOW, DF_UPLOAD_FILE
from app.config.config import settings
from app.config.const import *
from app.models import DialogModel, ApiTokenModel, UserTokenModel
@@ -11,6 +14,8 @@
from app.service.v2.app_driver.chat_data import ChatBaseApply
from app.service.v2.app_driver.chat_dialog import ChatDialog
from app.service.v2.app_driver.chat_workflow import ChatWorkflow
from docx import Document
from dashscope import get_tokenizer  # dashscope版本 >= 1.14.0
async def update_session_log(db, session_id: str, message: dict, conversation_id: str):
@@ -243,3 +248,73 @@
    url = settings.fwr_base_url + RG_CHAT_SESSIONS.format(chat_id)
    chat = ChatDialog()
    return await chat.chat_sessions(url, {"name": name}, await chat.get_headers(token))
async def service_chat_upload(db, chat_id, file, user_id):
    files = []
    token = await get_chat_token(db, chat_id)
    if not token:
        return files
    url = settings.dify_base_url + DF_UPLOAD_FILE
    chat = ChatBaseApply()
    for f in file:
        try:
            file_content = await f.read()
            file_upload = await chat.chat_upload(url, {"file": (f.filename, file_content)}, {"user": str(user_id)},
                                                 {'Authorization': f'Bearer {token}'})
            try:
                tokens = await read_file(file_content, f.filename, f.content_type)
                file_upload["tokens"] = tokens
            except:
                ...
            files.append(file_upload)
        except Exception as e:
            logger.error(e)
    return json.dumps(files) if files else ""
async def get_str_token(input_str):
    # 获取tokenizer对象,目前只支持通义千问系列模型
    tokenizer = get_tokenizer('qwen-turbo')
    # 将字符串切分成token并转换为token id
    tokens = tokenizer.encode(input_str)
    # print(f"经过切分后的token id为:{tokens}。")
    # # 经过切分后的token id为: [31935, 64559, 99320, 56007, 100629, 104795, 99788, 1773]
    # print(f"经过切分后共有{len(tokens)}个token")
    # # 经过切分后共有8个token
    #
    # # 将token id转化为字符串并打印出来
    # for i in range(len(tokens)):
    #     print(f"token id为{tokens[i]}对应的字符串为:{tokenizer.decode(tokens[i])}")
    return len(tokens)
async def read_pdf(pdf_stream):
    text = ""
    with fitz.open(stream=pdf_stream, filetype="pdf") as pdf_document:
        for page in pdf_document:
            text += page.get_text()
    return text
async def read_word(word_stream):
    # 使用 python-docx 打开 Word 文件流
    doc = Document(io.BytesIO(word_stream))
    # 提取每个段落的文本
    text = ""
    for para in doc.paragraphs:
        text += para.text
    return text
async def read_file(file, filename, content_type):
    text = ""
    if content_type == "application/pdf" or filename.endswith('.pdf'):
        # 提取 PDF 内容
        text = await read_pdf(file)
    elif content_type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document" or filename.endswith(
            '.docx'):
        text = await read_word(file)
    return await get_str_token(text)
main.py
@@ -91,7 +91,7 @@
app.include_router(canvas_router, prefix='/api/canvas', tags=["canvas"])
app.include_router(label_router, prefix='/api/label', tags=["label"])
app.include_router(public_api, prefix='/v1/api', tags=["public_api"])
app.include_router(chat_router_v2, prefix='/api/v1/chat', tags=["chat1"])
app.include_router(chat_router_v2, prefix='/api/v1', tags=["chat1"])
app.mount("/static", StaticFiles(directory="app/images"), name="static")
if __name__ == "__main__":