Source code for app.model.lib.crossref_fetcher
import requests
import re
[docs]
class CrossrefFetcher:
"""
This class encapsulates requests to api.crossref.org to get information
about a publication based on its DOI. For now, it only fetches the author
list and the title of a study.
"""
def __init__(self, doi):
self._response_json = None
[docs]
def make_request(self):
# Author records for linking and searching:
quoted_doi = requests.utils.quote(self.doi)
crossref_url = f"https://api.crossref.org/works/{quoted_doi}"
response = requests.get(crossref_url)
if response.status_code == 404:
raise ValueError("Couldn't find publication")
if response.status_code != 200:
raise ValueError(f"Couldn't reach Crossref API (Status {response.status_code})")
self._response_json = response.json()
if self._response_json["status"] != "ok":
raise ValueError("The Crossref API didn't return a successful result")
message_field = self._response_json.get("message", {})
title_field = message_field.get("title", [])
if canonical_doi := message_field.get("DOI"):
self.doi = f"https://doi.org/{canonical_doi}"
self.title = title_field[0] if len(title_field) else ''
self.authors = message_field.get("author", [])
self.author_cache = ', '.join([a['family'].lower() for a in self.authors])
licenses = message_field.get("license", [])
if len(licenses):
self.license_url = licenses[0].get("URL")
for key in ['published-online', 'published-print', 'published']:
publication_date_parts = message_field.get(key, {}).get("date-parts", [])
if len(publication_date_parts):
self.publication_date = '-'.join([f"{int(str(part)):02}" for part in publication_date_parts[0]])
break
if resource_url := message_field.get('resource', {}).get('primary', {}).get('URL'):
if re.match(r'https?://(www.)?biorxiv.org/', resource_url):
self.publication_type = 'preprint'
else:
self.publication_type = 'publication'
else:
self.publication_type = 'dataset'