Compare commits

..

No commits in common. "415e7980212dfdc8ba96e3ac9531562486de5b31" and "c4b727ab19a0c9ae31b320be68f98f6ed76df0fe" have entirely different histories.

6 changed files with 38 additions and 288 deletions

View File

@ -1,17 +1,12 @@
El sistema funciona en un docker pip install llama-index
para generar: pip install llama-index-llms-groq
pip install llama-index-embeddings-huggingface
docker build -t supertutor-app . pip install llama-parse
pip install chromadb
pip install llama-index-vector-stores-chroma
pip install llama-index-embeddings-huggingface
pip install python-fasthtml
pip install grok
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
para ejecutar:
docker run -it -p 7884:7884 --rm fastapi-app
si tienes problemas con permisos:
sudo chmod 666 /var/run/docker.sock

View File

@ -1,21 +0,0 @@
# Usar una imagen base de Python
FROM python:3.11.10-bookworm
# Establecer el directorio de trabajo en el contenedor
WORKDIR /app
# Copiar el archivo requirements.txt y otros archivos necesarios
COPY requirements.txt ./
# Instalar las dependencias de Python
RUN pip install --no-cache-dir -r requirements.txt
# Copiar todo el código de la aplicación al contenedor
COPY . .
# Expone el puerto que usará Uvicorn
EXPOSE 7884
# Especificar el comando
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7884", "--reload"]

112
main.py
View File

