Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add user-controlled-only flag to metadata retrieval command #13

Merged
merged 3 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelog/13.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Added the `--user-controlled-only` flag to `openscm-zenodo retrieve-metadata`.
This is the flag to use if you want to use the retrieved metadata as the starting point for the next version of a deposit.
16 changes: 15 additions & 1 deletion src/openscm_zenodo/cli/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,18 @@ def cli(
def retrieve_metadata_command(
deposition_id: DEPOSITION_ID_TYPE,
token: TOKEN_TYPE = None,
user_controlled_only: Annotated[
bool,
typer.Option(
help="""Only return metadata keys that the user can control.

If this is `True`, the metadata keys controlled by Zenodo (e.g. the DOI)
are removed from the returned metadata.
This flag is important to use
if you want to use the retrieved metadata
as the starting point for the next version of a deposit."""
),
] = False,
zenodo_domain: ZENODO_DOMAIN_TYPE = ZenodoDomain.production,
) -> None:
"""
Expand All @@ -160,7 +172,9 @@ def retrieve_metadata_command(
zenodo_domain=zenodo_domain,
)

metadata = zenoodo_interactor.get_metadata(deposition_id)
metadata = zenoodo_interactor.get_metadata(
deposition_id, user_controlled_only=user_controlled_only
)

print(json.dumps(metadata, indent=2, sort_keys=True))

Expand Down
22 changes: 22 additions & 0 deletions src/openscm_zenodo/zenodo.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ def get_deposition(
def get_metadata(
self,
deposition_id: str,
user_controlled_only: bool = False,
) -> MetadataType:
"""
Get the metadata for a given deposition ID
Expand All @@ -227,6 +228,16 @@ def get_metadata(
deposition_id
The ID of the deposition

user_controlled_only
Only return metadata keys that the user can control.

If this is `True`, the metadata keys controlled by Zenodo
(e.g. the DOI)
are removed from the returned metadata.
This flag is important to use
if you want to use the retrieved metadata
as the starting point for the next version of a deposit.

Returns
-------
:
Expand All @@ -244,6 +255,17 @@ def get_metadata(

metadata = {"metadata": deposition.json()["metadata"]}

if user_controlled_only:
for k in [
"doi",
"imprint_publisher",
"prereserve_doi",
"publication_date",
"relations",
]:
if k in metadata["metadata"]:
metadata["metadata"].pop(k)

return metadata

def get_bibtex_entry(
Expand Down
30 changes: 30 additions & 0 deletions tests/integration/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,36 @@ def test_retrieve_metadata(test_data_dir):
assert res.stdout == f"{json.dumps(exp, indent=2, sort_keys=True)}\n"


@pytest.mark.zenodo_token
def test_retrieve_metadata_user_controlled_only(test_data_dir):
"""
Test we can retrieve only user-controlled metadata from Zenodo
"""
deposition_id = "101709"

res = runner.invoke(
app,
[
"retrieve-metadata",
deposition_id,
"--zenodo-domain",
"https://sandbox.zenodo.org",
"--user-controlled-only",
],
)
assert res.exit_code == 0, res.stderr
exp = {
"metadata": {
"access_right": "open",
"creators": [{"affiliation": None, "name": "Nicholls, Zebedee"}],
"license": "cc-by-4.0",
"title": "OpenSCM-Zenodo testing 0",
"upload_type": "dataset",
}
}
assert res.stdout == f"{json.dumps(exp, indent=2, sort_keys=True)}\n"


def test_retrieve_bibtex(test_data_dir):
"""
Test we can retrieve a bibtex entry from Zenodo
Expand Down
37 changes: 29 additions & 8 deletions tests/integration/test_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@

from __future__ import annotations

import copy
import datetime as dt
import json
import os
from pathlib import Path

import pytest
import requests
Expand All @@ -14,14 +17,14 @@


@pytest.mark.zenodo_token
def test_default_end_to_end_flow(test_data_dir):
def test_default_end_to_end_flow(test_data_dir, tmpdir):
"""
Test we can start with an ID and end up publishing a new version
"""
tmpdir = Path(tmpdir)

any_deposition_id = "101709"
metadata_file = test_data_dir / "test-deposit-metadata.json"
sub_dir_file = test_data_dir / "sub-dir" / "file-in-sub-dir.txt"
files_to_upload = [metadata_file, sub_dir_file]

zenoodo_interactor = ZenodoInteractor(
token=os.environ["ZENODO_TOKEN"],
Expand All @@ -48,21 +51,37 @@ def test_default_end_to_end_flow(test_data_dir):
for response in remove_all_files_responses
)

with open(metadata_file) as fh:
metadata = json.load(fh)
# Retrieve metadata from existing version
metadata_current = zenoodo_interactor.get_metadata(
latest_deposition_id, user_controlled_only=True
)

# Update this metadata for this version
timestamp = dt.datetime.now(dt.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
metadata_updated = copy.deepcopy(metadata_current)
metadata_updated["metadata"][
"title"
] = f"OpenSCM-Zenodo testing test run {timestamp}"

# Save the metadata to a file
metadata_file = tmpdir / "test-deposit-metadata.json"
with open(metadata_file, "w") as fh:
json.dump(metadata_current, fh)

update_metadata_response = zenoodo_interactor.update_metadata(
deposition_id=new_deposition_id,
metadata=metadata,
metadata=metadata_updated,
)
assert isinstance(update_metadata_response, requests.models.Response)

# Just a test that this exists really, but handy trick to know
reserved_doi = get_reserved_doi(update_metadata_response)
assert "10.5281/zenodo" in reserved_doi

# Upload files
bucket_url = zenoodo_interactor.get_bucket_url(deposition_id=new_deposition_id)

files_to_upload = [metadata_file, sub_dir_file]
for file in files_to_upload:
resp = zenoodo_interactor.upload_file_to_bucket_url(
file,
Expand All @@ -79,12 +98,14 @@ def test_default_end_to_end_flow(test_data_dir):
zenodo_altered_keys = ["prereserve_doi"]

comparable_metadata_from_user = {
k: v for k, v in metadata["metadata"].items() if k not in zenodo_altered_keys
k: v
for k, v in metadata_updated["metadata"].items()
if k not in zenodo_altered_keys
}
comparable_metadata_from_publish_response = {
k: v
for k, v in publish_response_json["metadata"].items()
if k in metadata["metadata"] and k not in zenodo_altered_keys
if k in metadata_updated["metadata"] and k not in zenodo_altered_keys
}
assert comparable_metadata_from_user == comparable_metadata_from_publish_response

Expand Down
Loading