ChaoticEconomist commited on
Commit
718c553
·
verified ·
1 Parent(s): 4ff7dcd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +109 -157
app.py CHANGED
@@ -1,178 +1,130 @@
1
  import gradio as gr
2
- import fitz # PyMuPDF
3
  import requests
4
  import os
 
 
 
5
 
6
  # -----------------------------
7
- # CONFIG
8
  # -----------------------------
9
- XAI_API_KEY = os.getenv("XAI_API_KEY")
10
- XAI_URL = "https://api.x.ai/v1/chat/completions"
11
 
12
-
13
- # -----------------------------
14
- # PDF TEXT EXTRACTION
15
- # -----------------------------
16
- def extract_text(file):
17
- try:
18
- doc = fitz.open(file.name)
19
- text = ""
20
- for page in doc:
21
- text += page.get_text()
22
- return text[:20000]
23
- except Exception as e:
24
- return f"Error reading PDF: {str(e)}"
25
-
26
-
27
- # -----------------------------
28
- # GROK CALL
29
- # -----------------------------
30
  def call_grok(prompt):
31
- headers = {
32
- "Authorization": f"Bearer {XAI_API_KEY}",
33
- "Content-Type": "application/json"
34
- }
35
-
36
- data = {
37
  "model": "grok-4-1-fast-non-reasoning",
38
  "messages": [
39
- {"role": "system", "content": "You are an expert AI research analyst."},
40
  {"role": "user", "content": prompt}
41
  ],
42
- "temperature": 0.7
43
  }
44
-
45
  try:
46
- response = requests.post(XAI_URL, headers=headers, json=data, timeout=60)
47
- result = response.json()
48
- return result["choices"][0]["message"]["content"]
49
  except Exception as e:
50
- return f"API Error: {str(e)} | {response.text if 'response' in locals() else ''}"
51
-
52
 
53
  # -----------------------------
54
- # MAIN ANALYSIS PIPELINE
55
  # -----------------------------
56
- def analyze_paper(file):
57
- if file is None:
58
- return ["❌ Please upload a PDF."]
59
-
60
- text = extract_text(file)
61
-
62
- prompt = f"""
63
- Analyze this research paper and return a structured explanation.
64
-
65
- FORMAT STRICTLY as sections with clear headings:
66
-
67
- # 🧠 Core Idea
68
- # Research Question
69
- # 🏗 Problem It Solves
70
- # ⚙️ Methodology
71
- # 📊 Data & Experiments
72
- # 🧮 Math Explained Simply
73
- # 📈 Key Results
74
- # 💡 Key Insights
75
- # ⚠️ Limitations
76
- # 🧠 AI Critique
77
- # 👨‍🔬 About the Authors
78
- # 🔗 Related Concepts
79
- # 🧾 Summary
80
-
81
- Rules:
82
- - Explain clearly and deeply
83
- - Simplify math intuitively
84
- - Be insightful, not generic
85
- - No fluff
86
-
87
- Paper:
88
- {text}
89
- """
90
-
91
- result = call_grok(prompt)
92
-
93
- # Split into sections by headings
94
- sections = [s.strip() for s in result.split("\n#") if s.strip()]
95
- sections = [("#" + s) if not s.startswith("#") else s for s in sections]
96
-
97
- return sections
98
-
99
-
100
- # -----------------------------
101
- # DEEP EXPLAIN (PER SECTION)
102
- # -----------------------------
103
- def explain_section(section):
104
- if not section:
105
- return ""
106
-
107
- prompt = f"""
108
- Explain this section of a research paper in more depth.
109
-
110
- - Make it easier to understand
111
- - Add intuition
112
- - Give examples if possible
113
-
114
- Section:
115
- {section}
116
- """
117
- return call_grok(prompt)
118
-
119
-
120
- # -----------------------------
121
- # BUILD UI
122
- # -----------------------------
123
- with gr.Blocks(title="arXivForMe") as app:
124
-
125
- gr.Markdown("# 📄 arXivForMe")
126
- gr.Markdown("Understand any research paper from arXiv in minutes")
127
-
128
- file_input = gr.File(label="Upload PDF", file_types=[".pdf"])
129
- analyze_btn = gr.Button("🚀 Analyze Paper")
130
-
131
- sections_state = gr.State([])
132
-
133
- section_dropdown = gr.Dropdown(label="Sections", choices=[])
134
- section_output = gr.Markdown()
135
-
136
- explain_btn = gr.Button("🧠 Explain Deeper")
137
- deep_output = gr.Markdown()
138
-
139
- # -----------------------------
140
- # EVENTS
141
- # -----------------------------
142
-
143
- def update_dropdown(sections):
144
- return gr.update(choices=[f"Section {i}" for i in range(len(sections))])
145
-
146
- def show_section(sections, idx):
147
- if idx is None:
148
- return ""
149
- return sections[int(idx.split()[-1])]
150
-
151
- analyze_btn.click(
152
- analyze_paper,
153
- inputs=file_input,
154
- outputs=sections_state
155
- ).then(
156
- update_dropdown,
157
- inputs=sections_state,
158
- outputs=section_dropdown
159
- )
160
-
161
- section_dropdown.change(
162
- show_section,
163
- inputs=[sections_state, section_dropdown],
164
- outputs=section_output
165
- )
166
-
167
- explain_btn.click(
168
- explain_section,
169
- inputs=section_output,
170
- outputs=deep_output
171
- )
172
-
173
 
