From 6baad69a12176d744ea743302584f73efb301bd7 Mon Sep 17 00:00:00 2001 From: "Michael Hirsch, Ph.D" Date: Tue, 26 Jun 2018 05:42:19 -0600 Subject: [PATCH] update API URL --- meta.ini | 6 --- pyzenodo3/upload.py | 101 ++++++++++++++++++++++++++++++-------------- setup.cfg | 15 +++++-- upload_zenodo.py | 10 +++-- 4 files changed, 87 insertions(+), 45 deletions(-) diff --git a/meta.ini b/meta.ini index 13c2496..f53d6b2 100644 --- a/meta.ini +++ b/meta.ini @@ -1,12 +1,6 @@ [zenodo] author = Jane Doe title = An Example Title -keywords = python, machine learning description = A test file -creators = Jane Doe, John Smith -upload_type = software -license = CC-BY-SA-4.0 - -publication_date = 2018-07-01 diff --git a/pyzenodo3/upload.py b/pyzenodo3/upload.py index 1ca1390..18e10b2 100644 --- a/pyzenodo3/upload.py +++ b/pyzenodo3/upload.py @@ -5,9 +5,8 @@ from configparser import ConfigParser from typing import Dict, Union, List -SANDBOX_URL = "https://sandbox.zenodo.org/api" BASE_URL = "https://zenodo.org/api" - +HDR = {"Content-Type": "application/json"} def meta(inifn: Path) -> Path: """ creates metadata for Zenodo upload. @@ -49,48 +48,88 @@ def meta(inifn: Path) -> Path: return outfn -def upload(metafn: Path, datafn: Path, token: Union[str, Path], live: bool): - """takes metadata and file and uploads to Zenodo""" - - if not metafn: - raise ValueError('must specify API token or file containing the token') +def check_token(token: str): + if not isinstance(token, str) or not token: + raise TypeError('Token need to be a string') - metafn = Path(metafn).expanduser() - datafn = Path(datafn).expanduser() - assert datafn.is_file(), "for now, upload a file only" + r = requests.get('https://zenodo.org/api/deposit/depositions', + params={'access_token': token}) - if not metafn.is_file(): - raise FileNotFoundError('meta JSON file is required') + if r.status_code != 200: + raise requests.HTTPError(f"Token accept error, status code: {r.status_code} {r.json()['message']}") - meta = metafn.read_text() - base_url = BASE_URL if live else SANDBOX_URL -# %% token +def get_token(token: Union[str, Path]) -> str: if Path(token).expanduser().is_file(): token = Path(token).expanduser().read_text().strip() # in case \n or spaces sneak in elif isinstance(token, str) and 100 > len(token) > 10: pass else: raise ValueError('API Token must be specified to upload to Zenodo') -# %% Create new paper submission - url = f"{base_url}/deposit/depositions/?access_token={token}" - headers = {"Content-Type": "application/json"} - response = requests.post(url, data=meta, headers=headers) - if response.status_code != 200: - raise requests.HTTPError(f"Error happened during submission, status code: {response.status_code}") -# %% Get the submission ID - submission_id = json.loads(response.text)["id"] -# %% Upload - url = f"{base_url}/api/deposit/depositions/{submission_id}/files?access_token={token}" + return token + - upload_metadata = {'filename': str(metafn)} +def upload_meta(token: str, metafn: Path, depid: str): + """upload metadata to zenodo""" + + if not metafn: + raise ValueError('must specify API token or file containing the token') + + metafn = Path(metafn).expanduser() + + if not metafn.is_file(): + raise FileNotFoundError('meta JSON file is required') + + meta = metafn.read_text() - files = {'file': datafn.open('rb')} + r = requests.put(f"{BASE_URL}/deposit/depositions/{depid}", + params={'access_token': token}, + data=meta, #json.dumps(meta), + headers=HDR) + + if r.status_code != 200: + raise requests.HTTPError(f"Error in metadata upload, status code: {r.status_code} {r.json()['message']}") + + +def upload_data(token: str, datafn: Path, depid: str): + + r = requests.post(f"{BASE_URL}/deposit/depositions/{depid}/files", + params={'access_token': token}, + data={'filename': str(datafn)}, + files={'file': datafn.open('rb')}) + + if r.status_code != 201: + raise requests.HTTPError(f"Error in data upload, status code: {r.status_code} {r.json()['message']}") + + print(f"{datafn} ID = {depid} (DOI: 10.5281/zenodo.{depid})") + + +def create(token: str) -> str: + + r = requests.post(f"{BASE_URL}/deposit/depositions", + params={'access_token': token}, + json={}, + headers=HDR) + + if r.status_code != 201: + raise requests.HTTPError(f"Error in creation, status code: {r.status_code} {r.json()['message']}") +# %% Get the deposition ID + return r.json()["id"] + +def upload(metafn: Path, datafn: Path, token: Union[str, Path]): + """takes metadata and file and uploads to Zenodo""" - response = requests.post(url, data=upload_metadata, files=files) + datafn = Path(datafn).expanduser() + assert datafn.is_file(), "for now, upload a file only" - if response.status_code != 200: - raise requests.HTTPError(f"Error happened during submission, status code: {response.status_code}") +# %% token check + token = get_token(token) - print(f"{datafn} submitted with submission ID = {submission_id} (DOI: 10.5281/zenodo.{submission_id})") + check_token(token) +# %% Create new submission + depid = create(token) +# %% Upload data + upload_data(token, datafn, depid) +# %% add metadata + # upload_meta(token, metafn, depid) diff --git a/setup.cfg b/setup.cfg index 643c6c0..bff1f03 100644 --- a/setup.cfg +++ b/setup.cfg @@ -10,11 +10,12 @@ license_file = LICENSE keywords = zenodo, open data license = Apache 2.0 classifiers = - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 Development Status :: 3 - Alpha + Environment :: Console Intended Audience :: Developers Operating System :: OS Independent + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 Topic :: Software Development :: Libraries :: Python Modules Topic :: Scientific/Engineering @@ -27,8 +28,14 @@ install_requires = [options.extras_require] -tests = pytest; pytest-cov; coveralls; flake8; mypy +tests = + pytest + pytest-cov + coveralls + flake8 + mypy [flake8] max-line-length = 132 -exclude = .git,__pycache__,doc/,docs/,pipenv/vendor/,get-pipenv.py +exclude = .git,__pycache__,doc/,docs/,build/,dist/,archive/ + diff --git a/upload_zenodo.py b/upload_zenodo.py index c3d73b4..18524f4 100755 --- a/upload_zenodo.py +++ b/upload_zenodo.py @@ -13,13 +13,15 @@ def cmdparse() -> Namespace: p.add_argument('inifn', help='mymeta.ini file with author, title, etc.') p.add_argument('path', help='directory or file to upload to Zenodo', nargs='?') - p.add_argument('-y', '--yes', help='upload to Zenodo, not just the sandbox', - action='store_true') return p.parse_args() -if __name__ == '__main__': +def main(): p = cmdparse() metafn = zup.meta(p.inifn) - zup.upload(metafn, p.path, p.apikey, p.yes) + zup.upload(metafn, p.path, p.apikey) + + +if __name__ == '__main__': + main()