From a7edbb743cc26d1daafbb0c48ce584b1964a5c5f Mon Sep 17 00:00:00 2001 From: zhaoqingang <zhaoqg0118@163.com> Date: 星期二, 18 二月 2025 09:43:15 +0800 Subject: [PATCH] tmp --- app/service/v2/chat.py | 77 +++++++++++++++++++++++++ main.py | 2 app/api/v2/chat.py | 35 ++++++----- app/models/base_model.py | 2 app/service/v2/app_driver/chat_base.py | 7 ++ app/config/agent_base_url.py | 3 app/service/v2/app_driver/chat_data.py | 25 +++++--- 7 files changed, 122 insertions(+), 29 deletions(-) diff --git a/app/api/v2/chat.py b/app/api/v2/chat.py index 2828bd2..819b5a6 100644 --- a/app/api/v2/chat.py +++ b/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) \ No newline at end of file + +@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) diff --git a/app/config/agent_base_url.py b/app/config/agent_base_url.py index 78c1b24..3e4c48f 100644 --- a/app/config/agent_base_url.py +++ b/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" \ No newline at end of file +DF_PING = "/console/api/workspaces" +DF_UPLOAD_FILE = "/v1/files/upload" \ No newline at end of file diff --git a/app/models/base_model.py b/app/models/base_model.py index 4f66ee2..401063f 100644 --- a/app/models/base_model.py +++ b/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() diff --git a/app/service/v2/app_driver/chat_base.py b/app/service/v2/app_driver/chat_base.py index ccd6cbd..47211d0 100644 --- a/app/service/v2/app_driver/chat_base.py +++ b/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', diff --git a/app/service/v2/app_driver/chat_data.py b/app/service/v2/app_driver/chat_data.py index 52e6883..2dd4434 100644 --- a/app/service/v2/app_driver/chat_data.py +++ b/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): diff --git a/app/service/v2/chat.py b/app/service/v2/chat.py index d2b8ff7..246b3f1 100644 --- a/app/service/v2/chat.py +++ b/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') + # 灏嗗瓧绗︿覆鍒囧垎鎴恡oken骞惰浆鎹负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)}涓猼oken") + # # 缁忚繃鍒囧垎鍚庡叡鏈�8涓猼oken + # + # # 灏唗oken 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) diff --git a/main.py b/main.py index f4497c8..3351960 100644 --- a/main.py +++ b/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__": -- Gitblit v1.8.0