samwjya commited on
Commit
dce4654
·
1 Parent(s): 97bb518

change api source

Browse files
Files changed (1) hide show
  1. retriever.py +47 -11
retriever.py CHANGED
@@ -1,24 +1,60 @@
 
1
  import requests
2
  from rank_bm25 import BM25Okapi
3
 
4
 
5
- SEMANTIC_SCHOLAR_URL = "https://api.semanticscholar.org/graph/v1/paper/search"
6
- FIELDS = "title,abstract,year,authors,citationCount"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
 
9
  def fetch_papers(query: str, limit: int = 50) -> list[dict]:
10
- """Fetch candidate papers from the Semantic Scholar API."""
11
  params = {
12
- "query": query,
13
- "limit": limit,
14
- "fields": FIELDS,
15
  }
16
- response = requests.get(SEMANTIC_SCHOLAR_URL, params=params, timeout=15)
17
  response.raise_for_status()
18
- data = response.json()
19
- papers = data.get("data", [])
20
- # Drop papers with no abstract — BM25 and reranker both need text
21
- return [p for p in papers if p.get("abstract")]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
 
24
  def tokenize(text: str) -> list[str]:
 
1
+ import os
2
  import requests
3
  from rank_bm25 import BM25Okapi
4
 
5
 
6
+ OPEN_ALEX_URL = "https://api.openalex.org/works"
7
+
8
+
9
+ def _load_api_key() -> str:
10
+ env_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), ".env")
11
+ with open(env_path) as f:
12
+ for line in f:
13
+ if line.startswith("OPEN_ALEX_API="):
14
+ return line.strip().split("=", 1)[1]
15
+ return ""
16
+
17
+
18
+ def _reconstruct_abstract(inverted_index: dict) -> str:
19
+ """OpenAlex stores abstracts as an inverted index; reconstruct plain text."""
20
+ if not inverted_index:
21
+ return ""
22
+ max_pos = max(pos for positions in inverted_index.values() for pos in positions)
23
+ words = [""] * (max_pos + 1)
24
+ for word, positions in inverted_index.items():
25
+ for pos in positions:
26
+ words[pos] = word
27
+ return " ".join(words)
28
 
29
 
30
  def fetch_papers(query: str, limit: int = 50) -> list[dict]:
31
+ """Fetch candidate papers from the OpenAlex API."""
32
  params = {
33
+ "search.semantic": query,
34
+ "per_page": min(limit, 200),
35
+ "api_key": _load_api_key(),
36
  }
37
+ response = requests.get(OPEN_ALEX_URL, params=params, timeout=15)
38
  response.raise_for_status()
39
+ raw_papers = response.json().get("results", [])
40
+
41
+ papers = []
42
+ for p in raw_papers:
43
+ abstract = _reconstruct_abstract(p.get("abstract_inverted_index") or {})
44
+ if not abstract:
45
+ continue
46
+ papers.append({
47
+ "title": p.get("title") or "",
48
+ "abstract": abstract,
49
+ "year": p.get("publication_year"),
50
+ "citationCount": p.get("cited_by_count"),
51
+ "authors": [
52
+ {"name": a["author"]["display_name"]}
53
+ for a in p.get("authorships", [])
54
+ if a.get("author") and a["author"].get("display_name")
55
+ ],
56
+ })
57
+ return papers
58
 
59
 
60
  def tokenize(text: str) -> list[str]: