zhiyi commited on
Commit
ea4f5df
·
1 Parent(s): e10073b

Retry slow arXiv and PDF requests

Browse files
Files changed (1) hide show
  1. app.py +40 -9
app.py CHANGED
@@ -5,6 +5,7 @@ import io
5
  import json
6
  import os
7
  import re
 
8
  import uuid
9
  import zipfile
10
  from datetime import datetime, timezone
@@ -54,6 +55,33 @@ def safe_slug(value: str) -> str:
54
  return (slug or "algorithm-topic")[:64]
55
 
56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  def arxiv_search(topic: str, limit: int) -> list[dict[str, Any]]:
58
  query = quote_plus(f'all:"{topic}"')
59
  url = (
@@ -62,9 +90,7 @@ def arxiv_search(topic: str, limit: int) -> list[dict[str, Any]]:
62
  "&sortBy=submittedDate&sortOrder=descending"
63
  )
64
  headers = {"User-Agent": f"algorithm-research-deck/1.0 ({os.getenv('CONTACT_EMAIL', 'contact-not-set')})"}
65
- with httpx.Client(timeout=30, follow_redirects=True, headers=headers) as client:
66
- response = client.get(url)
67
- response.raise_for_status()
68
  ns = {"a": "http://www.w3.org/2005/Atom"}
69
  root = ElementTree.fromstring(response.text)
70
  papers = []
@@ -167,11 +193,9 @@ def select_papers(request: ResearchRequest, papers: list[dict[str, Any]], screen
167
 
168
 
169
  def extract_pdf(paper: dict[str, Any], max_chars: int = 14000) -> str:
170
- with httpx.Client(timeout=45, follow_redirects=True) as client:
171
- response = client.get(paper["pdf_url"])
172
- response.raise_for_status()
173
- if len(response.content) > 20 * 1024 * 1024:
174
- return "PDF omitted because it exceeds the 20 MB limit."
175
  reader = PdfReader(io.BytesIO(response.content))
176
  pages = []
177
  indexes = list(range(min(8, len(reader.pages))))
@@ -304,7 +328,14 @@ def run_research_ui(
304
  )
305
  budget = DEPTHS[request.depth]
306
  progress(0.08, desc="正在检索 arXiv")
307
- papers = deduplicate(normalize_user_papers(request.paper_urls) + arxiv_search(request.topic, budget["discover"]))
 
 
 
 
 
 
 
308
  if not papers:
309
  raise gr.Error("没有检索到论文,请尝试英文关键词或提供 arXiv 链接。")
310
  screen = papers[: budget["screen"]]
 
5
  import json
6
  import os
7
  import re
8
+ import time
9
  import uuid
10
  import zipfile
11
  from datetime import datetime, timezone
 
55
  return (slug or "algorithm-topic")[:64]
56
 
57
 
58
+ def http_get_with_retries(
59
+ url: str,
60
+ *,
61
+ headers: dict[str, str] | None = None,
62
+ read_timeout: float = 90,
63
+ attempts: int = 3,
64
+ ) -> httpx.Response:
65
+ last_error: Exception | None = None
66
+ timeout = httpx.Timeout(connect=20, read=read_timeout, write=30, pool=30)
67
+ for attempt in range(attempts):
68
+ try:
69
+ with httpx.Client(
70
+ timeout=timeout,
71
+ follow_redirects=True,
72
+ headers=headers,
73
+ http2=False,
74
+ ) as client:
75
+ response = client.get(url)
76
+ response.raise_for_status()
77
+ return response
78
+ except (httpx.TimeoutException, httpx.NetworkError, httpx.RemoteProtocolError) as exc:
79
+ last_error = exc
80
+ if attempt + 1 < attempts:
81
+ time.sleep(2 + attempt * 3)
82
+ raise RuntimeError(f"External source did not respond after {attempts} attempts: {url}") from last_error
83
+
84
+
85
  def arxiv_search(topic: str, limit: int) -> list[dict[str, Any]]:
86
  query = quote_plus(f'all:"{topic}"')
87
  url = (
 
90
  "&sortBy=submittedDate&sortOrder=descending"
91
  )
92
  headers = {"User-Agent": f"algorithm-research-deck/1.0 ({os.getenv('CONTACT_EMAIL', 'contact-not-set')})"}
93
+ response = http_get_with_retries(url, headers=headers, read_timeout=90, attempts=3)
 
 
94
  ns = {"a": "http://www.w3.org/2005/Atom"}
95
  root = ElementTree.fromstring(response.text)
96
  papers = []
 
193
 
194
 
195
  def extract_pdf(paper: dict[str, Any], max_chars: int = 14000) -> str:
196
+ response = http_get_with_retries(paper["pdf_url"], read_timeout=120, attempts=3)
197
+ if len(response.content) > 20 * 1024 * 1024:
198
+ return "PDF omitted because it exceeds the 20 MB limit."
 
 
199
  reader = PdfReader(io.BytesIO(response.content))
200
  pages = []
201
  indexes = list(range(min(8, len(reader.pages))))
 
328
  )
329
  budget = DEPTHS[request.depth]
330
  progress(0.08, desc="正在检索 arXiv")
331
+ user_papers = normalize_user_papers(request.paper_urls)
332
+ try:
333
+ discovered_papers = arxiv_search(request.topic, budget["discover"])
334
+ except Exception as exc:
335
+ if not user_papers:
336
+ raise gr.Error(f"arXiv 连续三次请求超时。请稍后重试,或填写至少一个 arXiv 论文链接。详情:{exc}") from exc
337
+ discovered_papers = []
338
+ papers = deduplicate(user_papers + discovered_papers)
339
  if not papers:
340
  raise gr.Error("没有检索到论文,请尝试英文关键词或提供 arXiv 链接。")
341
  screen = papers[: budget["screen"]]