Spaces:
Runtime error
Runtime error
| 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() | |