import json import requests import os import streamlit as st import pandas as pd import openpyxl import faiss import torch from reportlab.lib.pagesizes import letter from reportlab.pdfgen import canvas from sentence_transformers import SentenceTransformer from transformers import AutoModelForCausalLM, AutoTokenizer # ✅ Streamlit UI Setup st.set_page_config(page_title="AI-Powered Timetable", layout="wide") st.markdown("

📅 AI-Powered Timetable

", unsafe_allow_html=True) # ✅ API Key Input st.sidebar.markdown("## 🔑 Enter Hugging Face API Key") hf_api_key = st.sidebar.text_input("API Key", type="password") # ✅ File Upload Section st.sidebar.markdown("## 📂 Upload Your Timetable Files") uploaded_master = st.sidebar.file_uploader("Upload Master Timetable", type=["xlsx"]) uploaded_lab = st.sidebar.file_uploader("Upload Lab Timetable", type=["xlsx"]) uploaded_classroom = st.sidebar.file_uploader("Upload Classroom Timetable", type=["xlsx"]) uploaded_individual = st.sidebar.file_uploader("Upload Individual Timetable", type=["xlsx"]) uploaded_files = { "Master Timetable": uploaded_master, "Lab Timetable": uploaded_lab, "Classroom Timetable": uploaded_classroom, "Individual Timetable": uploaded_individual, } # ✅ Load Timetable Data (Directly from Uploaded File) def load_timetable(file): if not file: return None wb = openpyxl.load_workbook(file) sheet = wb.active return [row for row in sheet.iter_rows(values_only=True)] # ✅ Initialize Sentence Transformer for Embeddings embedder = SentenceTransformer("all-MiniLM-L6-v2") # ✅ Process Uploaded Files and Create RAG Index rag_data = {} for name, file in uploaded_files.items(): if file: timetable_data = load_timetable(file) if timetable_data: rag_data[name] = timetable_data # ✅ Convert timetable data to text format data_texts = ["\n".join(map(str, data)) for data in rag_data.values() if data] if not data_texts: st.error("Error: No extracted timetable content available for AI processing.") st.stop() # ✅ Generate FAISS Embeddings data_embeddings = embedder.encode(data_texts, convert_to_tensor=True) if len(data_embeddings) == 0: st.error("Error: No valid embeddings created. Check your timetable files.") st.stop() dimension = data_embeddings.shape[1] # FIXED ERROR: Ensuring valid shape index = faiss.IndexFlatL2(dimension) index.add(data_embeddings.cpu().numpy()) # ✅ Function to Retrieve Relevant Data from FAISS def retrieve_relevant_text(query, top_k=2): query_embedding = embedder.encode([query], convert_to_tensor=True).cpu().numpy() distances, indices = index.search(query_embedding, top_k) retrieved_texts = [data_texts[idx] for idx in indices[0] if idx < len(data_texts)] return "\n".join(retrieved_texts) # ✅ Ask LLaMA-3 AI via API def ask_llama_api(query): if not hf_api_key: return "Error: Please enter your API key." retrieved_text = retrieve_relevant_text(query) context = f"Relevant timetable data:\n{retrieved_text}\n\nUser Query: {query}" url = "https://api-inference.huggingface.co/v1/chat/completions" headers = { "Authorization": f"Bearer {hf_api_key}", "Content-Type": "application/json" } payload = { "model": "meta-llama/Meta-Llama-3-8B", "messages": [{"role": "user", "content": context}], "max_tokens": 500 } response = requests.post(url, headers=headers, json=payload) if response.status_code == 200: return response.json()["choices"][0]["message"]["content"] else: return f"API Error: {response.status_code} - {response.text}" # ✅ Auto-Schedule Missing Slots def auto_schedule(file): if not file: return "No timetable uploaded." wb = openpyxl.load_workbook(file) sheet = wb.active empty_slots = [] for row_idx, row in enumerate(sheet.iter_rows(min_row=2, values_only=True), start=2): if None in row or "" in row: empty_slots.append(row_idx) for row_idx in empty_slots: query = f"Suggest a subject and faculty for the empty slot in row {row_idx}." suggestion = ask_llama_api(query) try: subject, faculty = suggestion.split(", Faculty: ") sheet.cell(row=row_idx, column=4, value=subject.strip()) sheet.cell(row=row_idx, column=5, value=faculty.strip()) except: continue return f"Auto-scheduling completed for {len(empty_slots)} slots." # ✅ AI Query Section st.markdown("## 🤖 Ask LLaMA-3 AI About Your Timetable") user_query = st.text_input("Type your question here (e.g., 'Who is free at 10 AM on Monday?')") if st.button("Ask AI via API"): ai_response = ask_llama_api(user_query) st.write("🧠 **LLaMA-3 AI Suggests:**", ai_response) # ✅ Auto-Schedule Feature st.markdown("## 📅 Auto-Schedule Missing Timetable Slots") selected_file = st.selectbox("Choose a timetable file to auto-fill missing slots:", list(uploaded_files.keys())) if st.button("Auto-Schedule"): result = auto_schedule(uploaded_files[selected_file]) st.write("✅", result) # ✅ Display Uploaded Timetables st.markdown("## 📜 View Uploaded Timetables") for name, file in uploaded_files.items(): if file: df = pd.read_excel(file) st.markdown(f"### {name}") st.dataframe(df)