@ -9,23 +9,20 @@ from llama_index.core import SummaryIndex
from llama_index.llms.groq import Groq as GroqLLamaIndex from llama_index.llms.groq import Groq as GroqLLamaIndex
from chromadb import PersistentClient from chromadb import PersistentClient
from llama_index.core import Settings from llama_index.core import Settings
#from llama_index.embeddings.huggingface_api import ( from llama_index.embeddings.huggingface_api import (
# HuggingFaceInferenceAPIEmbedding, HuggingFaceInferenceAPIEmbedding,
#) )
import shutil
import chromadb import chromadb
import os import os
import threading import threading
import time import time
from llama_index.core.memory import ChatMemoryBuffer from llama_index.core.memory import ChatMemoryBuffer
import json import json
#from llama_index.llms.ollama import Ollama from llama_index.llms.ollama import Ollama
from llama_index.core.base.response.schema import Response from llama_index.core.base.response.schema import Response
from groq import Groq from groq import Groq
from fastapi import File as FileFast import shutil
from fastapi import UploadFile as UploadFileFast
from fastapi import Form as FormFast
#import shutil
pwd = os.getcwd() pwd = os.getcwd()
def extractConfig(nameModel="SystemData",relPath=os.path.join(pwd,"conf/experiment_config.json"),dataOut="keyantrophics"): def extractConfig(nameModel="SystemData",relPath=os.path.join(pwd,"conf/experiment_config.json"),dataOut="keyantrophics"):
configPath=os.path.join(os.getcwd(),relPath) configPath=os.path.join(os.getcwd(),relPath)
@ -53,8 +50,8 @@ Settings.llm = llm_localLlamma
gridlink = Link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/flexboxgrid/6.3.1/flexboxgrid.min.css", type="text/css") gridlink = Link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/flexboxgrid/6.3.1/flexboxgrid.min.css", type="text/css")
colorpico=Link(rel="stylesheet", href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.colors.min.css")
app= FastHTML(hdrs=(picolink, gridlink,colorpico)) app= FastHTML(hdrs=(picolink, gridlink))
@ -81,9 +78,9 @@ def checkInfoSources(user:str):
subdir = [Option(file.name,value="static/"+user+"/"+file.name) for file in files if (file.is_dir() and file.name!="chroma_db") ] subdir = [Option(file.name,value="static/"+user+"/"+file.name) for file in files if (file.is_dir() and file.name!="chroma_db") ]
userdata=user userdata=user
print("Cambio",userdata)
return Form( return Form(
H3("Grupo de archivos",cls="col-xs-3"), H3("Grupos de archivos",cls="col-xs-3"),
Select( Select(
*subdir,name="data",cls="col-xs-3"), *subdir,name="data",cls="col-xs-3"),
Input(id="name-db", name="collection", placeholder="Enter a collection name",cls="col-xs-4"), Input(id="name-db", name="collection", placeholder="Enter a collection name",cls="col-xs-4"),
@ -166,7 +163,7 @@ def loadCollection(data:str):
def queryPrompt(question:str): def queryPrompt(question:str):
#index=load_create_db(collection="my_collection") #index=load_create_db(collection="my_collection")
query_engine = index.as_query_engine(similarity_top_k=5,vector_store_query_mode="default",response_mode="tree_summarize") query_engine = index.as_query_engine(similarity_top_k=15,vector_store_query_mode="default",response_mode="tree_summarize")
summary_prompt = ( summary_prompt = (
"Por favor, genera un resumen completo y detallado del material dado. " "Por favor, genera un resumen completo y detallado del material dado. "
"Incluye los principales temas, argumentos y conclusiones. " "Incluye los principales temas, argumentos y conclusiones. "
@ -194,7 +191,7 @@ def queryPrompt(question:str):
response2 = query_engine.query(tematic_prompt) response2 = query_engine.query(tematic_prompt)
response3 = query_engine.query(issues_prompt) response3 = query_engine.query(issues_prompt)
response4 = query_engine.query(Question_prompt) response4 = query_engine.query(Question_prompt)
Output="<H1>Resumen</H1>"+str(response)+"<H1>Tematica</H1>"+str(response2)+"<H1>Problemas</H1>"+str(response3)+"<H1>Preguntas</H1>"+str(response4) Output="<H1>Summary</H1>"+str(response)+"<H1>Tematic</H1>"+str(response2)+"<H1>Issues</H1>"+str(response3)+"<H1>Questions</H1>"+str(response4)
return Output return Output
@ -241,6 +238,10 @@ Evaluate the coherence and accuracy of previous response to respond %s in this e
Verificate if previous context is related to the previous response, if not, say that you do not have information about that issue Verificate if previous context is related to the previous response, if not, say that you do not have information about that issue
The format of output is a json with keys 'coherencia', 'exactitud', 'relacion_con_el_contexto' and 'comentario' . The format of output is a json with keys 'coherencia', 'exactitud', 'relacion_con_el_contexto' and 'comentario' .
'coherencia', 'exactitud', 'relacion_con_el_contexto' are numeric variables with max value is 10"""%(response,ContextNodes,message) 'coherencia', 'exactitud', 'relacion_con_el_contexto' are numeric variables with max value is 10"""%(response,ContextNodes,message)
print(chat_engine.__dict__)
chat_completion = client.chat.completions.create( chat_completion = client.chat.completions.create(
# #
@ -292,7 +293,7 @@ The format of output is a json with keys 'coherencia', 'exactitud', 'relacion_co
) )
return H6(message),P(response,cls="pico-color-pink-500"),P(chat_completion.choices[0].message.content,cls="pico-color-pink-500") return P(message),P(response),P(chat_completion.choices[0].message.content)
@app.get("/SummarySources") @app.get("/SummarySources")
def SummarySources(): def SummarySources():
@ -301,7 +302,7 @@ def SummarySources():
return Form("Este es muy caro para documentos grandes y tarda mucho", return Form("Este es muy caro para documentos grandes y tarda mucho",
Select( Select(
*subdir,name="data"), *subdir,name="data"),
Input( name="query", placeholder="Dar una pregunta"), Input( name="query", placeholder="Enter a query"),
Button("Submit",type="submit"), hx_post="/SummaryMake",hx_swap="innerHTML",hx_target="#summaryR" ) Button("Submit",type="submit"), hx_post="/SummaryMake",hx_swap="innerHTML",hx_target="#summaryR" )
@app.post("/SummaryMake") @app.post("/SummaryMake")
@ -373,18 +374,18 @@ def home():
Div(Div(id="options",hx_target="this",hx_swap="outerHTML",hx_get="/listmodelactives",hx_trigger="click from:#buttonMenuuser delay:3s"),cls="col-xs-12"), Div(Div(id="options",hx_target="this",hx_swap="outerHTML",hx_get="/listmodelactives",hx_trigger="click from:#buttonMenuuser delay:3s"),cls="col-xs-12"),
Div(Div(id="Infomodel"),cls="col-xs-12"), Div(Div(id="Infomodel"),cls="col-xs-12"),
#Div("Resumen",Div(id="summary",hx_target="this",hx_swap="outerHTML",hx_get="/SummarySources",hx_trigger="click from:#buttonMenuuser"),Div(id="summaryR")), #Div("Resumen",Div(id="summary",hx_target="this",hx_swap="outerHTML",hx_get="/SummarySources",hx_trigger="click from:#buttonMenuuser"),Div(id="summaryR")),
Div(H3("Chat para preguntarle al material de estudios "), Div(
Div( Div(
Form( Form(
Input(id="question", name="message", placeholder="Dar una pregunta"), Input(id="question", name="message", placeholder="Enter a message"),
Button("Submit",type="submit"), hx_post="/chatData",hx_swap="afterend",hx_target="#questionR" ), Button("Submit",type="submit"), hx_post="/chatData",hx_swap="afterend",hx_target="#questionR" ),
Div(id="questionR") Div(id="questionR")
,id="questions"), ,id="questions"),
cls="col-xs-6"), cls="col-xs-6"),
Div(H3("Este genera informacion general del material, pero es intensivo en unso del api. No USAR."), Div(
Div( Div(
Form( Form(
Input(id="query", name="question", placeholder="Dar una pregunta"), Input(id="query", name="question", placeholder="Enter a query"),
Button("Submit",type="submit"), hx_post="/queryprompt",hx_swap="innerHTML",hx_target="#queryR" ), Button("Submit",type="submit"), hx_post="/queryprompt",hx_swap="innerHTML",hx_target="#queryR" ),
Div(id="queryR"), Div(id="queryR"),
id="query"), id="query"),
@ -393,71 +394,14 @@ def home():
)) ))
return page return page
@app.get("/fileup") # @app.post("/upload")
def fileup(): # def upload(data: UploadFile = File(...),user : str = Form(...), dir: str = Form(...)):
return Div( # filename="static/"+user+dir+data.filename
P('Upload data Super tutor'),
Div(H2("Subir Archivos"),Form(
Input(type='file', name='file',cls="col-xs-3"),
Input( name='dir',placeholder="Enter a directory",cls="col-xs-2"),
Input( name='user',placeholder="Enter a user",cls="col-xs-2"),
Button('Upload', type='submit',cls="col-xs-4"),
hx_post="/upload",
hx_target="#info",
hx_swap="innerHTML",
enctype="multipart/form-data",
),cls="col-xs-12"),
Div(H2("Crear Usuario"),Form(
Input( name='user',placeholder="Enter a user",cls="col-xs-7"),
Button('Upload', type='submit',cls="col-xs-5"),
hx_post="/createuser",
hx_target="#info",
hx_swap="innerHTML",
enctype="multipart/form-data",
),cls="col-xs-12"),
Div(H2("Crear grupo de Archivos"),Form(
Input( name='dir',placeholder="Enter a directory",cls="col-xs-4"),
Input( name='user',placeholder="Enter a user",cls="col-xs-3"),
Button('Upload', type='submit',cls="col-xs-5"),
hx_post="/creategroup",
hx_target="#info",
hx_swap="innerHTML",
enctype="multipart/form-data",
),cls="col-xs-12"),
Div(id="info")
# with open(f"{filename}", "wb") as buffer:
# shutil.copyfileobj(data.file, buffer)
) # app.mount("/static", StaticFiles(directory="static"), name="static")
@app.post("/upload")
def upload(file: UploadFile,dir : str = Form(...),user : str = Form(...)):
filenameB="static/"+user+"/"+dir+"/"+file.filename
pathB="static/"+user+"/"+dir
if not os.path.exists(pathB):
os.makedirs(pathB)
if not os.path.exists(filenameB):
with open(f"{filenameB}", "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
return P("Se ha subido %s"%(filenameB))
@app.post("/createuser")
def createuser(user : str = Form(...)):
pathB="static/"+user
if not os.path.exists(pathB):
os.makedirs(pathB)
return P("Se ha creado %s"%(pathB))
@app.post("/creategroup")
def createuser(user : str = Form(...),dir : str = Form(...)):
pathB="static/"+user+"/"+dir
if not os.path.exists(pathB):
os.makedirs(pathB)
return P("Se ha creado %s"%(pathB))
app.mount("/static", StaticFiles(directory="static"), name="static")

View File

@ -1,146 +0,0 @@
aiohappyeyeballs==2.4.3
aiohttp==3.10.9
aiosignal==1.3.1
annotated-types==0.7.0
anyio==4.6.0
asgiref==3.8.1
attrs==24.2.0
backoff==2.2.1
bcrypt==4.2.0
beautifulsoup4==4.12.3
build==1.2.2.post1
cachetools==5.5.0
certifi==2024.8.30
charset-normalizer==3.3.2
chroma-hnswlib==0.7.6
chromadb==0.5.7
click==8.1.7
coloredlogs==15.0.1
dataclasses-json==0.6.7
Deprecated==1.2.14
dirtyjson==1.0.8
distro==1.9.0
durationpy==0.9
fastapi==0.115.0
fastcore==1.7.11
fastlite==0.0.11
filelock==3.16.1
flatbuffers==24.3.25
frozenlist==1.4.1
fsspec==2024.9.0
google-auth==2.35.0
googleapis-common-protos==1.65.0
greenlet==3.1.1
groq==0.11.0
grpcio==1.66.2
h11==0.14.0
httpcore==1.0.6
httptools==0.6.1
httpx==0.27.2
huggingface-hub==0.25.1
humanfriendly==10.0
idna==3.10
importlib_metadata==8.4.0
importlib_resources==6.4.5
itsdangerous==2.2.0
jiter==0.6.1
joblib==1.4.2
kubernetes==31.0.0
llama-cloud==0.1.2
llama-index==0.11.13
llama-index-agent-openai==0.3.4
llama-index-cli==0.3.1
llama-index-core==0.11.16
llama-index-embeddings-huggingface==0.3.1
llama-index-embeddings-openai==0.2.5
llama-index-indices-managed-llama-cloud==0.4.0
llama-index-legacy==0.9.48.post3
llama-index-llms-openai==0.2.12
llama-index-llms-groq==0.2.0
llama-index-multi-modal-llms-openai==0.2.2
llama-index-program-openai==0.2.0
llama-index-question-gen-openai==0.2.0
llama-index-readers-file==0.2.2
llama-index-readers-llama-parse==0.3.0
llama-index-vector-stores-chroma==0.2.0
llama-parse==0.5.7
markdown-it-py==3.0.0
marshmallow==3.22.0
mdurl==0.1.2
mmh3==5.0.1
monotonic==1.6
mpmath==1.3.0
multidict==6.1.0
mypy-extensions==1.0.0
nest-asyncio==1.6.0
networkx==3.3
nltk==3.9.1
numpy==1.26.4
oauthlib==3.2.2
onnxruntime==1.19.2
openai==1.51.1
opentelemetry-api==1.27.0
opentelemetry-exporter-otlp-proto-common==1.27.0
opentelemetry-exporter-otlp-proto-grpc==1.27.0
opentelemetry-instrumentation==0.48b0
opentelemetry-instrumentation-asgi==0.48b0
opentelemetry-instrumentation-fastapi==0.48b0
opentelemetry-proto==1.27.0
opentelemetry-sdk==1.27.0
opentelemetry-semantic-conventions==0.48b0
opentelemetry-util-http==0.48b0
orjson==3.10.7
overrides==7.7.0
packaging==24.1
pandas==2.2.3
pillow==10.4.0
posthog==3.7.0
propcache==0.2.0
protobuf==4.25.5
pyasn1==0.6.1
pyasn1_modules==0.4.1
pydantic==2.9.2
pydantic_core==2.23.4
Pygments==2.18.0
pypdf==4.3.1
PyPika==0.48.9
pyproject_hooks==1.2.0
pysqlite3-binary==0.5.3.post1
pysqlite3-binary==0.5.3.post1
python-dateutil==2.9.0.post0
python-dotenv==1.0.1
python-fasthtml==0.6.7
python-multipart==0.0.12
pytz==2024.2
PyYAML==6.0.2
regex==2024.9.11
requests==2.32.3
requests-oauthlib==2.0.0
rich==13.9.2
rsa==4.9
shellingham==1.5.4
six==1.16.0
sniffio==1.3.1
soupsieve==2.6
SQLAlchemy==2.0.35
sqlite-minutils==3.37.0.post3
starlette==0.38.6
striprtf==0.0.26
sympy==1.13.3
tenacity==8.5.0
tiktoken==0.8.0
tokenizers==0.20.0
tqdm==4.66.5
typer==0.12.5
typing-inspect==0.9.0
typing_extensions==4.12.2
tzdata==2024.2
urllib3==2.2.3
uvicorn==0.31.0
uvloop==0.20.0
watchfiles==0.24.0
websocket-client==1.8.0
websockets==13.1
wrapt==1.16.0
yarl==1.14.0
zipp==3.20.2

1
run.sh
View File

@ -1 +0,0 @@
docker run -it -p 7884:7884 --rm fastapi-app

View File

@ -1,21 +0,0 @@
# Usar una imagen base de Python
FROM python:3.11.10-bookworm
# Establecer el directorio de trabajo en el contenedor
WORKDIR /app
# Copiar el archivo requirements.txt y otros archivos necesarios
COPY requirements.txt ./
# Instalar las dependencias de Python
RUN pip install --no-cache-dir -r requirements.txt
# Copiar todo el código de la aplicación al contenedor
COPY . .
# Expone el puerto que usará Uvicorn
EXPOSE 7884
# Especificar el comando
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7884", "--reload"]