import os, requests import gradio as gr from pypdf import PdfReader OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") OPENAI_URL = "https://api.openai.com/v1/chat/completions" MODEL = "gpt-4o-mini" MAX_PAGES, MAX_CHARS = 15, 10000 def extract_text(pdf_file): try: reader = PdfReader(pdf_file) pages = min(len(reader.pages), MAX_PAGES) text = "\n".join((reader.pages[i].extract_text() or "") for i in range(pages)) lines = [ln.strip() for ln in text.splitlines() if ln.strip()] return "\n".join(lines)[:MAX_CHARS] except Exception: return "" def call_openai(system_prompt, user_content): if not OPENAI_API_KEY: raise RuntimeError("Missing OPENAI_API_KEY (set it in Space → Settings → Secrets).") headers = {"Authorization": f"Bearer {OPENAI_API_KEY}", "Content-Type": "application/json"} body = { "model": MODEL, "messages": [ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_content} ], "temperature": 0.2 } r = requests.post(OPENAI_URL, headers=headers, json=body, timeout=60) r.raise_for_status() return r.json()["choices"][0]["message"]["content"] def summarize(content, length): sys = ("You are a precise study assistant for MBA-level students. " "Summarize in clean bullet points; short=5 bullets, medium=8-10, long=12-15.") usr = f"Length: {length}\n\nCONTENT:\n{content[:MAX_CHARS]}" return call_openai(sys, usr) def mcqs(content): sys = ("Create 10 single-answer MCQs from the content. " "Each item: question + 4 options labeled A)–D), then a line 'Answer: X' " "and a one-sentence explanation.") usr = f"CONTENT:\n{content[:8000]}" return call_openai(sys, usr) def generate(pasted_text, pdf_file, length): source = "" if pdf_file is not None: source = extract_text(pdf_file) if not source and pasted_text: source = pasted_text.strip()[:MAX_CHARS] if not source: return "❌ Paste text or upload a PDF.", "" if len(source) < 200: return "❌ Input too short.", "" try: summary_md = summarize(source, length) except Exception as e: return f"❌ Summarization failed: {e}", "" try: mcq_md = mcqs(source) except Exception as e: mcq_md = f"❌ MCQ generation failed: {e}" summary_md = f"### 📄 Summary\n\n{summary_md}" mcq_md = f"### 🧠 Practice — 10 MCQs\n\n{mcq_md}" return summary_md, mcq_md with gr.Blocks(title="StudySnap — Summaries + MCQs") as demo: gr.Markdown("# 📚 StudySnap\nUpload a PDF or paste text. Get a clean summary + 10 MCQs.") with gr.Row(): pasted = gr.Textbox(label="Paste Text", lines=10, placeholder="Paste your lecture notes or article here…") pdf = gr.File(label="Upload PDF (first 15 pages)", file_types=[".pdf"]) length = gr.Radio(["short", "medium", "long"], value="medium", label="Output length") btn = gr.Button("Generate", variant="primary") out_summary = gr.Markdown() out_mcq = gr.Markdown() btn.click(fn=generate, inputs=[pasted, pdf, length], outputs=[out_summary, out_mcq]) if __name__ == "__main__": demo.launch()