mirror of
https://github.com/BoardWare-Genius/jarvis-models.git
synced 2025-12-13 16:53:24 +00:00
146 lines
5.9 KiB
Python
Executable File
146 lines
5.9 KiB
Python
Executable File
from typing import Any, Coroutine
|
||
|
||
from fastapi import Request, Response, status
|
||
from fastapi.responses import JSONResponse
|
||
from .blackbox import Blackbox
|
||
|
||
import requests
|
||
import json
|
||
|
||
from langchain_community.document_loaders.csv_loader import CSVLoader
|
||
from langchain_community.document_loaders import PyPDFLoader, DirectoryLoader, TextLoader, UnstructuredHTMLLoader, JSONLoader, Docx2txtLoader, UnstructuredExcelLoader
|
||
from langchain_community.vectorstores import Chroma
|
||
from langchain.text_splitter import RecursiveCharacterTextSplitter, CharacterTextSplitter
|
||
from langchain_community.embeddings.sentence_transformer import SentenceTransformerEmbeddings
|
||
import chromadb
|
||
|
||
import os
|
||
import tempfile
|
||
|
||
from ..utils import chroma_setting
|
||
|
||
from injector import singleton
|
||
@singleton
|
||
class ChromaUpsert(Blackbox):
|
||
|
||
def __init__(self, *args, **kwargs) -> None:
|
||
# config = read_yaml(args[0])
|
||
# load embedding model
|
||
self.embedding_model = SentenceTransformerEmbeddings(model_name='/model/Weight/BAAI/bge-small-en-v1.5', model_kwargs={"device": "cuda"})
|
||
# load chroma db
|
||
self.client = chromadb.HttpClient(host='10.6.82.192', port=8000)
|
||
|
||
def __call__(self, *args, **kwargs):
|
||
return self.processing(*args, **kwargs)
|
||
|
||
def valid(self, *args, **kwargs) -> bool:
|
||
data = args[0]
|
||
return isinstance(data, list)
|
||
|
||
def processing(self, collection_id, file, string, context, setting: chroma_setting) -> str:
|
||
# 用户的操作历史
|
||
if context is None:
|
||
context = []
|
||
|
||
context = [
|
||
{
|
||
"collection_id": "123",
|
||
"action": "query",
|
||
"content": "你吃饭了吗",
|
||
"answer": "吃了",
|
||
},
|
||
{
|
||
"collection_id": "123",
|
||
"action": "upsert",
|
||
"content": "file_name or string",
|
||
"answer": "collection 123 has 12472 documents. /tmp/Cheap and Quick:Efficient Vision-Language Instruction Tuning for Large Language Models.pdf ids is 0~111",
|
||
},
|
||
]
|
||
|
||
if collection_id is None and setting.ChromaSetting.collection_ids[0] != []:
|
||
collection_id = setting.ChromaSetting.collection_ids[0]
|
||
else:
|
||
collection_id = "123"
|
||
|
||
if file is not None:
|
||
file_type = file.split(".")[-1]
|
||
print("file_type: ",file_type)
|
||
if file_type == "pdf":
|
||
loader = PyPDFLoader(file)
|
||
elif file_type == "txt":
|
||
loader = TextLoader(file)
|
||
elif file_type == "csv":
|
||
loader = CSVLoader(file)
|
||
elif file_type == "html":
|
||
loader = UnstructuredHTMLLoader(file)
|
||
elif file_type == "json":
|
||
loader = JSONLoader(file, jq_schema='.', text_content=False)
|
||
elif file_type == "docx":
|
||
loader = Docx2txtLoader(file)
|
||
elif file_type == "xlsx":
|
||
loader = UnstructuredExcelLoader(file)
|
||
|
||
|
||
documents = loader.load()
|
||
text_splitter = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=0)
|
||
|
||
docs = text_splitter.split_documents(documents)
|
||
|
||
ids = [str(file)+str(i) for i in range(len(docs))]
|
||
|
||
Chroma.from_documents(documents=docs, embedding=self.embedding_model, ids=ids, collection_name=collection_id, client=self.client)
|
||
|
||
collection_number = self.client.get_collection(collection_id).count()
|
||
response_file = f"collection {collection_id} has {collection_number} documents. {file} ids is 0~{len(docs)-1}"
|
||
|
||
if string is not None:
|
||
# 生成一个新的id ids_string: 1
|
||
# ids = setting.ChromaSetting.string_ids[0] + 1
|
||
ids = "1"
|
||
|
||
Chroma.from_texts(texts=[string], embedding=self.embedding_model, ids=[ids], collection_name=collection_id, client=self.client)
|
||
|
||
|
||
collection_number = self.client.get_collection(collection_id).count()
|
||
response_string = f"collection {collection_id} has {collection_number} documents. {string} ids is {ids}"
|
||
|
||
|
||
if file is not None and string is not None:
|
||
return response_file + " \n and " + response_string
|
||
elif file is not None and string is None:
|
||
return response_file
|
||
elif file is None and string is not None:
|
||
return response_string
|
||
|
||
|
||
|
||
async def fast_api_handler(self, request: Request) -> Response:
|
||
|
||
user_collection_id = (await request.form()).get("collection_id")
|
||
user_file = (await request.form()).get("file")
|
||
user_string = (await request.form()).get("string")
|
||
user_context = (await request.form()).get("context")
|
||
user_setting = (await request.form()).get("setting")
|
||
|
||
if user_collection_id is None and user_setting["collections"] == []:
|
||
return JSONResponse(content={"error": "The first creation requires a collection id"}, status_code=status.HTTP_400_BAD_REQUEST)
|
||
|
||
if user_file is None and user_string is None:
|
||
return JSONResponse(content={"error": "file or string is required"}, status_code=status.HTTP_400_BAD_REQUEST)
|
||
|
||
if user_file is not None:
|
||
pdf_bytes = await user_file.read()
|
||
|
||
custom_filename = user_file.filename
|
||
# 获取系统的临时目录路径
|
||
safe_filename = os.path.join(tempfile.gettempdir(), os.path.basename(custom_filename))
|
||
|
||
with open(safe_filename, "wb") as f:
|
||
f.write(pdf_bytes)
|
||
else:
|
||
safe_filename = None
|
||
|
||
|
||
return JSONResponse(
|
||
content={"response": self.processing(user_collection_id, safe_filename, user_string, user_context, user_setting)},
|
||
status_code=status.HTTP_200_OK) |