FOIA_Doc_Search / app.py
GodsDevProject's picture
Create app.py
9c8150d verified
raw
history blame
3.25 kB
import gradio as gr
import asyncio
from ingest.registry import get_live_adapters, get_stub_adapters
from ingest.export import export_results_zip
LIVE_ADAPTERS = get_live_adapters()
STUB_ADAPTERS = get_stub_adapters()
async def federated_search(query: str, include_stubs: bool):
results = []
for adapter in LIVE_ADAPTERS.values():
try:
res = await adapter.search(query)
results.extend(res)
except Exception:
continue
if include_stubs:
for adapter in STUB_ADAPTERS.values():
try:
res = await adapter.search(query)
results.extend(res)
except Exception:
continue
return results
def search_handler(query, include_stubs, confirm_extended):
if include_stubs and not confirm_extended:
return [], "⚠️ You must acknowledge the Extended Features warning."
if not query.strip():
return [], "⚠️ Enter a search term."
results = asyncio.run(federated_search(query, include_stubs))
rows = [
[r["source"], r["title"], r["url"], r["snippet"]]
for r in results
]
return rows, ""
with gr.Blocks() as app:
gr.Markdown(
"# **Federal FOIA Intelligence Search**\n"
"### Public Electronic Reading Rooms Only\n\n"
"Live, robots-compliant search across U.S. government FOIA libraries.\n\n"
"**Default mode queries only agencies that explicitly permit automated access.**"
)
query = gr.Textbox(
label="Search term",
placeholder="e.g. UAP, procurement, surveillance"
)
include_stubs = gr.Checkbox(
label="Include Stub Results (Non-Live, Informational Only)",
value=False
)
with gr.Accordion("⚠️ Extended Features (Advanced – Read Carefully)", open=False):
gr.Markdown(
"**The following agencies do NOT permit automated querying or do not "
"provide public FOIA search endpoints:**\n\n"
"- NSA\n- NRO\n- SAP / Special Access Programs\n- TEN-CAP\n"
"- AATIP\n- Special Activities\n- DIA\n- NGA\n\n"
"If enabled, these sources return **clearly labeled stub results only**. "
"**No live requests are made.**"
)
confirm_extended = gr.Checkbox(
label="I understand and want to include stub-only results",
value=False
)
search_btn = gr.Button("Search")
status = gr.Markdown("")
results_table = gr.Dataframe(
headers=["Source", "Title", "URL", "Snippet"],
wrap=True,
interactive=False
)
search_btn.click(
fn=search_handler,
inputs=[query, include_stubs, confirm_extended],
outputs=[results_table, status]
)
gr.Markdown("### Export")
export_btn = gr.Button("Export Results (ZIP)")
export_file = gr.File(label="Download ZIP")
export_btn.click(
fn=lambda rows: export_results_zip([
{
"source": r[0],
"title": r[1],
"url": r[2],
"snippet": r[3]
} for r in rows
]),
inputs=results_table,
outputs=export_file
)
app.launch()