import os os.environ["GRADIO_ANALYTICS_ENABLED"] = "False" os.environ["HF_HUB_OFFLINE"] = "1" os.environ["GRADIO_TEMP_DIR"] = "/tmp" import gradio as gr from groq import Groq from docx import Document from docx.shared import Pt, RGBColor, Inches from docx.enum.text import WD_ALIGN_PARAGRAPH from docx.oxml.ns import qn from docx.oxml import OxmlElement from datetime import datetime import re # Initialize Groq client try: client = Groq() print("Groq client initialized successfully") except Exception as e: print(f"Warning: Groq client initialization failed: {e}") client = None # ---------------- TOKEN SAFE GENERATION ---------------- # def safe_generate(messages, max_tokens=400): """ Controlled generation to avoid token overflow """ try: response = client.chat.completions.create( model="openai/gpt-oss-120b", messages=messages, temperature=0.7, max_completion_tokens=max_tokens, top_p=0.9 ) return response.choices[0].message.content.strip() except Exception as e: return f"Error: {str(e)}" # ---------------- DATA ---------------- # SUBJECTS_BY_GRADE = { "Grade 1-5": ["English", "Urdu", "Mathematics", "General Science", "Islamiyat", "Pakistan Studies", "Computer"], "Grade 6-8": ["English", "Urdu", "Mathematics", "General Science", "Islamiyat", "Pakistan Studies", "Computer"], "Grade 9-10": ["English", "Urdu", "Mathematics", "Physics", "Chemistry", "Biology", "Islamiyat", "Pakistan Studies", "Computer Science"], "Grade 11-12": ["English", "Urdu", "Mathematics", "Physics", "Chemistry", "Biology", "Islamiyat", "Pakistan Studies", "Computer Science", "Economics", "Statistics"] } DISTRICTS_GB = [ "Gilgit", "Ghizer", "Hunza", "Nagar", "Skardu", "Shigar", "Kharmang", "Ghanche", "Astore", "Diamer", "Darel", "Tangir", "Gupis Yasin", "Roundu" ] TEACHING_METHODS = [ "Lecture Method", "Discussion Method", "Demonstration Method", "Activity-Based Learning", "Inquiry-Based Learning", "Group Work", "Project-Based Learning", "Problem-Based Learning", "Hands-on Activities", "Visual Learning", "Interactive Learning", "Storytelling", "Cooperative Learning", "Flipped Classroom", "Think-Pair-Share" ] ASSESSMENT_TYPES = [ "Formative Assessment", "Summative Assessment", "Oral Questions", "Written Test", "Practical Work", "Class Participation", "Quiz", "Worksheet", "Group Presentation", "Individual Assignment", "Peer Assessment", "Self Assessment", "Portfolio Assessment" # ---------------- URDU TRANSLATIONS ---------------- # URDU_TRANSLATIONS = { "English": "انگریزی", "Urdu": "اردو", "Mathematics": "ریاضی", "General Science": "عمومی سائنس", "Islamiyat": "اسلامیات", "Pakistan Studies": "پاکستان کی تاریخ و جغرافیہ", "Computer": "کمپیوٹر", "Physics": "طبیعیات", "Chemistry": "کیمیا", "Biology": "حیاتیات", "Computer Science": "کمپیوٹر سائنس", "Economics": "معاشیات", "Statistics": "شماریات", "Lecture Method": "لیکچر کا طریقہ", "Discussion Method": "گفتگو کا طریقہ", "Demonstration Method": "عملی مظاہرہ", "Activity-Based Learning": "سرگرمی پر مبنی تعلیم", "Inquiry-Based Learning": "تحقیقی تعلیم", "Group Work": "اجتماعی کام", "Project-Based Learning": "منصوبہ پر مبنی تعلیم", "Problem-Based Learning": "مسئلہ حل کرنے کی تعلیم", "Hands-on Activities": "عملی سرگرمیاں", "Visual Learning": "بصری تعلیم", "Interactive Learning": "تعاملی تعلیم", "Storytelling": "کہانی سنانا", "Cooperative Learning": "باہمی تعاون سے سیکھنا", "Flipped Classroom": "تبدیل شدہ کلاس روم", "Think-Pair-Share": "سوچیں، جوڑے بنائیں، شیئر کریں", "Formative Assessment": "تشکیلی تشخیص", "Summative Assessment": "اختتامی تشخیص", "Oral Questions": "زبانی سوالات", "Written Test": "تحریری امتحان", "Practical Work": "عملی کام", "Class Participation": "کلاسی شرکت", "Quiz": "مختصر امتحان", "Worksheet": "ورک شیٹ", "Group Presentation": "اجتماعی پیشکش", "Individual Assignment": "انفرادی تفویض", "Peer Assessment": "ہم جماعت کی تشخیص", "Self Assessment": "خود تشخیص", "Portfolio Assessment": "پورٹ فولیو کی تشخیص", "Grade 1": "جماعت اول", "Grade 2": "جماعت دوم", "Grade 3": "جماعت سوم", "Grade 4": "جماعت چہارم", "Grade 5": "جماعت پنجم", "Grade 6": "جماعت ششم", "Grade 7": "جماعت ہفتم", "Grade 8": "جماعت ہشتم", "Grade 9": "جماعت نہم", "Grade 10": "جماعت دہم", "Grade 11": "جماعت یازدہم", "Grade 12": "جماعت دوازدہم", "District": "ضلع", "School": "تعلیمی ادارہ", "Teacher": "استاد کا نام", "Date": "تاریخ", "Topic": "عنوانِ سبق", "Duration": "دورانیہ", "No. of Students": "طلبہ کی تعداد", "Teaching Method": "تدریسی طریقہ", "Assessment Type": "تشخیصی طریقہ", "minutes": "منٹ" } # ---------------- HELPERS ---------------- # def translate_to_urdu(text): if not text: return text if text in URDU_TRANSLATIONS: return URDU_TRANSLATIONS[text] words = str(text).split() return " ".join([URDU_TRANSLATIONS.get(w, w) for w in words]) def update_subjects(grade_range): if not grade_range: return gr.Dropdown(choices=[], value=None) return gr.Dropdown(choices=SUBJECTS_BY_GRADE.get(grade_range, []), value=None) def validate_inputs(language, grade_range, subject, topic, teacher_name, school_name): errors = [] if not language: errors.append("Language is required") if not grade_range: errors.append("Grade range is required") if not subject: errors.append("Subject is required") if not topic or len(topic.strip()) < 3: errors.append("Topic too short") if not teacher_name: errors.append("Teacher name required") if not school_name: errors.append("School name required") return errors # ---------------- DOCX UTILITIES ---------------- # def add_table_border(table): tbl = table._tbl tblPr = tbl.tblPr if tblPr is None: tblPr = OxmlElement('w:tblPr') tbl.insert(0, tblPr) borders = OxmlElement('w:tblBorders') for name in ['top', 'left', 'bottom', 'right', 'insideH', 'insideV']: border = OxmlElement(f'w:{name}') border.set(qn('w:val'), 'single') border.set(qn('w:sz'), '4') border.set(qn('w:color'), '000000') borders.append(border) tblPr.append(borders) def apply_rtl_to_paragraph(para, alignment=WD_ALIGN_PARAGRAPH.RIGHT): para.alignment = alignment para.paragraph_format.right_to_left = True pPr = para._element.get_or_add_pPr() bidi = OxmlElement('w:bidi') pPr.append(bidi) def apply_rtl_to_run(run): run.font.rtl = True run.font.name = 'Arial' def create_rtl_table_cell(cell, text, bold=False): cell.text = '' para = cell.paragraphs[0] run = para.add_run(str(text)) run.font.size = Pt(11) run.font.name = 'Arial' run.font.rtl = True if bold: run.bold = True apply_rtl_to_paragraph(para) def generate_lesson_plan(language, grade_range, grade_specific, subject, topic, school_name, teacher_name, district, date_input, students, duration, teaching_method, assessment_type, include_resources, include_differentiation): # ---------- VALIDATION ---------- errors = validate_inputs(language, grade_range, subject, topic, teacher_name, school_name) if errors: return None, "\n".join(errors) if client is None: return None, "Groq API not initialized" # ---------- DATE ---------- try: formatted_date = datetime.strptime(date_input, "%Y-%m-%d").strftime("%Y-%m-%d") except: formatted_date = datetime.now().strftime("%Y-%m-%d") # ---------- GRADE ---------- full_grade = grade_specific if grade_specific else grade_range.split('-')[0] # ---------- URDU PREP ---------- if language == "Urdu": full_grade_urdu = translate_to_urdu(full_grade) subject_urdu = translate_to_urdu(subject) district_urdu = translate_to_urdu(district) teaching_method_urdu = translate_to_urdu(teaching_method) assessment_type_urdu = translate_to_urdu(assessment_type) topic_urdu = topic # ============================================================ # 🔥 CHUNKED GENERATION STARTS HERE # ============================================================ print(f"Generating {language} lesson plan (chunked mode)...") # ---------- ENGLISH VERSION ---------- if language == "English": # 1️⃣ SLOs slos = safe_generate([ {"role": "system", "content": "Generate in English only"}, {"role": "user", "content": f""" Write 3 SMART SLOs: Grade: {full_grade} Subject: {subject} Topic: {topic} Use: 1 Knowledge 2 Understanding 3 Application """} ], max_tokens=250) # 2️⃣ CONTENT content = safe_generate([ {"role": "system", "content": "Generate in English only"}, {"role": "user", "content": f""" Write CONTENT KNOWLEDGE for: {topic} (Grade {full_grade}) Include: - Key concepts - Definitions - Examples (Pakistan context) {"- Resources" if include_resources else ""} {"- Differentiation" if include_differentiation else ""} No teaching steps. """} ], max_tokens=600) # 3️⃣ ASSIGNMENT assignment = safe_generate([ {"role": "system", "content": "Generate in English only"}, {"role": "user", "content": f""" Create HOME ASSIGNMENT: Topic: {topic} Grade: {full_grade} 3-5 questions. """} ], max_tokens=250) lesson_text = f""" SMART STUDENT LEARNING OUTCOMES {slos} CONTENT KNOWLEDGE {content} HOME ASSIGNMENT {assignment} """ # ---------- URDU VERSION ---------- else: slos = safe_generate([ {"role": "system", "content": "صرف اردو میں لکھیں"}, {"role": "user", "content": f""" 3 اسمارٹ نتائج لکھیں: جماعت: {full_grade_urdu} مضمون: {subject_urdu} عنوان: {topic_urdu} """} ], max_tokens=250) content = safe_generate([ {"role": "system", "content": "صرف اردو میں لکھیں"}, {"role": "user", "content": f""" علمی مواد لکھیں: {topic_urdu} (جماعت {full_grade_urdu}) شامل کریں: - بنیادی تصورات - تعریفات - مثالیں {"- وسائل" if include_resources else ""} {"- مختلف طلبہ کے لیے حکمت عملی" if include_differentiation else ""} """} ], max_tokens=600) assignment = safe_generate([ {"role": "system", "content": "صرف اردو میں لکھیں"}, {"role": "user", "content": f""" گھر کا کام بنائیں: {topic_urdu} 3-5 سوالات شامل کریں۔ """} ], max_tokens=250) lesson_text = f""" اسمارٹ طلبہ سیکھنے کے نتائج {slos} علمی مواد {content} گھر کی تفویض {assignment} """ # Clean extra noise lesson_text = lesson_text.strip() # ============================================================ # ✅ RETURN TEXT FOR DOC GENERATION (PART 4) # ============================================================ return lesson_text, { "formatted_date": formatted_date, "full_grade": full_grade, "topic": topic, "subject": subject, "district": district, "students": students, "duration": duration, "teacher_name": teacher_name, "school_name": school_name, "teaching_method": teaching_method, "assessment_type": assessment_type, "language": language, "topic_urdu": topic if language == "Urdu" else None } def build_docx(lesson_text, meta): """ DOCX builder using already generated safe text (NO API CALLS HERE) """ language = meta["language"] topic = meta["topic"] subject = meta["subject"] district = meta["district"] teacher_name = meta["teacher_name"] school_name = meta["school_name"] full_grade = meta["full_grade"] students = meta["students"] duration = meta["duration"] teaching_method = meta["teaching_method"] assessment_type = meta["assessment_type"] formatted_date = meta["formatted_date"] doc = Document() # ============================================================ # ===================== ENGLISH DOC ========================== # ============================================================ if language == "English": section = doc.sections[0] section.top_margin = Inches(0.75) section.bottom_margin = Inches(0.75) section.left_margin = Inches(0.75) section.right_margin = Inches(0.75) # Header header = doc.add_paragraph() run = header.add_run("Government of Gilgit-Baltistan\nSchool Education Department") run.bold = True run.font.size = Pt(13) header.alignment = WD_ALIGN_PARAGRAPH.CENTER # Title title = doc.add_paragraph() run = title.add_run("SMART LESSON PLAN") run.bold = True run.font.size = Pt(14) title.alignment = WD_ALIGN_PARAGRAPH.CENTER doc.add_paragraph() # Table table = doc.add_table(rows=6, cols=4) add_table_border(table) def cell(r, c, text, bold=False): cell = table.rows[r].cells[c] cell.text = str(text) if bold: for p in cell.paragraphs: for run in p.runs: run.bold = True cell(0, 0, "Grade", True) cell(0, 1, full_grade) cell(0, 2, "Subject", True) cell(0, 3, subject) cell(1, 0, "Topic", True) cell(1, 1, topic) cell(1, 2, "Duration", True) cell(1, 3, f"{duration} min") cell(2, 0, "Teacher", True) cell(2, 1, teacher_name) cell(2, 2, "Date", True) cell(2, 3, formatted_date) cell(3, 0, "School", True) cell(3, 1, school_name) cell(3, 2, "District", True) cell(3, 3, district) cell(4, 0, "Students", True) cell(4, 1, students) cell(4, 2, "Method", True) cell(4, 3, teaching_method) cell(5, 0, "Assessment", True) table.rows[5].cells[1].merge(table.rows[5].cells[3]) cell(5, 1, assessment_type) doc.add_paragraph() # Content sections (SAFE TEXT ONLY) for line in lesson_text.split("\n"): if line.strip(): para = doc.add_paragraph(line.strip()) para.alignment = WD_ALIGN_PARAGRAPH.LEFT file_path = f"/tmp/LP_{subject}_{topic[:20]}_{formatted_date}.docx" doc.save(file_path) return file_path, "English Lesson Plan Generated Successfully" # ============================================================ # ======================= URDU DOC =========================== # ============================================================ else: section = doc.sections[0] section.top_margin = Inches(0.75) section.bottom_margin = Inches(0.75) section.left_margin = Inches(0.75) section.right_margin = Inches(1) # Header header = doc.add_paragraph() run = header.add_run("حکومتِ گلگت بلتستان\nمحکمہ تعلیم") run.bold = True run.font.size = Pt(13) apply_rtl_to_paragraph(header) # Title title = doc.add_paragraph() run = title.add_run("اسمارٹ سبق کا منصوبہ") run.bold = True run.font.size = Pt(14) apply_rtl_to_paragraph(title) doc.add_paragraph() # Table (simplified safe version) table = doc.add_table(rows=6, cols=4) add_table_border(table) def urdu_cell(r, c, text, bold=False): cell = table.rows[r].cells[c] cell.text = str(text) para = cell.paragraphs[0] apply_rtl_to_paragraph(para) urdu_cell(0, 0, translate_to_urdu(subject)) urdu_cell(0, 1, translate_to_urdu("Subject"), True) urdu_cell(0, 2, translate_to_urdu(full_grade)) urdu_cell(0, 3, translate_to_urdu("Grade"), True) urdu_cell(1, 0, topic) urdu_cell(1, 1, translate_to_urdu("Topic"), True) urdu_cell(1, 2, f"{duration} {translate_to_urdu('minutes')}") urdu_cell(1, 3, translate_to_urdu("Duration"), True) urdu_cell(2, 0, teacher_name) urdu_cell(2, 1, translate_to_urdu("Teacher"), True) urdu_cell(2, 2, formatted_date) urdu_cell(2, 3, translate_to_urdu("Date"), True) urdu_cell(3, 0, district) urdu_cell(3, 1, translate_to_urdu("District"), True) urdu_cell(3, 2, school_name) urdu_cell(3, 3, translate_to_urdu("School"), True) urdu_cell(4, 0, students) urdu_cell(4, 1, translate_to_urdu("Students"), True) urdu_cell(4, 2, teaching_method) urdu_cell(4, 3, translate_to_urdu("Method"), True) urdu_cell(5, 0, assessment_type) table.rows[5].cells[0].merge(table.rows[5].cells[3]) doc.add_paragraph() # Content (SAFE TEXT ONLY) for line in lesson_text.split("\n"): if line.strip(): para = doc.add_paragraph(line.strip()) apply_rtl_to_paragraph(para) file_path = f"/tmp/LP_Urdu_{topic[:20]}_{formatted_date}.docx" doc.save(file_path) return file_path, "اردو سبق کا منصوبہ تیار ہو گیا" # ============================================================ # ================= GRADIO INTERFACE ========================= # ============================================================ custom_css = """ .gradio-container { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif !important; } .main-header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 2rem; border-radius: 10px; color: white; margin-bottom: 2rem; } .section-header { background-color: #f8f9fa; padding: 1rem; border-left: 4px solid #667eea; margin: 1.5rem 0 1rem 0; border-radius: 5px; } """ with gr.Blocks(theme=gr.themes.Soft(), css=custom_css, title="SMART Lesson Plan Generator") as demo: gr.HTML("""

