1 line
6.7 KiB
JSON
1 line
6.7 KiB
JSON
{"repo": "biswajeetdev/ai-policy-summarizer", "files": {"app.py": {"94ce213cee5ea9d8ca12e7b78c6ef7bf362551f0": {"t": 1785674397.2492893, "n": 5866, "h": "881369a776d42d8a", "c": "import os\nimport io\nimport html\n\nimport streamlit as st\nfrom pypdf import PdfReader\nfrom dotenv import load_dotenv\n\nfrom summarizer import make_client, summarise, compare\n\nload_dotenv()\n\nst.set_page_config(\n page_title=\"Policy Summarizer\",\n page_icon=\"📋\",\n layout=\"wide\",\n)\n\nst.markdown(\"\"\"\n<style>\n .summary-box {\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n padding: 1.25rem 1.5rem;\n font-size: 0.9rem;\n line-height: 1.7;\n }\n .badge {\n display: inline-block;\n background: #dbeafe;\n color: #1e40af;\n border-radius: 4px;\n padding: 0.15rem 0.5rem;\n font-size: 0.75rem;\n font-weight: 600;\n margin-bottom: 0.5rem;\n }\n</style>\n\"\"\", unsafe_allow_html=True)\n\n# ── Session state ──────────────────────────────────────────────────────────────\n\nfor k, v in {\"client\": None, \"provider\": None, \"docs\": {}, \"result\": None, \"mode\": \"summarize\"}.items():\n if k not in st.session_state:\n st.session_state[k] = v\n\n# ── Sidebar ────────────────────────────────────────────────────────────────────\n\nwith st.sidebar:\n st.header(\"Setup\")\n\n provider_label = st.selectbox(\"LLM Provider\", [\"Groq (free)\", \"OpenAI\"])\n provider = \"groq\" if \"Groq\" in provider_label else \"openai\"\n\n if provider == \"groq\":\n api_key = st.text_input(\n \"Groq API Key\", type=\"password\",\n placeholder=\"gsk_...\",\n value=os.getenv(\"GROQ_API_KEY\", \"\"),\n )\n st.caption(\"Free key at [console.groq.com/keys](https://console.groq.com/keys)\")\n else:\n api_key = st.text_input(\n \"OpenAI API Key\", type=\"password\",\n placeholder=\"sk-...\",\n value=os.getenv(\"OPENAI_API_KEY\", \"\"),\n )\n\n ready = bool(api_key)\n if ready:\n st.session_state.client = make_client(api_key, provider)\n st.session_state.provider = provider\n\n st.divider()\n st.subheader(\"Mode\")\n mode = st.radio(\"\", [\"Summarize\", \"Compare documents\"], label_visibility=\"collapsed\")\n st.session_state.mode = \"compare\" if \"Compare\" in mode else \"summarize\"\n\n st.divider()\n st.subheader(\"Upload documents\")\n\n MAX_PDF_MB = 10\n uploaded = st.file_uploader(\n \"PDF files\",\n type=\"pdf\",\n accept_multiple_files=(st.session_state.mode == \"compare\"),\n label_visibility=\"collapsed\",\n )\n\n paste_label = st.text_input(\"Document name (for paste)\", value=\"Policy\")\n pasted = st.text_area(\"Or paste text\", height=140, label_visibility=\"collapsed\")\n\n if st.button(\"Add pasted text\", use_container_width=True, disabled=not pasted.strip()):\n st.session_state.docs[paste_label] = pasted.strip()\n st.success(f\"Added: {paste_label}\")\n\n if uploaded:\n files = uploaded if isinstance(uploaded, list) else [uploaded]\n for f in files:\n if f.name not in st.session_state.docs:\n if f.size > MAX_PDF_MB * 1024 * 1024:\n st.error(f\"{f.name} exceeds {MAX_PDF_MB} MB limit.\")\n else:\n text = \"\\n\\n\".join(\n page.extract_text() or \"\"\n for page in PdfReader(io.BytesIO(f.read())).pages\n )\n st.session_state.docs[f.name] = text\n st.success(f\"Loaded: {f.name}\")\n\n if st.session_state.docs:\n st.caption(f\"{len(st.session_state.docs)} document(s) loaded:\")\n for name in st.session_state.docs:\n col1, col2 = st.columns([4, 1])\n col1.write(f\"- {name}\")\n if col2.button(\"x\", key=f\"del_{name}\"):\n del st.session_state.docs[name]\n st.rerun()\n\n if st.button(\"Clear all\", use_container_width=True):\n st.session_state.docs = {}\n st.session_state.result = None\n st.rerun()\n\n# ── Main ────────────────────────────────────────────────────────────────────────\n\nst.title(\"Policy Summarizer\")\nst.caption(\"Upload dense policy documents — get plain-language summaries, key actions, and side-by-side comparisons.\")\n\nif not ready:\n st.info(\"Enter your API key in the sidebar to get started.\")\n st.stop()\n\nif not st.session_state.docs:\n st.info(\"Upload a PDF or paste policy text in the sidebar.\")\n st.stop()\n\ncol_run, col_dl = st.columns([3, 1])\n\nwith col_run:\n if st.session_state.mode == \"summarize\":\n doc_name = st.selectbox(\"Select document to summarize\", list(st.session_state.docs.keys()))\n run_label = \"Summarize\"\n else:\n if len(st.session_state.docs) < 2:\n st.warning(\"Load at least 2 documents to compare.\")\n st.stop()\n run_label = f\"Compare {len(st.session_state.docs)} documents\"\n\nif st.button(run_label, type=\"primary\", use_container_width=True):\n with st.spinner(\"Analysing...\"):\n try:\n if st.session_state.mode == \"summarize\":\n result = summarise(\n st.session_state.docs[doc_name],\n st.session_state.client,\n st.session_state.provider,\n )\n else:\n result = compare(\n st.session_state.docs,\n st.session_state.client,\n st.session_state.provider,\n )\n st.session_state.result = result\n except RuntimeError as e:\n st.error(str(e))\n\nif st.session_state.result:\n st.divider()\n st.markdown(\n f'<div class=\"badge\">{\"Summary\" if st.session_state.mode == \"summarize\" else \"Comparison\"}</div>',\n unsafe_allow_html=True,\n )\n st.markdown(st.session_state.result)\n st.download_button(\n \"Download as Markdown\",\n data=st.session_state.result,\n file_name=\"policy_summary.md\",\n mime=\"text/markdown\",\n )\n"}}}} |