Lilymutinda commited on
Commit
9cdb5b6
·
verified ·
1 Parent(s): 3dab80a

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +76 -0
app.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ from pypdf import PdfReader
4
+
5
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
6
+ from langchain_community.vectorstores import FAISS
7
+ from langchain_openai import OpenAIEmbeddings, ChatOpenAI
8
+ from langchain.schema import Document
9
+
10
+ APP_TITLE = "Election Memory Engine"
11
+ APP_TAGLINE = "Ask your newsroom archive anything — with sources."
12
+
13
+ def read_pdf(file_path: str) -> str:
14
+ reader = PdfReader(file_path)
15
+ pages = []
16
+ for p in reader.pages:
17
+ pages.append(p.extract_text() or "")
18
+ return "\n".join(pages)
19
+
20
+ def build_index(files):
21
+ docs = []
22
+ for f in files:
23
+ text = read_pdf(f.name)
24
+ source_name = os.path.basename(f.name)
25
+ docs.append(Document(page_content=text, metadata={"source": source_name}))
26
+
27
+ splitter = RecursiveCharacterTextSplitter(chunk_size=900, chunk_overlap=120)
28
+ chunks = splitter.split_documents(docs)
29
+
30
+ embeddings = OpenAIEmbeddings()
31
+ index = FAISS.from_documents(chunks, embeddings)
32
+ return index
33
+
34
+ def answer_question(index, question):
35
+ retriever = index.as_retriever(search_kwargs={"k": 4})
36
+ hits = retriever.get_relevant_documents(question)
37
+
38
+ context = ""
39
+ for i, d in enumerate(hits, start=1):
40
+ context += f"\n[Source {i}: {d.metadata['source']}]\n{d.page_content[:700]}\n"
41
+
42
+ llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.2)
43
+
44
+ prompt = f"""
45
+ You are an archive assistant for an election newsroom.
46
+ Answer using ONLY the context below.
47
+ Include which sources you used.
48
+
49
+ Question: {question}
50
+
51
+ Context:
52
+ {context}
53
+ """
54
+
55
+ return llm.invoke(prompt).content
56
+
57
+ with gr.Blocks() as demo:
58
+ gr.Markdown(f"# {APP_TITLE}")
59
+ gr.Markdown(APP_TAGLINE)
60
+
61
+ index_state = gr.State()
62
+
63
+ uploader = gr.File(file_types=[".pdf"], file_count="multiple")
64
+ build_btn = gr.Button("Build Memory")
65
+ question = gr.Textbox(label="Ask a question")
66
+ ask_btn = gr.Button("Ask")
67
+ output = gr.Markdown()
68
+
69
+ def build(files):
70
+ index = build_index(files)
71
+ return index
72
+
73
+ build_btn.click(build, uploader, index_state)
74
+ ask_btn.click(answer_question, [index_state, question], output)
75
+
76
+ demo.launch()