SMART Lesson Plan Generator

AI Powered Lesson Planning System (Pakistan Curriculum)

""") # ---------------- INPUTS ---------------- # language = gr.Dropdown(["English", "Urdu"], value="English", label="Language") grade_range = gr.Dropdown( ["Grade 1-5", "Grade 6-8", "Grade 9-10", "Grade 11-12"], label="Grade Range" ) grade_specific = gr.Dropdown( [f"Grade {i}" for i in range(1, 13)], label="Specific Grade (Optional)" ) subject = gr.Dropdown([], label="Subject") topic = gr.Textbox(label="Topic") school_name = gr.Textbox(label="School Name") teacher_name = gr.Textbox(label="Teacher Name") district = gr.Dropdown(DISTRICTS_GB, label="District") date_input = gr.Textbox(label="Date", value=datetime.now().strftime("%Y-%m-%d")) students = gr.Number(label="Students", value=30) duration = gr.Number(label="Duration (minutes)", value=40) teaching_method = gr.Dropdown(TEACHING_METHODS, label="Teaching Method") assessment_type = gr.Dropdown(ASSESSMENT_TYPES, label="Assessment Type") include_resources = gr.Checkbox(label="Include Resources", value=True) include_differentiation = gr.Checkbox(label="Include Differentiation", value=True) # ---------------- OUTPUT ---------------- # file_output = gr.File(label="Download Lesson Plan") status_output = gr.Textbox(label="Status") # ============================================================ # ===================== EVENT PIPELINE ======================= # ============================================================ def pipeline(*inputs): """ FULL FIXED PIPELINE: 1. Generate chunked lesson text 2. Build DOCX """ lesson_text, meta = generate_lesson_plan(*inputs) file_path, status = build_docx(lesson_text, meta) return file_path, status # Grade → Subject update grade_range.change(update_subjects, grade_range, subject) # Generate button gr.Button("Generate Lesson Plan", variant="primary").click( pipeline, inputs=[ language, grade_range, grade_specific, subject, topic, school_name, teacher_name, district, date_input, students, duration, teaching_method, assessment_type, include_resources, include_differentiation ], outputs=[file_output, status_output] ) # ============================================================ # ===================== LAUNCH APP ============================ # ============================================================ if __name__ == "__main__": demo.launch( server_name="0.0.0.0", server_port=7860, share=False, show_error=True, allowed_paths=["/tmp"] )