174
  # -----------------------------
175
- # LAUNCH
176
  # -----------------------------
177
- if __name__ == "__main__":
178
- app.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
 
2
  import requests
3
  import os
4
+ import arxiv
5
+ import io
6
+ from pypdf import PdfReader
7
 
8
  # -----------------------------
9
+ # LLM ENGINE (Grok-4)
10
  # -----------------------------
11
+ API_KEY = os.getenv("XAI_API_KEY")
12
+ API_URL = "https://api.x.ai/v1/chat/completions"
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  def call_grok(prompt):
15
+ headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
16
+ payload = {
 
 
 
 
17
  "model": "grok-4-1-fast-non-reasoning",
18
  "messages": [
19
+ {"role": "system", "content": "You are an expert polymath, research scientist, and critic. Use LaTeX for math ($...$ or $$...$$). Be dense, technical, and objective."},
20
  {"role": "user", "content": prompt}
21
  ],
22
+ "temperature": 0.15
23
  }
 
24
  try:
25
+ response = requests.post(API_URL, headers=headers, json=payload, timeout=60)
26
+ return response.json()["choices"][0]["message"]["content"]
 
27
  except Exception as e:
28
+ return f"LLM Error: {str(e)}"
 
29
 
30
  # -----------------------------
31
+ # THE ENGINE ROOM
32
  # -----------------------------
