@@ -46,21 +46,28 @@ def doi2url(self, doi):
46
46
# Transform a DOI to a URL
47
47
# If not a doi, assume we have a URL and return
48
48
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
62
70
raise
63
- return resp .url
64
71
else :
65
72
# Just return what is actulally just a URL
66
73
return doi
0 commit comments