jake2004 commited on
Commit
fc208c7
Β·
verified Β·
1 Parent(s): c1dc179

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +73 -58
app.py CHANGED
@@ -4,16 +4,16 @@ import os
4
  import streamlit as st
5
  import pandas as pd
6
  import openpyxl
7
- import torch
8
  import faiss
 
9
  from reportlab.lib.pagesizes import letter
10
  from reportlab.pdfgen import canvas
11
- from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
12
  from sentence_transformers import SentenceTransformer
 
13
 
14
  # βœ… Streamlit UI Setup
15
  st.set_page_config(page_title="AI-Powered Timetable", layout="wide")
16
- st.markdown("<h1 style='text-align: center; color: #4CAF50;'>πŸ“… AI-Powered Timetable with RAG</h1>", unsafe_allow_html=True)
17
 
18
  # βœ… API Key Input
19
  st.sidebar.markdown("## πŸ”‘ Enter Hugging Face API Key")
@@ -21,10 +21,10 @@ hf_api_key = st.sidebar.text_input("API Key", type="password")
21
 
22
  # βœ… File Upload Section
23
  st.sidebar.markdown("## πŸ“‚ Upload Your Timetable Files")
24
- uploaded_master = st.sidebar.file_uploader("Upload Master Timetable", type=["xlsx", "pdf"])
25
- uploaded_lab = st.sidebar.file_uploader("Upload Lab Timetable", type=["xlsx", "pdf"])
26
- uploaded_classroom = st.sidebar.file_uploader("Upload Classroom Timetable", type=["xlsx", "pdf"])
27
- uploaded_individual = st.sidebar.file_uploader("Upload Individual Timetable", type=["xlsx", "pdf"])
28
 
