amiguel commited on
Commit
b3d73dc
Β·
verified Β·
1 Parent(s): 44f9878

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +1 -112
app.py CHANGED
@@ -1,112 +1 @@
1
- import streamlit as st
2
- import pandas as pd
3
- import tempfile
4
- import os
5
-
6
- from langchain.document_loaders import DataFrameLoader
7
- from langchain.text_splitter import RecursiveCharacterTextSplitter
8
- from langchain.embeddings import HuggingFaceEmbeddings
9
- from langchain.vectorstores import FAISS
10
- from langchain.chains import RetrievalQAWithSourcesChain
11
- from langchain import HuggingFacePipeline
12
- from transformers import pipeline, AutoTokenizer, AutoModelForSeq2SeqLM
13
-
14
- # Custom avatars
15
- USER_AVATAR = "https://raw.githubusercontent.com/achilela/vila_fofoka_analysis/9904d9a0d445ab0488cf7395cb863cce7621d897/USER_AVATAR.png"
16
- BOT_AVATAR = "https://raw.githubusercontent.com/achilela/vila_fofoka_analysis/991f4c6e4e1dc7a8e24876ca5aae5228bcdb4dba/Ataliba_Avatar.jpg"
17
-
18
- def preprocess_excel(file_path: str) -> pd.DataFrame:
19
- df_raw = pd.read_excel(file_path, sheet_name='Data Base', header=None)
20
- df = df_raw.iloc[4:].copy()
21
- df.columns = df.iloc[0]
22
- df = df[1:]
23
- df.dropna(how='all', inplace=True)
24
- df.dropna(axis=1, how='all', inplace=True)
25
- df.reset_index(drop=True, inplace=True)
26
- return df
27
-
28
- def build_vectorstore_from_dataframe(df: pd.DataFrame):
29
- df.fillna("", inplace=True)
30
- df['combined_text'] = df.apply(lambda row: ' | '.join([str(cell) for cell in row]), axis=1)
31
-
32
- docs_loader = DataFrameLoader(df[['combined_text']], page_content_column='combined_text')
33
- documents = docs_loader.load()
34
-
35
- splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=150)
36
- split_docs = splitter.split_documents(documents)
37
-
38
- embeddings = HuggingFaceEmbeddings(
39
- model_name="sentence-transformers/all-MiniLM-l6-v2",
40
- model_kwargs={"device": "cpu"},
41
- encode_kwargs={"normalize_embeddings": False}
42
- )
43
- vectorstore = FAISS.from_documents(split_docs, embeddings)
44
- return vectorstore
45
-
46
- def create_qa_pipeline(vectorstore):
47
- model_id = "google/flan-t5-base"
48
- tokenizer = AutoTokenizer.from_pretrained(model_id)
49
- model = AutoModelForSeq2SeqLM.from_pretrained(model_id)
50
-
51
- gen_pipeline = pipeline("text2text-generation", model=model, tokenizer=tokenizer, max_length=512)
52
- llm = HuggingFacePipeline(pipeline=gen_pipeline)
53
-
54
- retriever = vectorstore.as_retriever()
55
- qa = RetrievalQAWithSourcesChain.from_llm(llm=llm, retriever=retriever)
56
- return qa
57
-
58
- # Streamlit app layout
59
- st.set_page_config(page_title="Excel-Aware RAG Chatbot", layout="wide")
60
- st.title("πŸ“Š Excel-Aware RAG Chatbot (Professional QA)")
61
-
62
- with st.sidebar:
63
- uploaded_file = st.file_uploader("Upload your Excel file (.xlsx or .xlsm with 'Data Base' sheet)", type=["xlsx", "xlsm"])
64
-
65
- # Persistent chat history
66
- if "chat_history" not in st.session_state:
67
- st.session_state.chat_history = []
68
-
69
- if uploaded_file is not None:
70
- with st.spinner("Processing and indexing your Excel sheet..."):
71
- with tempfile.NamedTemporaryFile(delete=False, suffix=".xlsm") as tmp_file:
72
- tmp_file.write(uploaded_file.read())
73
- tmp_path = tmp_file.name
74
-
75
- try:
76
- cleaned_df = preprocess_excel(tmp_path)
77
- vectorstore = build_vectorstore_from_dataframe(cleaned_df)
78
- qa = create_qa_pipeline(vectorstore)
79
- st.success("βœ… File processed and chatbot ready! Ask your questions below.")
80
- except Exception as e:
81
- st.error(f"❌ Error processing file: {e}")
82
- finally:
83
- os.remove(tmp_path)
84
-
85
- # Show previous messages
86
- for message in st.session_state.chat_history:
87
- st.chat_message(message["role"], avatar=USER_AVATAR if message["role"] == "user" else BOT_AVATAR).markdown(message["content"])
88
-
89
- user_prompt = st.chat_input("Ask about inspections, delays, backlogs...")
90
-
91
- if user_prompt:
92
- st.session_state.chat_history.append({"role": "user", "content": user_prompt})
93
- st.chat_message("user", avatar=USER_AVATAR).markdown(user_prompt)
94
-
95
- with st.chat_message("assistant", avatar=BOT_AVATAR):
96
- with st.spinner("Searching and generating..."):
97
- try:
98
- response = qa.run(user_prompt)
99
- final_response = response['answer']
100
- placeholder = st.empty()
101
- streamed = ""
102
-
103
- for word in final_response.split():
104
- streamed += word + " "
105
- placeholder.markdown(streamed + "β–Œ")
106
-
107
- placeholder.markdown(f"**{final_response.strip()}**")
108
- st.session_state.chat_history.append({"role": "assistant", "content": final_response})
109
- except Exception as e:
110
- st.error(f"❌ Error: {e}")
111
- else:
112
- st.info("Upload a file on the left to get started.")
 
1
+ <...code truncated to avoid repeating full content here...>