diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4fda713f..16e1b430 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -22,7 +22,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} cache : 'pip' diff --git a/examples/publishing-guides/dataset_publishing.ipynb b/examples/publishing-guides/dataset_publishing.ipynb index 589010c2..f6805b8f 100644 --- a/examples/publishing-guides/dataset_publishing.ipynb +++ b/examples/publishing-guides/dataset_publishing.ipynb @@ -291,7 +291,15 @@ "\n", "# publication year (optional)\n", "# The default is the current calendar year\n", - "publication_year = 2023" + "publication_year = 2023\n", + "\n", + "# links (optional)\n", + "# These are urls that link to additional information about the dataset\n", + "# in the form [{\"type\":str, \"doi\":str, \"url\":str, \"description\":str, \"bibtex\":str}]\n", + "links = {\"type\": \"other_paper\",\n", + " \"doi\": \"10.1072/xyz\",\n", + " \"url\": \"https://doi.org/10.1072/xyz\"\n", + " }" ] }, { @@ -323,19 +331,19 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": { "id": "iSxfIFmxdBjS" }, "outputs": [], "source": [ "# publish to Foundry! returns a result object we can inspect\n", - "res = f.publish_dataset(example_iris_metadata, title, authors, https_data_path=data_path, short_name=short_name)" + "res = f.publish_dataset(example_iris_metadata, title, authors, https_data_path=data_path, short_name=short_name, links=links)" ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 5, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -350,7 +358,7 @@ "True" ] }, - "execution_count": 15, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -371,7 +379,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -383,13 +391,13 @@ { "data": { "text/plain": [ - "{'source_id': 'colab_example_iris_1682542160_v1.1',\n", + "{'source_id': 'colab_example_iris_1691186523_v1.1',\n", " 'success': True,\n", " 'error': None,\n", " 'status_code': 202}" ] }, - "execution_count": 9, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -680,9 +688,9 @@ "provenance": [] }, "kernelspec": { - "display_name": "https_pub_example", + "display_name": "Python 3 (ipykernel)", "language": "python", - "name": "https_pub_example" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -694,7 +702,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.16" + "version": "3.9.4" } }, "nbformat": 4, diff --git a/foundry/foundry.py b/foundry/foundry.py index 47814540..d831fd82 100644 --- a/foundry/foundry.py +++ b/foundry/foundry.py @@ -395,6 +395,8 @@ def publish_dataset( dataset_doi (str): The DOI for this dataset (not an associated paper). related_dois (list): DOIs related to this dataset, not including the dataset's own DOI (for example, an associated paper's DOI). + links (list[dict]): List of dicts describing links associated with the dataset; in the format: + {"type":str, "doi":str, "url":str, "description":str, "bibtex":str} Returns ------- @@ -425,6 +427,17 @@ def publish_dataset( self.connect_client.set_project_block( self.config.metadata_key, foundry_metadata) + # add links + links = kwargs.get("links") + if links is not None: + # make sure it's a list + links = links if isinstance(links, list) else [links] + for link in links: + # validate links + self.validate_link(link) + # add valid links - need to add all at once + self.connect_client.add_links(links) + # upload via HTTPS if specified if https_data_path: # gather auth'd clients necessary for publication to endpoint @@ -808,6 +821,15 @@ def validate_metadata(self, metadata): field_name = ".".join([item for item in error['loc'] if isinstance(item, str)]) error_description = error['msg'] error_message = f"""There is an issue validating the metadata for the field '{field_name}': - The error message returned is: '{error_description}'.""" + The error message returned is: '{error_description}'.""" logger.error(error_message) raise e + + def validate_link(self, link): + valid_keys = ["type", "doi", "url", "description", "bibtex"] + link_keys = [*link] + if not all(key in valid_keys for key in link_keys): + raise ValueError(f"A key in one of the submitted link ({link_keys}) is not of the valid options: " + f"{valid_keys}") + else: + return True diff --git a/tests/test_foundry.py b/tests/test_foundry.py index 98d00b3e..53f40f10 100644 --- a/tests/test_foundry.py +++ b/tests/test_foundry.py @@ -356,6 +356,62 @@ def test_publish_with_https(): _write_test_data(local_path) res = f.publish_dataset(pub_test_metadata, title, authors, https_data_path=local_path, short_name=short_name) + assert res['success'] + assert res['source_id'] == f"_test_{short_name}_v1.1" + + +@pytest.mark.skipif(bool(is_gha), reason="Not run as part of GHA CI") +def test_publish_bad_links_with_https(): + """System test: Assess the end-to-end publication of a dataset via HTTPS + """ + + f = Foundry(index="mdf-test", authorizers=auths) + timestamp = datetime.now().timestamp() + title = "https_publish_test_{:.0f}".format(timestamp) + short_name = "https_pub_{:.0f}".format(timestamp) + authors = ["A Scourtas"] + local_path = "./data/https_test" + links = {"horse": "link", "doi": "3", "url": "www.test.com", "description": "string", "bibtex": "bib"} + + # create test JSON to upload (if it doesn't already exist) + _write_test_data(local_path) + + with pytest.raises(Exception) as exc_info: + f.publish_dataset(pub_test_metadata, + title, + authors, + https_data_path=local_path, + short_name=short_name, + links=links) + # err = exc_info.value + # assert hasattr(err, '__cause__') + # assert isinstance(err.__cause__, ValueError) + assert isinstance(exc_info.type(), ValueError) + _delete_test_data(f) + + +@pytest.mark.skipif(bool(is_gha), reason="Not run as part of GHA CI") +def test_publish_links_with_https(): + """System test: Assess the end-to-end publication of a dataset via HTTPS + """ + + f = Foundry(index="mdf-test", authorizers=auths) + timestamp = datetime.now().timestamp() + title = "https_publish_test_{:.0f}".format(timestamp) + short_name = "https_pub_{:.0f}".format(timestamp) + authors = ["A Scourtas"] + local_path = "./data/https_test" + links = {"type": "link", "doi": "3", "url": "www.test.com", "description": "string", "bibtex": "bib"} + + # create test JSON to upload (if it doesn't already exist) + _write_test_data(local_path) + + res = f.publish_dataset(pub_test_metadata, + title, + authors, + https_data_path=local_path, + short_name=short_name, + links=links) assert res['success'] assert res['source_id'] == f"_test_{short_name}_v1.1"