fix(sources): resolve arXiv IDs via arXiv DOI (OpenAlex /works/arxiv: 404s) #5
@@ -25,17 +25,21 @@ _BASE = "https://api.openalex.org"
|
|||||||
|
|
||||||
|
|
||||||
def _resolve_id(id: str) -> str:
|
def _resolve_id(id: str) -> str:
|
||||||
"""Prefix a bare DOI or arXiv ID for the OpenAlex /works/ endpoint.
|
"""Resolve a bare DOI or arXiv ID for the OpenAlex /works/ endpoint.
|
||||||
|
|
||||||
OpenAlex accepts: doi:<doi>, arxiv:<id>, W-IDs, or full https:// URLs.
|
OpenAlex resolves DOIs, W-IDs and full https:// URLs in the /works/ path,
|
||||||
Bare DOIs (starting with "10.") and bare arXiv IDs require a prefix.
|
but NOT the ``arxiv:`` namespace (that path 404s). arXiv papers are looked
|
||||||
|
up via their arXiv DOI ``10.48550/arXiv.<id>`` instead — accepted by
|
||||||
|
OpenAlex for both modern (``2301.07041``) and legacy (``math/0603097``) IDs.
|
||||||
"""
|
"""
|
||||||
s = id.strip()
|
s = id.strip()
|
||||||
if s.startswith(("W", "https://", "doi:", "arxiv:")):
|
if s.lower().startswith("arxiv:"):
|
||||||
|
s = s[len("arxiv:") :]
|
||||||
|
if s.startswith(("W", "https://", "doi:")):
|
||||||
return s
|
return s
|
||||||
if s.startswith("10."):
|
if s.startswith("10."):
|
||||||
return f"doi:{s}"
|
return f"doi:{s}"
|
||||||
return f"arxiv:{s}"
|
return f"doi:10.48550/arXiv.{s}"
|
||||||
|
|
||||||
|
|
||||||
def _is_retryable(exc: BaseException) -> bool:
|
def _is_retryable(exc: BaseException) -> bool:
|
||||||
|
|||||||
@@ -45,7 +45,18 @@ def test_resolve_doi() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_resolve_arxiv() -> None:
|
def test_resolve_arxiv() -> None:
|
||||||
assert _resolve_id("2301.07041") == "arxiv:2301.07041"
|
# arXiv IDs resolve to their arXiv DOI (the arxiv: path 404s on OpenAlex).
|
||||||
|
assert _resolve_id("2301.07041") == "doi:10.48550/arXiv.2301.07041"
|
||||||
|
|
||||||
|
|
||||||
|
def test_resolve_arxiv_legacy() -> None:
|
||||||
|
# Legacy category/number IDs (pre-2007) resolve the same way.
|
||||||
|
assert _resolve_id("math/0603097") == "doi:10.48550/arXiv.math/0603097"
|
||||||
|
|
||||||
|
|
||||||
|
def test_resolve_arxiv_prefix_stripped() -> None:
|
||||||
|
# An explicit arxiv: prefix is stripped before building the arXiv DOI.
|
||||||
|
assert _resolve_id("arxiv:2301.07041") == "doi:10.48550/arXiv.2301.07041"
|
||||||
|
|
||||||
|
|
||||||
def test_resolve_w_id_unchanged() -> None:
|
def test_resolve_w_id_unchanged() -> None:
|
||||||
@@ -54,7 +65,6 @@ def test_resolve_w_id_unchanged() -> None:
|
|||||||
|
|
||||||
def test_resolve_prefixed_unchanged() -> None:
|
def test_resolve_prefixed_unchanged() -> None:
|
||||||
assert _resolve_id("doi:10.1145/x") == "doi:10.1145/x"
|
assert _resolve_id("doi:10.1145/x") == "doi:10.1145/x"
|
||||||
assert _resolve_id("arxiv:2301.07041") == "arxiv:2301.07041"
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -83,7 +93,7 @@ def test_fetch_paper_success(monkeypatch: pytest.MonkeyPatch) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_fetch_paper_arxiv_id_prefixed(monkeypatch: pytest.MonkeyPatch) -> None:
|
def test_fetch_paper_arxiv_id_prefixed(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
"""Bare arXiv IDs are prefixed with 'arxiv:' in the URL."""
|
"""Bare arXiv IDs are resolved to their arXiv DOI in the URL."""
|
||||||
called_url: list[str] = []
|
called_url: list[str] = []
|
||||||
|
|
||||||
def mock_get(url: str, params: dict[str, str] | None = None) -> httpx.Response:
|
def mock_get(url: str, params: dict[str, str] | None = None) -> httpx.Response:
|
||||||
@@ -93,7 +103,7 @@ def test_fetch_paper_arxiv_id_prefixed(monkeypatch: pytest.MonkeyPatch) -> None:
|
|||||||
monkeypatch.setattr(openalex, "_get", mock_get)
|
monkeypatch.setattr(openalex, "_get", mock_get)
|
||||||
openalex.fetch_paper("2301.07041")
|
openalex.fetch_paper("2301.07041")
|
||||||
|
|
||||||
assert called_url and "arxiv:2301.07041" in called_url[0]
|
assert called_url and "doi:10.48550/arXiv.2301.07041" in called_url[0]
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user