import streamlit as st from transformers import pipeline from nltk.tokenize import sent_tokenize import base64 import torch import nltk import os import tempfile @st.cache_resource def init_nltk(): # ✅ Use a writable temp directory, not /app nltk_data_dir = os.path.join(tempfile.gettempdir(), "nltk_data") os.makedirs(nltk_data_dir, exist_ok=True) # ✅ Register this directory for nltk if nltk_data_dir not in nltk.data.path: nltk.data.path.insert(0, nltk_data_dir) # ✅ Download only required packages for pkg in ["punkt"]: try: nltk.data.find(f"tokenizers/{pkg}") except LookupError: nltk.download(pkg, download_dir=nltk_data_dir, quiet=True) return True # ✅ Run it once at startup init_nltk() # Device detection DEVICE = 0 if torch.cuda.is_available() else -1 # Lazy model loading def get_summarizer(): if 'summarizer' not in st.session_state: with st.spinner("🧠 Loading AI Brain..."): st.session_state.summarizer = pipeline("summarization", model="sshleifer/distilbart-cnn-12-6", device=DEVICE) return st.session_state.summarizer def get_qa(): if 'qa' not in st.session_state: with st.spinner("🧠 Loading AI Brain..."): st.session_state.qa = pipeline("question-answering", model="distilbert-base-uncased-distilled-squad", device=DEVICE) return st.session_state.qa def get_classifier(): if 'classifier' not in st.session_state: with st.spinner("🧠 Loading AI Brain..."): st.session_state.classifier = pipeline("zero-shot-classification", model="typeform/distilbert-base-uncased-mnli", device=DEVICE) return st.session_state.classifier @st.cache_resource def load_translator(model_name): return pipeline("translation", model=model_name, device=DEVICE) def truncate_text(text, max_words=400): words = text.split() return (" ".join(words[:max_words]), len(words) > max_words) # ULTRA PREMIUM CSS - Glassmorphism + Animations - FIXED HEADER st.markdown(""" """, unsafe_allow_html=True) # New Simple Header st.markdown("""
🧠 AI Study Helper Pro
⚡ Supercharge Your Learning with Advanced AI Technology
""", unsafe_allow_html=True) # Sidebar with st.sidebar: st.markdown("### đŸŽ¯ Dashboard") st.markdown("---") # Stats col1, col2 = st.columns(2) with col1: st.markdown('
📊 247 Processed
', unsafe_allow_html=True) with col2: st.markdown('
⚡ 2.3s Avg
', unsafe_allow_html=True) st.markdown("---") st.markdown("### ✨ Features") features = [ "📝 AI Summarization", "đŸ’Ŧ Smart Q&A", "đŸŽ¯ Quiz Generator", "🌍 Multi-Language", "🔑 Keyword Extraction", "💨 Lightning Fast" ] for feat in features: st.markdown(f"**{feat}**") st.markdown("---") st.markdown("### 👩‍đŸ’ģ Developer") st.markdown("**Umaima Qureshi**") st.markdown("[GitHub](https://github.com/Umaima122)") # Session state for key in ["summary", "quiz", "translation", "keywords"]: if key not in st.session_state: st.session_state[key] = "" if key not in ["quiz", "keywords"] else [] # Tabs tab1, tab2, tab3, tab4, tab5, tab6 = st.tabs([ "📝 Summarize", "đŸ’Ŧ Q&A", "đŸŽ¯ Quiz", "🌍 Translate", "🔑 Keywords", "đŸ“Ĩ Download" ]) # SUMMARIZE TAB with tab1: st.markdown("### 📝 Intelligent Summarization") text = st.text_area("âœī¸ Your notes or textbook:", value="", height=250, key="sum_txt", placeholder="Paste your content here and watch AI magic happen...") col1, col2, col3 = st.columns([1, 1, 1]) with col2: if st.button("✨ Generate Summary", key="sum_btn"): if not text.strip(): st.error("âš ī¸ Please provide text to summarize") else: trunc, was_trunc = truncate_text(text, 400) if was_trunc: st.info("📊 Text optimized to 400 words") if len(trunc.split()) < 20: st.error("âš ī¸ Need at least 20 words") else: with st.spinner("🧠 AI is thinking..."): try: summarizer = get_summarizer() result = summarizer(trunc, max_length=130, min_length=30, do_sample=False, truncation=True) summary = result[0]['summary_text'] st.markdown(f"""

📄 AI-Generated Summary

{summary}

{len(summary.split())} words ✓ Completed
""", unsafe_allow_html=True) st.session_state["summary"] = summary except Exception as e: st.error(f"❌ Error: {str(e)}") # Q&A TAB with tab2: st.markdown("### đŸ’Ŧ Intelligent Q&A System") context = st.text_area("📚 Context (Your notes):", value="", height=200, key="qa_ctx", placeholder="Paste your study material here...") question = st.text_input("❓ Ask your question:", key="qa_q", placeholder="What would you like to know?") col1, col2, col3 = st.columns([1, 1, 1]) with col2: if st.button("🔍 Get Answer", key="qa_btn"): if not context.strip() or not question.strip(): st.error("âš ī¸ Please provide both context and question") else: trunc_ctx, _ = truncate_text(context, 400) with st.spinner("🤔 Analyzing..."): try: qa_model = get_qa() answer = qa_model(question=question, context=trunc_ctx)['answer'] st.markdown(f"""

