import os import streamlit as st from groq import Groq from io import BytesIO from PyPDF2 import PdfReader import docx from textwrap import wrap import json # Configure Streamlit st.set_page_config( page_title="EduAI Assistant", page_icon="📚", layout="wide" ) # Initialize Groq client groq_api_key = os.environ.get("Groq_Api_Key") if not groq_api_key: st.error("Missing Groq API key! Please set the 'Groq_Api_Key' environment variable.") st.stop() client = Groq(api_key=groq_api_key) # Sidebar Configuration st.sidebar.header("Upload Files or Enter Text") uploaded_files = st.sidebar.file_uploader( "Upload lesson files (PDFs or Word documents)", accept_multiple_files=True ) manual_input = st.sidebar.text_area("Or paste lesson text here", height=200) st.sidebar.header("Select Action") task = st.sidebar.selectbox("What would you like to do?", [ "Summarize a Topic", "Ask Questions", "Generate MCQs", "Adapt Lesson for Grades", "Generate Conceptual Assignment", "Provide Learning Resources", "Generate Conceptual Short Questions" ]) # Helper functions def extract_text_from_pdf(pdf_file): pdf_reader = PdfReader(pdf_file) return "".join(page.extract_text() for page in pdf_reader.pages) def extract_text_from_word(doc_file): doc = docx.Document(doc_file) return "\n".join(paragraph.text for paragraph in doc.paragraphs) def chunk_text(text, max_tokens=2000): char_limit = max_tokens * 4 # Approximation: 1 token = 4 characters return wrap(text, char_limit) def process_with_groq(messages, model="llama-3.3-70b-versatile"): try: response = client.chat.completions.create(messages=messages, model=model, stream=False) return response.choices[0].message.content.strip() except Exception as e: st.error(f"Error with Groq API: {e}") return "" def save_to_docx(text, filename="download.docx"): doc = docx.Document() doc.add_paragraph(text) byte_io = BytesIO() doc.save(byte_io) byte_io.seek(0) return byte_io # Main App Layout st.title("EduAI-Assistant for Teachers") st.markdown(""" Welcome to your AI-powered teaching assistant! - Upload lesson files or input text. - Perform actions like summarizing topics, generating assignments/quizzez/short questions, generating learning resources and adapting lessons. """) if uploaded_files or manual_input: lesson_text = "" if uploaded_files: for file in uploaded_files: file_type = file.name.split(".")[-1].lower() if file_type == "pdf": lesson_text += extract_text_from_pdf(file) elif file_type == "docx": lesson_text += extract_text_from_word(file) else: st.error(f"Unsupported file type: {file_type}") st.stop() else: lesson_text = manual_input text_chunks = chunk_text(lesson_text) if task == "Summarize a Topic": topic = st.text_input("Enter the topic or keywords:") if st.button("Summarize"): summaries = [process_with_groq([ {"role": "system", "content": "Summarize the following lesson content."}, {"role": "user", "content": f"Context: {chunk}\n\nSummarize the topic: {topic}"} ]) for chunk in text_chunks] st.write("### Summary") summary_text = "\n\n".join(summaries) st.write(summary_text) docx_file = save_to_docx(summary_text) st.download_button("Download Summary as DOCX", docx_file, file_name="summary.docx") elif task == "Ask Questions": question = st.text_input("Enter your question:") if st.button("Get Answer"): answers = [process_with_groq([ {"role": "system", "content": "You are a helpful teaching assistant."}, {"role": "user", "content": f"Context: {chunk}\n\nQuestion: {question}"} ]) for chunk in text_chunks] st.write("### Answer") st.write("\n\n".join(answers)) elif task == "Generate MCQs": num_questions = st.slider("Number of questions to generate:", 1, 10, 5) if st.button("Generate MCQs"): mcqs = [] for chunk in text_chunks: response = process_with_groq([ {"role": "system", "content": "You are an AI assistant generating multiple-choice questions. Please provide each MCQ in a clearly structured format with the following fields: question, options (list of options), and answer. Separate each question with a newline."}, {"role": "user", "content": f"Context: {chunk}\n\nGenerate {num_questions} MCQs in a structured format."} ]) # Check if the response contains a valid structure (e.g., 'Q1:', 'Options:') if "Q" in response and "Options:" in response: # Split the response into individual MCQs using a delimiter like 'Q' or a newline mcq_blocks = response.split("\n") for block in mcq_blocks: if block.strip().startswith("Q"): question = block.strip() options = [] answer = "" # Extract options and answer for option_line in mcq_blocks: if option_line.startswith("Options:"): options = option_line[len("Options:"):].split(" ") if option_line.startswith("Answer:"): answer = option_line[len("Answer:"):].strip() mcqs.append({ "question": question, "options": options, "answer": answer }) else: st.error(f"Failed to parse structured MCQs from the response: {response}") st.write("### Multiple Choice Questions") for idx, mcq in enumerate(mcqs): st.write(f"**Q{idx + 1}:** {mcq['question']}") for option in mcq['options']: st.write(f"- {option}") # Create the MCQs text for download mcqs_text = "\n\n".join([f"**Q{idx + 1}:** {mcq['question']}\n" + "\n".join([f"- {option}" for option in mcq['options']]) for idx, mcq in enumerate(mcqs)]) mcqs_file = save_to_docx(mcqs_text, filename="mcqs.docx") st.download_button("Download MCQs as DOCX", mcqs_file, file_name="mcqs.docx") elif task == "Adapt Lesson for Grades": grade = st.slider("Select Grade:", 1, 16, 9) if st.button("Adapt Lesson"): adaptations = [process_with_groq([ {"role": "system", "content": "Adapt the lesson content for a specific grade."}, {"role": "user", "content": f"Context: {chunk}\n\nAdapt this lesson for grade {grade}."} ]) for chunk in text_chunks] st.write("### Adapted Lesson") st.write("\n\n".join(adaptations)) elif task == "Generate Conceptual Assignment": topic = st.text_input("Enter the topic for the assignment:") if st.button("Generate Assignment"): assignments = [process_with_groq([ {"role": "system", "content": "Generate a conceptual-based assignment."}, {"role": "user", "content": f"Context: {chunk}\n\nTopic: {topic}"} ]) for chunk in text_chunks] st.write("### Conceptual Assignment") assignment_text = "\n\n".join(assignments) st.write(assignment_text) # Display the assignment first docx_file = save_to_docx(assignment_text) st.download_button("Download Assignment as DOCX", docx_file, file_name="assignment.docx") elif task == "Provide Learning Resources": topic = st.text_input("Enter the topic:") if st.button("Generate Resources"): resources = process_with_groq([ {"role": "system", "content": "Provide a list of learning resources for a topic."}, {"role": "user", "content": f"Topic: {topic}"} ]) st.write("### Learning Resources") st.write(resources) elif task == "Generate Conceptual Short Questions": topic = st.text_input("Enter the topic for conceptual short questions:") if st.button("Generate Conceptual Short Questions"): conceptual_questions = [process_with_groq([ {"role": "system", "content": "Generate conceptual short questions based on the provided lesson content."}, {"role": "user", "content": f"Context: {chunk}\n\nGenerate deep conceptual questions for the topic: {topic}"} ]) for chunk in text_chunks] st.write("### Conceptual Short Questions") conceptual_questions_text = "\n\n".join(conceptual_questions) st.write(conceptual_questions_text) docx_file = save_to_docx(conceptual_questions_text) st.download_button("Download Conceptual Short Questions as DOCX", docx_file, file_name="conceptual_short_questions.docx") else: st.info("Please upload files or enter lesson text to get started.")