33
+ def analyze_full_paper(url):
34
+ try:
35
+ # 1. Fetch Metadata
36
+ paper_id = url.split('/')[-1].split('v')[0]
37
+ search = arxiv.Search(id_list=[paper_id])
38
+ paper = next(search.results())
39
+
40
+ # 2. Extract PDF Text (Targeting the first 10 pages for depth)
41
+ resp = requests.get(paper.pdf_url)
42
+ reader = PdfReader(io.BytesIO(resp.content))
43
+ content = "".join([page.extract_text() for page in reader.pages[:10]])
44
+
45
+ # 3. Master Prompt
46
+ prompt = f"""
47
+ PAPER: {paper.title}
48
+ AUTHORS: {', '.join([a.name for a in paper.authors])}
49
+ CONTENT: {content[:15000]}
50
+
51
+ Provide an exhaustive breakdown using these EXACT markers:
52
+ [SUMMARY] - High-level TL;DR.
53
+ [PROBLEM] - The specific research gap.
54
+ [IDEAS] - The core conceptual innovations.
55
+ [THEORY] - The formal mathematical framework (Use LaTeX).
56
+ [ALGO] - The implementation logic or pseudocode.
57
+ [FINDINGS] - Data, benchmarks, and results.
58
+ [AUTHORS] - Evaluation of the authors' expertise and potential institutional bias.
59
+ [VERDICT] - Brutal honest critique: What's good, what's bad, and is it overhyped?
60
+ """
61
+
62
+ raw_resp = call_grok(prompt)
63
+
64
+ # 4. Parse into Tabs
65
+ markers = ["[SUMMARY]", "[PROBLEM]", "[IDEAS]", "[THEORY]", "[ALGO]", "[FINDINGS]", "[AUTHORS]", "[VERDICT]"]
66
+ data = {m: "Section not generated." for m in markers}
67
+ current = None
68
+ for line in raw_resp.split('\n'):
69
+ if line.strip() in markers:
70
+ current = line.strip()
71
+ data[current] = ""
72
+ elif current:
73
+ data[current] += line + "\n"
74
+
75
+ return [paper.title] + [data[m] for m in markers]
76
+
77
+ except Exception as e:
78
+ return [f"Error: {str(e)}"] + [""] * 8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
  # -----------------------------
81
+ # THE DASHBOARD UI
82
  # -----------------------------
83
+ with gr.Blocks(theme=gr.themes.Default(primary_hue="orange", secondary_hue="slate"), title="arXivForMe Ultra") as demo:
84
+ gr.Markdown("# 🧬 arXivForMe: The Full Intelligence Suite")
85
+ gr.Markdown("*Deep-dive analysis of any arXiv paper: Theory, Math, and Critical Review.*")
86
+
87
+ with gr.Row():
88
+ url_input = gr.Textbox(label="arXiv URL", placeholder="https://arxiv.org/abs/2401.xxxxx", scale=4)
89
+ run_btn = gr.Button("RUN FULL ANALYSIS", variant="primary", scale=1)
90
+
91
+ paper_head = gr.HTML("<h2 style='text-align: center;'>Submit a paper to begin extraction</h2>")
92
+
93
+ with gr.Tabs():
94
+ with gr.Tab("📋 Executive Summary"):
95
+ with gr.Row():
96
+ with gr.Column():
97
+ gr.Markdown("### TL;DR")
98
+ out_sum = gr.Markdown()
99
+ with gr.Column():
100
+ gr.Markdown("### The Research Problem")
101
+ out_prob = gr.Markdown()
102
+
103
+ with gr.Tab("💡 Main Ideas"):
104
+ out_idea = gr.Markdown()
105
+
106
+ with gr.Tab("📐 Math & Theory"):
107
+ gr.Markdown("### Mathematical Framework")
108
+ out_theo = gr.Markdown()
109
+
110
+ with gr.Tab("💻 Algorithm"):
111
+ gr.Markdown("### Logic & Implementation")
112
+ out_algo = gr.Markdown()
113
+
114
+ with gr.Tab("📊 Findings"):
115
+ gr.Markdown("### Results & Benchmarks")
116
+ out_find = gr.Markdown()
117
+
118
+ with gr.Tab("👤 Author Analysis"):
119
+ gr.Markdown("### Reputation & Context")
120
+ out_auth = gr.Markdown()
121
+
122
+ with gr.Tab("⚖️ AI Opinion"):
123
+ gr.Markdown("### The Brutal Verdict")
124
+ out_verd = gr.Markdown()
125
+
126
+ output_list = [paper_head, out_sum, out_prob, out_idea, out_theo, out_algo, out_find, out_auth, out_verd]
127
+
128
+ run_btn.click(fn=analyze_full_paper, inputs=url_input, outputs=output_list)
129
+
130
+ demo.launch()