nikeshn commited on
Commit
d15c5ee
·
verified ·
1 Parent(s): f5e7077

Delete openalex.py

Browse files
Files changed (1) hide show
  1. openalex.py +0 -88
openalex.py DELETED
@@ -1,88 +0,0 @@
1
- """
2
- OpenAlex enrichment — journal metadata + peer percentile calculation.
3
- Free API, no key required. Uses polite pool with mailto header.
4
- """
5
- import httpx, asyncio
6
- from typing import Optional
7
-
8
- UA = "ResearchNavigator/1.0 (mailto:library@ku.ac.ae)"
9
- BASE = "https://api.openalex.org"
10
-
11
- def _norm_issn(raw: str) -> Optional[str]:
12
- if not raw: return None
13
- d = raw.strip().upper().replace(" ","").replace("-","")
14
- if len(d) == 8:
15
- return f"{d[:4]}-{d[4:]}"
16
- return None
17
-
18
- async def enrich_journal(name: str, issn: Optional[str]) -> Optional[dict]:
19
- try:
20
- async with httpx.AsyncClient(timeout=8.0) as client:
21
- if issn:
22
- clean = _norm_issn(issn) or issn.strip()
23
- r = await client.get(f"{BASE}/sources/issn:{clean}", headers={"User-Agent": UA})
24
- else:
25
- r = await client.get(f"{BASE}/sources", params={"search": name, "per_page": 1}, headers={"User-Agent": UA})
26
- if not r.is_success: return None
27
- d = r.json()
28
- s = d if issn else (d.get("results") or [None])[0]
29
- if not s: return None
30
- return {
31
- "openalex_id": s.get("id"),
32
- "display_name": s.get("display_name"),
33
- "issn_l": s.get("issn_l"),
34
- "issns": s.get("issn", []),
35
- "host_organization": s.get("host_organization_name"),
36
- "is_oa": s.get("is_oa"),
37
- "is_in_doaj": s.get("is_in_doaj"),
38
- "works_count": s.get("works_count"),
39
- "cited_by_count": s.get("cited_by_count"),
40
- "h_index": (s.get("summary_stats") or {}).get("h_index"),
41
- "two_yr_mean_citedness": (s.get("summary_stats") or {}).get("2yr_mean_citedness"),
42
- "homepage_url": s.get("homepage_url"),
43
- "top_concept": ((s.get("x_concepts") or [{}])[0]).get("display_name"),
44
- "top_concept_id": ((s.get("x_concepts") or [{}])[0]).get("id"),
45
- }
46
- except Exception as e:
47
- print(f"[OpenAlex] enrich error for {name}: {e}")
48
- return None
49
-
50
- async def compute_percentile(openalex: dict) -> Optional[dict]:
51
- try:
52
- if not openalex or not openalex.get("top_concept_id"): return None
53
- val = openalex.get("two_yr_mean_citedness")
54
- if val is None: return None
55
- concept_id = str(openalex["top_concept_id"]).split("/")[-1]
56
- async with httpx.AsyncClient(timeout=10.0) as client:
57
- r = await client.get(
58
- f"{BASE}/sources",
59
- params={"filter": f"concepts.id:{concept_id},type:journal",
60
- "per_page": 200, "sort": "summary_stats.2yr_mean_citedness:desc"},
61
- headers={"User-Agent": UA}
62
- )
63
- if not r.is_success: return None
64
- peers = [s.get("summary_stats", {}).get("2yr_mean_citedness")
65
- for s in r.json().get("results", [])]
66
- peers = [v for v in peers if isinstance(v, (int, float))]
67
- if len(peers) < 10: return None
68
- below = sum(1 for v in peers if v < val)
69
- pct = round(below / len(peers) * 100)
70
- q = "Q1" if pct >= 75 else "Q2" if pct >= 50 else "Q3" if pct >= 25 else "Q4"
71
- return {"percentile": pct, "quartile": q,
72
- "peer_count": len(peers), "concept": openalex.get("top_concept")}
73
- except Exception as e:
74
- print(f"[OpenAlex] percentile error: {e}")
75
- return None
76
-
77
- async def enrich_all(journals: list) -> list:
78
- """Enrich a list of journal dicts in parallel."""
79
- async def _enrich_one(j: dict) -> dict:
80
- oa = await enrich_journal(j.get("name",""), j.get("issn"))
81
- pct = await compute_percentile(oa) if oa else None
82
- j["openalex"] = oa
83
- j["oa_percentile"] = pct
84
- # Supplement ISSN from OpenAlex if missing
85
- if not j.get("issn") and oa:
86
- j["issn"] = oa.get("issn_l") or (oa.get("issns") or [None])[0]
87
- return j
88
- return list(await asyncio.gather(*[_enrich_one(j) for j in journals]))