60 lines
1.9 KiB
Python
60 lines
1.9 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Search the Semantic Scholar Graph API. No API key required for light use;
|
|
set the S2_API_KEY environment variable for higher rate limits.
|
|
|
|
CLI usage:
|
|
python3 search_semantic_scholar.py "UAV magnetic compensation" --max 10
|
|
|
|
Importable:
|
|
from search_semantic_scholar import search_s2
|
|
"""
|
|
import sys
|
|
import os
|
|
import json
|
|
import argparse
|
|
import urllib.request
|
|
import urllib.parse
|
|
|
|
S2_API = "https://api.semanticscholar.org/graph/v1/paper/search"
|
|
FIELDS = "title,authors,year,venue,externalIds,abstract,citationCount"
|
|
|
|
|
|
def search_s2(query, max_results=10, timeout=20):
|
|
params = {"query": query, "limit": max_results, "fields": FIELDS}
|
|
url = f"{S2_API}?{urllib.parse.urlencode(params)}"
|
|
req = urllib.request.Request(url)
|
|
api_key = os.environ.get("S2_API_KEY")
|
|
if api_key:
|
|
req.add_header("x-api-key", api_key)
|
|
with urllib.request.urlopen(req, timeout=timeout) as resp:
|
|
data = json.loads(resp.read())
|
|
results = []
|
|
for p in data.get("data", []) or []:
|
|
ext = p.get("externalIds") or {}
|
|
results.append({
|
|
"source": "semantic_scholar",
|
|
"title": p.get("title"),
|
|
"authors": [a.get("name") for a in (p.get("authors") or [])],
|
|
"year": p.get("year"),
|
|
"venue": p.get("venue"),
|
|
"doi": ext.get("DOI"),
|
|
"arxiv_id": ext.get("ArXiv"),
|
|
"abstract": p.get("abstract"),
|
|
"citation_count": p.get("citationCount"),
|
|
})
|
|
return results
|
|
|
|
|
|
if __name__ == "__main__":
|
|
ap = argparse.ArgumentParser(description=__doc__)
|
|
ap.add_argument("query")
|
|
ap.add_argument("--max", type=int, default=10)
|
|
args = ap.parse_args()
|
|
try:
|
|
out = search_s2(args.query, args.max)
|
|
print(json.dumps(out, ensure_ascii=False, indent=2))
|
|
except Exception as e:
|
|
print(json.dumps({"error": str(e)}, ensure_ascii=False))
|
|
sys.exit(1)
|