29
  uploaded_files = {
30
  "Master Timetable": uploaded_master,
@@ -33,51 +33,58 @@ uploaded_files = {
33
  "Individual Timetable": uploaded_individual,
34
  }
35
 
36
- # βœ… Load Timetable Data
37
  def load_timetable(file):
38
  if not file:
39
  return None
40
- if file.name.endswith('.xlsx'):
41
- wb = openpyxl.load_workbook(file)
42
- sheet = wb.active
43
- return [row for row in sheet.iter_rows(values_only=True)]
44
- elif file.name.endswith('.pdf'):
45
- import PyPDF2
46
- pdf_reader = PyPDF2.PdfReader(file)
47
- text = ""
48
- for page in pdf_reader.pages:
49
- text += page.extract_text() + "\n"
50
- return text
51
-
52
- # βœ… Extract and Store Data
53
  rag_data = {}
54
  for name, file in uploaded_files.items():
55
  if file:
56
- rag_data[name] = load_timetable(file)
 
 
57
 
58
- # βœ… Encode Timetable Data with Sentence Embeddings
59
- embedder = SentenceTransformer("all-MiniLM-L6-v2")
60
  data_texts = ["\n".join(map(str, data)) for data in rag_data.values() if data]
 
 
 
 
 
 
61
  data_embeddings = embedder.encode(data_texts, convert_to_tensor=True)
62
 
63
- # βœ… Create FAISS Vector Store
64
- dimension = data_embeddings.shape[1]
 
 
 
65
  index = faiss.IndexFlatL2(dimension)
66
  index.add(data_embeddings.cpu().numpy())
67
 
68
- # βœ… Retrieve Relevant Data using RAG
69
- def retrieve_data(query):
70
- query_embedding = embedder.encode([query], convert_to_tensor=True)
71
- D, I = index.search(query_embedding.cpu().numpy(), k=1)
72
- return data_texts[I[0][0]] if I[0][0] < len(data_texts) else "No relevant data found."
 
 
73
 
74
- # βœ… Ask LLaMA-3-8B with RAG Context
75
  def ask_llama_api(query):
76
  if not hf_api_key:
77
  return "Error: Please enter your API key."
78
-
79
- context = retrieve_data(query) # Get relevant timetable data
80
- final_query = f"Based on the timetable data:\n{context}\nAnswer this query: {query}"
81
 
82
  url = "https://api-inference.huggingface.co/v1/chat/completions"
83
  headers = {
@@ -86,7 +93,7 @@ def ask_llama_api(query):
86
  }
87
  payload = {
88
  "model": "meta-llama/Meta-Llama-3-8B",
89
- "messages": [{"role": "user", "content": final_query}],
90
  "max_tokens": 500
91
  }
92
 
@@ -96,11 +103,37 @@ def ask_llama_api(query):
96
  else:
97
  return f"API Error: {response.status_code} - {response.text}"
98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  # βœ… AI Query Section
100
  st.markdown("## πŸ€– Ask LLaMA-3 AI About Your Timetable")
101
  user_query = st.text_input("Type your question here (e.g., 'Who is free at 10 AM on Monday?')")
102
 
103
- if st.button("Ask AI via RAG"):
104
  ai_response = ask_llama_api(user_query)
105
  st.write("🧠 **LLaMA-3 AI Suggests:**", ai_response)
106
 
@@ -109,7 +142,7 @@ st.markdown("## πŸ“… Auto-Schedule Missing Timetable Slots")
109
  selected_file = st.selectbox("Choose a timetable file to auto-fill missing slots:", list(uploaded_files.keys()))
110
 
111
  if st.button("Auto-Schedule"):
112
- result = retrieve_data(selected_file)
113
  st.write("βœ…", result)
114
 
115
  # βœ… Display Uploaded Timetables
@@ -117,24 +150,6 @@ st.markdown("## πŸ“œ View Uploaded Timetables")
117
 
118
  for name, file in uploaded_files.items():
119
  if file:
120
- df = pd.read_excel(file) if file.name.endswith(".xlsx") else None
121
  st.markdown(f"### {name}")
122
- if df is not None:
123
- st.dataframe(df)
124
- else:
125
- st.text(rag_data[name])
126
-
127
- # βœ… PDF Export Feature
128
- st.sidebar.markdown("## πŸ“„ Export AI Responses to PDF")
129
- if st.sidebar.button("Export as PDF"):
130
- c = canvas.Canvas("Timetable_Responses.pdf", pagesize=letter)
131
- c.drawString(100, 750, "AI-Powered Timetable Responses")
132
- y = 720
133
- for query, response in [("Example Query", "Example Response")]: # Replace with actual
134
- c.drawString(50, y, f"Q: {query}")
135
- y -= 20
136
- c.drawString(70, y, f"A: {response}")
137
- y -= 30
138
- c.save()
139
- st.sidebar.success("PDF Exported: Timetable_Responses.pdf")
140
-
 
4
  import streamlit as st
5
  import pandas as pd
6
  import openpyxl
 
7
  import faiss
8
+ import torch
9
  from reportlab.lib.pagesizes import letter
10
  from reportlab.pdfgen import canvas
 
11
  from sentence_transformers import SentenceTransformer
12
+ from transformers import AutoModelForCausalLM, AutoTokenizer
13
 
14
  # βœ… Streamlit UI Setup
15
  st.set_page_config(page_title="AI-Powered Timetable", layout="wide")
16
+ st.markdown("<h1 style='text-align: center; color: #4CAF50;'>πŸ“… AI-Powered Timetable</h1>", unsafe_allow_html=True)
17
 
18
  # βœ… API Key Input
19
  st.sidebar.markdown("## πŸ”‘ Enter Hugging Face API Key")
 
21
 
22
  # βœ… File Upload Section
23
  st.sidebar.markdown("## πŸ“‚ Upload Your Timetable Files")
24
+ uploaded_master = st.sidebar.file_uploader("Upload Master Timetable", type=["xlsx"])
25
+ uploaded_lab = st.sidebar.file_uploader("Upload Lab Timetable", type=["xlsx"])
26
+ uploaded_classroom = st.sidebar.file_uploader("Upload Classroom Timetable", type=["xlsx"])
27
+ uploaded_individual = st.sidebar.file_uploader("Upload Individual Timetable", type=["xlsx"])
28
 
29
  uploaded_files = {
30
  "Master Timetable": uploaded_master,
 
33
  "Individual Timetable": uploaded_individual,
34
  }
35
 
36
+ # βœ… Load Timetable Data (Directly from Uploaded File)
37
  def load_timetable(file):
38
  if not file:
39
  return None
40
+ wb = openpyxl.load_workbook(file)
41
+ sheet = wb.active
42
+ return [row for row in sheet.iter_rows(values_only=True)]
43
+
44
+ # βœ… Initialize Sentence Transformer for Embeddings
45
+ embedder = SentenceTransformer("all-MiniLM-L6-v2")
46
+
47
+ # βœ… Process Uploaded Files and Create RAG Index
 
 
 
 
 
48
  rag_data = {}
49
  for name, file in uploaded_files.items():
50
  if file:
51
+ timetable_data = load_timetable(file)
52
+ if timetable_data:
53
+ rag_data[name] = timetable_data
54
 
55
+ # βœ… Convert timetable data to text format
 
56
  data_texts = ["\n".join(map(str, data)) for data in rag_data.values() if data]
57
+
58
+ if not data_texts:
59
+ st.error("Error: No extracted timetable content available for AI processing.")
60
+ st.stop()
61
+
62
+ # βœ… Generate FAISS Embeddings
63
  data_embeddings = embedder.encode(data_texts, convert_to_tensor=True)
64
 
65
+ if len(data_embeddings) == 0:
66
+ st.error("Error: No valid embeddings created. Check your timetable files.")
67
+ st.stop()
68
+
69
+ dimension = data_embeddings.shape[1] # FIXED ERROR: Ensuring valid shape
70
  index = faiss.IndexFlatL2(dimension)
71
  index.add(data_embeddings.cpu().numpy())
72
 
73
+ # βœ… Function to Retrieve Relevant Data from FAISS
74
+ def retrieve_relevant_text(query, top_k=2):
75
+ query_embedding = embedder.encode([query], convert_to_tensor=True).cpu().numpy()
76
+ distances, indices = index.search(query_embedding, top_k)
77
+
78
+ retrieved_texts = [data_texts[idx] for idx in indices[0] if idx < len(data_texts)]
79
+ return "\n".join(retrieved_texts)
80
 
81
+ # βœ… Ask LLaMA-3 AI via API
82
  def ask_llama_api(query):
83
  if not hf_api_key:
84
  return "Error: Please enter your API key."
85
+
86
+ retrieved_text = retrieve_relevant_text(query)
87
+ context = f"Relevant timetable data:\n{retrieved_text}\n\nUser Query: {query}"
88
 
89
  url = "https://api-inference.huggingface.co/v1/chat/completions"
90
  headers = {
 
93
  }
94
  payload = {
95
  "model": "meta-llama/Meta-Llama-3-8B",
96
+ "messages": [{"role": "user", "content": context}],
97
  "max_tokens": 500
98
  }
99
 
 
103
  else:
104
  return f"API Error: {response.status_code} - {response.text}"
105
 
106
+ # βœ… Auto-Schedule Missing Slots
107
+ def auto_schedule(file):
108
+ if not file:
109
+ return "No timetable uploaded."
110
+
111
+ wb = openpyxl.load_workbook(file)
112
+ sheet = wb.active
113
+
114
+ empty_slots = []
115
+ for row_idx, row in enumerate(sheet.iter_rows(min_row=2, values_only=True), start=2):
116
+ if None in row or "" in row:
117
+ empty_slots.append(row_idx)
118
+
119
+ for row_idx in empty_slots:
120
+ query = f"Suggest a subject and faculty for the empty slot in row {row_idx}."
121
+ suggestion = ask_llama_api(query)
122
+
123
+ try:
124
+ subject, faculty = suggestion.split(", Faculty: ")
125
+ sheet.cell(row=row_idx, column=4, value=subject.strip())
126
+ sheet.cell(row=row_idx, column=5, value=faculty.strip())
127
+ except:
128
+ continue
129
+
130
+ return f"Auto-scheduling completed for {len(empty_slots)} slots."
131
+
132
  # βœ… AI Query Section
133
  st.markdown("## πŸ€– Ask LLaMA-3 AI About Your Timetable")
134
  user_query = st.text_input("Type your question here (e.g., 'Who is free at 10 AM on Monday?')")
135
 
136
+ if st.button("Ask AI via API"):
137
  ai_response = ask_llama_api(user_query)
138
  st.write("🧠 **LLaMA-3 AI Suggests:**", ai_response)
139
 
 
142
  selected_file = st.selectbox("Choose a timetable file to auto-fill missing slots:", list(uploaded_files.keys()))
143
 
144
  if st.button("Auto-Schedule"):
145
+ result = auto_schedule(uploaded_files[selected_file])
146
  st.write("βœ…", result)
147
 
148
  # βœ… Display Uploaded Timetables
 
150
 
151
  for name, file in uploaded_files.items():
152
  if file:
153
+ df = pd.read_excel(file)
154
  st.markdown(f"### {name}")
155
+ st.dataframe(df)