From c183df6af9b00dee5bd0293dfa595d6f7b05b0d5 Mon Sep 17 00:00:00 2001 From: vuillaut <thomas.vuillaume@gmail.com> Date: Tue, 14 Sep 2021 16:58:23 +0200 Subject: [PATCH] add zenodo Record class and basic zenodo search function --- eossr/api/zenodo.py | 74 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/eossr/api/zenodo.py b/eossr/api/zenodo.py index 36b0ef88..6860addf 100644 --- a/eossr/api/zenodo.py +++ b/eossr/api/zenodo.py @@ -6,8 +6,11 @@ import pprint import requests from os.path import abspath from pathlib import Path +from urllib.parse import urlencode from ..metadata.codemeta2zenodo import parse_codemeta_and_write_zenodo_metadata_file +zenodo_api_url = "https://zenodo.org/api" + class ZenodoAPI: def __init__(self, access_token, sandbox=True, proj_root_dir='./'): @@ -38,11 +41,10 @@ class ZenodoAPI: """ if sandbox: - zenodo_api_url = "https://sandbox.zenodo.org/api" + self.zenodo_api_url = "https://sandbox.zenodo.org/api" else: - zenodo_api_url = "https://zenodo.org/api" + self.zenodo_api_url = zenodo_api_url - self.zenodo_api_url = zenodo_api_url self.access_token = access_token self.parameters = {'access_token': self.access_token} @@ -401,3 +403,69 @@ class ZenodoAPI: "`OSSR how to publish tutorial`:\n" "\t https://escape2020.pages.in2p3.fr/wp3/ossr-pages/page/contribute/publish_tutorial/#3-add-the-following-code-snippet \n" "In case you do, please contact us !\n") + + +class Record: + + def __init__(self, data: dict): + for k in ['id', 'metadata', 'files', 'links']: + if k not in data.keys(): + raise ValueError(f"key {k} not present in data") + self.data = data + + def __str__(self): + entry_id = self.data['id'] + metadata = self.data['metadata'] + return f"Record #{entry_id} : {metadata['title']}" + + def __repr__(self): + return f"Record({self.data})" + + def print_info(self): + entry_id = self.data['id'] + metadata = self.data['metadata'] + descrp = metadata['description'] + print(f"=== Record #{entry_id} ===") + print(f"Title: {metadata['title']} ===") + print(f"DOI: {self.data['doi']}") + print(f"URL: {self.data['links']['html']}") + print(f"Description:\n{descrp}") + print('\n') + + +def get_zenodo_records(search='', **kwargs) -> list[Record]: + """ + Search the ossr based on `search`. + Function rewritten from pyzenodo3 (https://github.com/space-physics/pyzenodo3) + + :param search: string + :param kwargs: Zenodo query arguments. + For an exhaustive list, see the query arguments at https://developers.zenodo.org/#list36 + Common arguments are: + - size: int + Number of results to return + - all_versions: int + Show (1) or hide (0) all versions of records + - type: string + Records of the specified type (Publication, Poster, Presentation, Software, ...) + - keywords: string + Records with the specified keywords + + :return: + list of `Record` + """ + search = search.replace("/", " ") # zenodo can't handle '/' in search query + + params = { + 'q': search, + **kwargs + } + + url = zenodo_api_url + "/records?" + urlencode(params) + + recs = [Record(hit) for hit in requests.get(url).json()["hits"]["hits"]] + + if not recs: + raise LookupError(f"No records found for search {search}") + + return recs -- GitLab