Skip to content

Commit 91242e5

Browse files
committed
Use the doi.org API to resolve URLs
1 parent f0b1c0c commit 91242e5

File tree

1 file changed

+21
-14
lines changed
  • repo2docker/contentproviders

1 file changed

+21
-14
lines changed

repo2docker/contentproviders/doi.py

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,28 @@ def doi2url(self, doi):
4646
# Transform a DOI to a URL
4747
# If not a doi, assume we have a URL and return
4848
if is_doi(doi):
49-
doi = normalize_doi(doi)
50-
51-
try:
52-
resp = self._request(f"https://doi.org/{doi}")
53-
resp.raise_for_status()
54-
except HTTPError as e:
55-
# If the DOI doesn't exist, just return URL
56-
if e.response.status_code == 404:
57-
return doi
58-
# Reraise any other errors because if the DOI service is down (or
59-
# we hit a rate limit) we don't want to silently continue to the
60-
# default Git provider as this leads to a misleading error.
61-
self.log.error(f"DOI {doi} does not resolve: {e}")
49+
normalized_doi = normalize_doi(doi)
50+
51+
# Use the doi.org resolver API
52+
# documented at https://www.doi.org/the-identifier/resources/factsheets/doi-resolution-documentation#5-proxy-server-rest-api
53+
req_url = f"https://doi.org/api/handles/{normalize_doi}"
54+
resp = self._request(req_url)
55+
if resp.status_code == 404:
56+
# Not a doi, return what we were passed in
57+
return doi
58+
elif resp.status_code == 200:
59+
data = resp.json()
60+
# Pick the first URL we find from the doi response
61+
for v in data["values"]:
62+
if v["type"] == "URL":
63+
return v["data"]["string"]
64+
65+
# No URLs found for this doi, what do we do?
66+
self.log.error("DOI {normalized_doi} doesn't point to any URLs")
67+
return doi
68+
else:
69+
# If we get any other status codes, raise error
6270
raise
63-
return resp.url
6471
else:
6572
# Just return what is actulally just a URL
6673
return doi

0 commit comments

Comments
 (0)