Skip to content
Open
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
320 changes: 320 additions & 0 deletions publish-notebook-sdm.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,320 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "845fb16a-85da-4602-9837-05bb5c96f76a",
"metadata": {},
"source": [
"# Publishing a Notebook to the tool registry\n",
"This notebook showcases how to use the tool-registry REST API to publish a tool."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "d53df91b-e41d-46aa-99c9-058de37d684d",
"metadata": {
"lines_to_next_cell": 2
},
"outputs": [],
"source": [
"import requests\n",
"import json\n",
"from packaging.version import Version, InvalidVersion"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "00ed3192-614c-43cf-a8ef-ec315f2431a7",
"metadata": {},
"outputs": [],
"source": [
"API_URL_BASE = \"https://tools-registry.eosc-data-commons.eu/api/v1/\"\n",
"API_URL_TOOLS = f\"{API_URL_BASE}tools/\"\n",
"TOOL_REGISTRY_VERSION = \"0.2.13\""
]
},
{
"cell_type": "markdown",
"id": "ce04ca4d-c583-46a8-bb6b-451522221f0f",
"metadata": {},
"source": [
"## Getting access credentials\n",
"Before publishing to the tool registry an EGI access token is needed. This can be obtained from [https://aai.egi.eu/token/](https://aai.egi.eu/token/). \n",
"Once obtained copy and paste in the cell below. The token is only valid for 1 hour."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "f5530c54-0fe0-447d-8c3f-8b59f376109b",
"metadata": {},
"outputs": [],
"source": [
"TOKEN = \"\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0e6d4d88-078f-4e19-b1ad-0728683a8bf7",
"metadata": {},
"outputs": [],
"source": [
"tool = {\n",
" \"uri\": \"https://github.com/EOSC-Data-Commons/FinBIF-R-Package-tool\",\n",
" \"name\": \"Species Distribution Model (SDM) for Eurasian Red Squirrel (Sciurus vulgaris)\",\n",
" \"version\": \"1\",\n",
" \"location\": \"https://github.com/EOSC-Data-Commons/FinBIF-R-Package-tool\",\n",
" \"description\": \"This tutorial is a quick demonstration of how to build a species distribution model (SDM) for Eurasian Red Squirrel (Sciurus vulgaris) using Maximum Entropy (MaxEnt). MaxEnt is a popular method for constructing SDMs for presence-only data. The following should not be taken as a best practice example, as it only aims to outline some of the key steps in the modelling process without applying any of the rigour required to build a fit for purpose model.\",\n",
" \"keywords\": [\n",
" \"species distribution model\",\n",
" \"Eurasian Red Squirrel\",\n",
" \"Sciurus vulgaris\",\n",
" \"biodiversity\",\n",
" \"Finnish Biodiversity Information Facility\",\n",
" \"Maximum Entropy\"\n",
"],\n",
" \"tags\": [\"finbif\"],\n",
" \"license\": \"MIT License\",\n",
" \"types\": [\"general\", \"egi-replay\", \"binder\", \"python_notebook_repo\"],\n",
" \"input_file_formats\": [\"tsv\"],\n",
" \"ouput_file_formats\": [],\n",
" \"raw_definition\": {}\n",
"} "
]
},
{
"cell_type": "markdown",
"id": "9f76f137-4180-4653-ac99-cce45a3c028a",
"metadata": {},
"source": [
"## Check tool registry version\n",
"This notebook was created for tool-registry version > `0.2.12`. Different versions might not have the same schema!"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a154469d-ad18-4cb5-b107-d2f5bf19310d",
"metadata": {},
"outputs": [],
"source": [
"response = requests.get(f\"{API_URL_BASE}health\")\n",
"if response.status_code in (200, 201):\n",
" data = response.json()\n",
" version = data.get(\"version\", None) \n",
" try:\n",
" if version and Version(version) >= Version(TOOL_REGISTRY_VERSION):\n",
" print(f\"Correct tool registry version: {version}\")\n",
" else:\n",
" print(f\"Incorrect or outdated version for tool registry: {response.text}\")\n",
"\n",
" except InvalidVersion:\n",
" print(f\"Invalid version format: {version}\")\n",
" \n",
"else:\n",
" print(f\"Failure: {response.status_code}, message: {response.text}\")"
]
},
{
"cell_type": "markdown",
"id": "636c4ffc-2d82-44ca-9e0e-ad97f3e8ebda",
"metadata": {},
"source": [
"## Publishing your tool\n",
"Next we can go ahead and submit the tool using a POST command."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6cadc70a-d8ff-4b3f-b0e3-a7c87102facf",
"metadata": {
"lines_to_next_cell": 2
},
"outputs": [],
"source": [
"headers = {\n",
" \"Content-Type\": \"application/json\",\n",
" \"Authorization\": f\"Bearer {TOKEN}\"\n",
"}\n",
"tool_id = None\n",
"response = requests.post(API_URL_TOOLS, json=tool, headers=headers)\n",
"if response.status_code in (200, 201):\n",
" print(\"Success\")\n",
" tool_id = response.json()[\"tool_id\"]\n",
" tool_url = f\"{API_URL_TOOLS}{tool_id}\"\n",
" print(f\"Created tool at: {tool_url}\")\n",
"if response.status_code == 400:\n",
" data = response.json()\n",
" if data[\"detail\"] and data[\"detail\"][\"existing_tool_id\"]:\n",
" tool_id = data[\"detail\"][\"existing_tool_id\"]\n",
" tool_url = f\"{API_URL_TOOLS}{tool_id}\"\n",
" print(f\"Tool already exists with ID: {tool_url}\")\n",
"\n",
"if not tool_id:\n",
" print(f\"Failure: {response.status_code}\")\n",
" print(response.text)"
]
},
{
"cell_type": "markdown",
"id": "34add4b2-f368-44cb-88f6-f3c58931706f",
"metadata": {},
"source": [
"## Check your tool in the registry\n",
"\n",
"On `Success`, the registry will respond with the tool ID. This is used to check/update/delete the tool in the future. \n",
"Checking that your tool exists in the registry is a matter of calling the correct URL."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0fe06a72-7127-4bba-8f7b-757aa64a7a8b",
"metadata": {
"lines_to_next_cell": 2
},
"outputs": [],
"source": [
"if tool_id:\n",
" \n",
" tool_url = f\"{API_URL_TOOLS}{tool_id}\"\n",
" tool_response = requests.get(tool_url)\n",
" if tool_response.status_code in (200, 201):\n",
" print(json.dumps(tool_response.json(), indent=4))\n",
" else:\n",
" print(f\"Failure: {tool_response.status_code}\")\n",
" print(tool_response.text)\n",
"else:\n",
" print(\"Tool was not created in previous step!\")"
]
},
{
"cell_type": "markdown",
"id": "aff73ebd-a501-4eb9-9d4b-4ac2271a6cc4",
"metadata": {},
"source": [
"## Update your tool information\n",
"It is also possible to update the tool inforamtion after being created. Updating tools is only allowed by the user that created the tool. This is done similary to creating a tool but instead we only provide the fields needing updating. \n",
"In this example we will update the `name` and `license`"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "61b20df3-cf23-4341-95f3-5a2ef90a4ff8",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{\n",
" \"message\": \"Tool updated successfully\",\n",
" \"tool_id\": 5491\n",
"}\n"
]
}
],
"source": [
"if tool_id:\n",
" tool_update = {\n",
" \"tags\": [\"finbif\"],\n",
" }\n",
" tool_url = f\"{API_URL_TOOLS}{tool_id}\"\n",
" tool_response = requests.patch(tool_url, json=tool_update, headers=headers)\n",
" if tool_response.status_code in (200, 201):\n",
" print(json.dumps(tool_response.json(), indent=4))\n",
" else:\n",
" print(f\"Failure: {tool_response.status_code}\")\n",
" print(tool_response.text)\n",
"else:\n",
" print(\"Tool was not created in previous step!\")"
]
},
{
"cell_type": "markdown",
"id": "77e4564c-3a74-4d28-b5ab-7fbf3be21c3f",
"metadata": {},
"source": [
"## Delete your tool from registry\n",
"\n",
"It is also possible to delete the tool from the registry. This is only allowed by the user that created the tool.\n",
"\n",
"> ⚠️ **Warning:** Proceed with caution. This action will delete your tool from the registry."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9cc1fbac-6040-4df0-ab60-2f5e16e692b8",
"metadata": {},
"outputs": [],
"source": [
"if tool_id:\n",
" tool_url = f\"{API_URL_TOOLS}{tool_id}\"\n",
" tool_response = requests.delete(tool_url, headers=headers)\n",
" if tool_response.status_code in (200, 201):\n",
" print(json.dumps(tool_response.json(), indent=4))\n",
" else:\n",
" print(f\"Failure: {tool_response.status_code}\")\n",
" print(tool_response.text)\n",
"else:\n",
" print(\"Tool was not created in previous step!\")"
]
},
{
"cell_type": "markdown",
"id": "76f04933-83e6-4eca-bef1-09aae99d85d3",
"metadata": {},
"source": [
"## Verify tool has been deleted\n",
"Use the same query as before to check if the tool exists (it should not!)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d7023763-a226-48a8-8fee-da2a647e020d",
"metadata": {},
"outputs": [],
"source": [
"if tool_id:\n",
" \n",
" tool_url = f\"{API_URL_TOOLS}{tool_id}\"\n",
" tool_response = requests.get(tool_url)\n",
" if tool_response.status_code == 404:\n",
" print(f\"Tool {tool_id} not in registry.\")\n",
" else:\n",
" print(f\"Status: {tool_response.status_code}\")\n",
" print(tool_response.text)\n",
"else:\n",
" print(\"Tool was not created in previous step!\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.14"
}
},
"nbformat": 4,
"nbformat_minor": 5
}