💡 AI Answer

{answer}

✓ Answer Found
""", unsafe_allow_html=True) except Exception as e: st.error(f"❌ Error: {str(e)}") # QUIZ TAB with tab3: st.markdown("### đŸŽ¯ AI Quiz Generator") quiz_ctx = st.text_area("📖 Study material:", value="", height=200, key="quiz_ctx", placeholder="Paste content for quiz generation...") col1, col2, col3 = st.columns([1, 1, 1]) with col2: if st.button("🚀 Generate Quiz", key="quiz_btn"): if not quiz_ctx.strip(): st.error("âš ī¸ Please provide text") else: trunc_quiz, _ = truncate_text(quiz_ctx, 200) with st.spinner("🎲 Creating questions..."): sentences = sent_tokenize(trunc_quiz)[:5] questions = [f"What is the main concept in: '{s[:70]}...'?" for s in sentences] st.markdown('
', unsafe_allow_html=True) st.markdown("

📝 Generated Quiz Questions

", unsafe_allow_html=True) for i, q in enumerate(questions, 1): st.markdown(f"""
Question {i}: {q}
""", unsafe_allow_html=True) st.markdown('
', unsafe_allow_html=True) st.session_state["quiz"] = questions # TRANSLATE TAB with tab4: st.markdown("### 🌍 AI Translation") trans_text = st.text_area("âœī¸ Text to translate:", height=200, key="trans_txt", placeholder="Enter text to translate...") col1, col2 = st.columns(2) with col1: lang = st.selectbox("đŸŽ¯ Target language:", ["French", "German", "Spanish", "Italian", "Hindi"]) with col2: st.write("") st.write("") if st.button("🌐 Translate Now", key="trans_btn"): if not trans_text.strip(): st.error("âš ī¸ Please provide text") else: model_map = { "French": "Helsinki-NLP/opus-mt-en-fr", "German": "Helsinki-NLP/opus-mt-en-de", "Spanish": "Helsinki-NLP/opus-mt-en-es", "Italian": "Helsinki-NLP/opus-mt-en-it", "Hindi": "Helsinki-NLP/opus-mt-en-hi" } trunc_trans, _ = truncate_text(trans_text, 200) with st.spinner(f"🌍 Translating to {lang}..."): try: translator = load_translator(model_map[lang]) translation = translator(trunc_trans, max_length=256)[0]['translation_text'] st.markdown(f"""

🌐 Translation ({lang})

{translation}

✓ Translated
""", unsafe_allow_html=True) st.session_state["translation"] = translation except Exception as e: st.error(f"❌ Error: {str(e)}") # KEYWORDS TAB with tab5: st.markdown("### 🔑 AI Keyword Extraction") keyword_input = st.text_area("📝 Text for analysis:", value="", height=200, key="kw_txt", placeholder="Paste text to extract key concepts...") col1, col2, col3 = st.columns([1, 1, 1]) with col2: if st.button("🔍 Extract Keywords", key="kw_btn"): if not keyword_input.strip(): st.error("âš ī¸ Please provide text") else: trunc_kw, _ = truncate_text(keyword_input, 200) with st.spinner("🔎 Analyzing concepts..."): try: classifier = get_classifier() labels = ["technology", "science", "education", "health", "business", "finance", "medical"] result = classifier(trunc_kw, labels) keywords = [lbl for lbl, score in zip(result['labels'], result['scores']) if score > 0.3][:5] if keywords: st.markdown('
', unsafe_allow_html=True) st.markdown("

đŸŽ¯ Extracted Keywords

", unsafe_allow_html=True) kw_html = " ".join([ f"{kw}" for kw in keywords ]) st.markdown(kw_html, unsafe_allow_html=True) st.markdown('
', unsafe_allow_html=True) st.session_state["keywords"] = keywords else: st.info("â„šī¸ No strong keywords found") except Exception as e: st.error(f"❌ Error: {str(e)}") # DOWNLOAD TAB with tab6: st.markdown("### đŸ“Ĩ Download Results") def download_link(text, filename, emoji): b64 = base64.b64encode(text.encode()).decode() return f""" {emoji} Download {filename} """ col1, col2 = st.columns(2) with col1: if st.session_state["summary"]: st.markdown(download_link(st.session_state["summary"], "summary.txt", "📄"), unsafe_allow_html=True) if st.session_state["quiz"]: st.markdown(download_link("\n".join(st.session_state["quiz"]), "quiz.txt", "đŸŽ¯"), unsafe_allow_html=True) with col2: if st.session_state["translation"]: st.markdown(download_link(st.session_state["translation"], "translation.txt", "🌍"), unsafe_allow_html=True) if st.session_state["keywords"]: st.markdown(download_link(", ".join(st.session_state["keywords"]), "keywords.txt", "🔑"), unsafe_allow_html=True) if not any([st.session_state["summary"], st.session_state["quiz"], st.session_state["translation"], st.session_state["keywords"]]): st.info("â„šī¸ Generate content in other tabs to enable downloads") # Premium Footer st.markdown(""" """, unsafe_allow_html=True)