Skip to content
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
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@
#
# SPDX-License-Identifier: Apache-2.0

CKAN_URL=https://catalogue.portal.dev.gdi.lu
REMS_URL=https://daam.portal.dev.gdi.lu
REMS_API_KEY=your-secret-api-key
REMS_BOT_USER=your-robot-user-id
VERIFY_SSL=true
2 changes: 1 addition & 1 deletion sonar-project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ sonar.organization=genomicdatainfrastructure
sonar.qualitygate.wait=true
sonar.python.coverage.reportPaths=coverage.xml
sonar.coverage.exclusions=**__init__**,**__pycache__**,tests/**,*.py
sonar.exclusions=*.xml
sonar.exclusions=*.xml,src/main.py
sonar.sources=src/
sonar.test.inclusions= tests/*.py
10 changes: 6 additions & 4 deletions src/ckan.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
import requests


def get_packages_count(ckan_base_url: str) -> int:
def get_packages_count(ckan_base_url: str, verify_ssl: bool) -> int:
response = requests.get(
f"{ckan_base_url}/api/3/action/package_search?rows=0"
url=f"{ckan_base_url}/api/3/action/package_search?rows=0",
verify=verify_ssl,
).json()
return response["result"]["count"]


def get_packages(start, rows, ckan_base_url: str) -> list:
def get_packages(start, rows, ckan_base_url: str, verify_ssl: bool) -> list:
response = requests.get(
f"{ckan_base_url}/api/3/action/package_search?rows={rows}&start={start}"
url=f"{ckan_base_url}/api/3/action/package_search?rows={rows}&start={start}",
verify=verify_ssl,
).json()
return response["result"]["results"]
19 changes: 13 additions & 6 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
print("REMS api key: **********")
rems_user_id = os.environ.get("REMS_BOT_USER", "owner")
print(f"REMS user id: {rems_user_id}")
verify_ssl = os.environ.get("VERIFY_SSL", "true").lower() == "true"
print(f"Verify SSL certificate: {verify_ssl}")

rows = 100
start = 0
Expand All @@ -29,22 +31,26 @@
"x-rems-user-id": rems_user_id,
}

organization_id = create_or_return_organization_in_rems(rems_base_url, headers)
organization_id = create_or_return_organization_in_rems(
rems_base_url, headers, verify_ssl
)
print(f"Organization id: {organization_id}")

form_id = create_or_return_form_in_rems(organization_id, rems_base_url, headers)
form_id = create_or_return_form_in_rems(
organization_id, rems_base_url, headers, verify_ssl
)
print(f"Form id: {form_id}")

workflow_id = create_or_return_workflow_in_rems(
organization_id, form_id, rems_base_url, headers
organization_id, form_id, rems_base_url, headers, verify_ssl
)
print(f"Workflow id: {workflow_id}")

count = get_packages_count(ckan_base_url)
count = get_packages_count(ckan_base_url, verify_ssl)
print(f"packages found: {count}")

while start < count:
packages = get_packages(start, rows, ckan_base_url)
packages = get_packages(start, rows, ckan_base_url, verify_ssl)
for package in packages:
if "identifier" not in package or package["identifier"] is None:
package_id = package["id"]
Expand All @@ -53,7 +59,7 @@
dataset_id = package["identifier"]
dataset_title = package["title"]
resource_id = create_or_return_resource_in_rems(
organization_id, dataset_id, rems_base_url, headers
organization_id, dataset_id, rems_base_url, headers, verify_ssl
)
print(f"resource id: {resource_id}")
catalogue_item_id = create_or_return_catalogue_item_in_rems(
Expand All @@ -64,6 +70,7 @@
dataset_title,
rems_base_url,
headers,
verify_ssl,
)
print(f"catalogue item id: {catalogue_item_id}")
start += rows
32 changes: 27 additions & 5 deletions src/rems.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ def load_json(path: str) -> Dict:
raise ValueError(f"Error loading JSON from {path}: {str(e)}")


def create_or_return_organization_in_rems(rems_base_url: str, headers: dict) -> str:
def create_or_return_organization_in_rems(
rems_base_url: str, headers: dict, verify_ssl: bool
) -> str:
base_workflow_organization = load_json("./data/workflow_organization.json")
name = base_workflow_organization["organization/name"]["en"]
organization_id = hashlib.md5(name.encode()).hexdigest()
Expand All @@ -26,7 +28,9 @@ def create_or_return_organization_in_rems(rems_base_url: str, headers: dict) ->
workflow_organization["organization/id"] = organization_id

response = requests.get(
url=f"{rems_base_url}/api/organizations/{organization_id}", headers=headers
url=f"{rems_base_url}/api/organizations/{organization_id}",
headers=headers,
verify=verify_ssl,
)
if response.status_code == 200:
return organization_id
Expand All @@ -36,18 +40,20 @@ def create_or_return_organization_in_rems(rems_base_url: str, headers: dict) ->
url=f"{rems_base_url}/api/organizations/create",
json=workflow_organization,
headers=headers,
verify=verify_ssl,
)
if response.status_code != 200:
raise RuntimeError(f"Organization creation failed: {response.text}")
return workflow_organization["organization/id"]


def create_or_return_form_in_rems(
organization_id: str, rems_base_url: str, headers: dict
organization_id: str, rems_base_url: str, headers: dict, verify_ssl: bool
) -> int:
response = requests.get(
url=f"{rems_base_url}/api/forms?disabled=false&archived=false",
headers=headers,
verify=verify_ssl,
)
if response.status_code != 200:
raise RuntimeError(f"Workflow retrieval failed: {response.text}")
Expand All @@ -74,18 +80,24 @@ def create_or_return_form_in_rems(
url=f"{rems_base_url}/api/forms/create",
json=form,
headers=headers,
verify=verify_ssl,
)
if response.status_code != 200:
raise RuntimeError(f"Workflow creation failed: {response.text}")
return response.json()["id"]


def create_or_return_workflow_in_rems(
organization_id: str, form_id: int, rems_base_url: str, headers: dict
organization_id: str,
form_id: int,
rems_base_url: str,
headers: dict,
verify_ssl: bool,
) -> int:
response = requests.get(
url=f"{rems_base_url}/api/workflows?disabled=false&archived=false",
headers=headers,
verify=verify_ssl,
)
if response.status_code != 200:
raise RuntimeError(f"Workflow retrieval failed: {response.text}")
Expand All @@ -109,18 +121,24 @@ def create_or_return_workflow_in_rems(
url=f"{rems_base_url}/api/workflows/create",
json=workflow,
headers=headers,
verify=verify_ssl,
)
if response.status_code != 200:
raise RuntimeError(f"Workflow creation failed: {response.text}")
return response.json()["id"]


def create_or_return_resource_in_rems(
organization_id: str, dataset_identifier: str, rems_base_url: str, headers: dict
organization_id: str,
dataset_identifier: str,
rems_base_url: str,
headers: dict,
verify_ssl: bool,
) -> str:
response = requests.get(
url=f"{rems_base_url}/api/resources?disabled=false&archived=false&resid={dataset_identifier}",
headers=headers,
verify=verify_ssl,
)
if response.status_code != 200 or len(response.json()) > 1:
raise RuntimeError(f"Resource retrieval failed: {response.text}")
Expand All @@ -137,6 +155,7 @@ def create_or_return_resource_in_rems(
url=f"{rems_base_url}/api/resources/create",
json=resource,
headers=headers,
verify=verify_ssl,
)
if response.status_code != 200:
raise RuntimeError(f"Resource creation failed: {response.text}")
Expand All @@ -151,10 +170,12 @@ def create_or_return_catalogue_item_in_rems(
title: str,
rems_base_url: str,
headers: dict,
verify_ssl: bool,
) -> str:
response = requests.get(
url=f"{rems_base_url}/api/catalogue-items?disabled=false&archived=false&resource={dataset_identifier}",
headers=headers,
verify=verify_ssl,
)
if response.status_code != 200 or len(response.json()) > 1:
raise RuntimeError(f"Catalogue Item retrieval failed: {response.text}")
Expand All @@ -173,6 +194,7 @@ def create_or_return_catalogue_item_in_rems(
url=f"{rems_base_url}/api/catalogue-items/create",
json=catalogue_item,
headers=headers,
verify=verify_ssl,
)

if response.status_code != 200:
Expand Down
10 changes: 6 additions & 4 deletions tests/test_ckan_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ def test_get_packages_count(mock_get):

# Call the function with a mock CKAN base URL
ckan_base_url = "http://mock-ckan-instance.com"
count = get_packages_count(ckan_base_url)
count = get_packages_count(ckan_base_url, True)

# Assert the function returns the correct count
assert count == 42
mock_get.assert_called_once_with(
f"{ckan_base_url}/api/3/action/package_search?rows=0"
url=f"{ckan_base_url}/api/3/action/package_search?rows=0",
verify=True,
)


Expand All @@ -50,12 +51,13 @@ def test_get_packages(mock_get):
start = 0
rows = 2
ckan_base_url = "http://mock-ckan-instance.com"
packages = get_packages(start, rows, ckan_base_url)
packages = get_packages(start, rows, ckan_base_url, True)

# Assert the function returns the correct packages
assert len(packages) == 2
assert packages[0]["id"] == "package1"
assert packages[1]["name"] == "Test Package 2"
mock_get.assert_called_once_with(
f"{ckan_base_url}/api/3/action/package_search?rows={rows}&start={start}"
url=f"{ckan_base_url}/api/3/action/package_search?rows={rows}&start={start}",
verify=True,
)
6 changes: 6 additions & 0 deletions tests/test_create_or_return_catalogue_item_in_rems.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def test_create_or_return_catalogue_item_in_rems_exists(mock_get):
title,
rems_base_url,
headers,
True,
)

# Assert the function returns the correct catalogue item ID
Expand All @@ -49,6 +50,7 @@ def test_create_or_return_catalogue_item_in_rems_exists(mock_get):
mock_get.assert_called_once_with(
url=f"{rems_base_url}/api/catalogue-items?disabled=false&archived=false&resource={dataset_identifier}",
headers=headers,
verify=True,
)


Expand Down Expand Up @@ -91,6 +93,7 @@ def test_create_or_return_catalogue_item_in_rems_create(
title,
rems_base_url,
headers,
True,
)

# Assert the function returns the newly created catalogue item ID
Expand All @@ -107,6 +110,7 @@ def test_create_or_return_catalogue_item_in_rems_create(
url=f"{rems_base_url}/api/catalogue-items/create",
json=expected_catalogue_item,
headers=headers,
verify=True,
)


Expand Down Expand Up @@ -136,6 +140,7 @@ def test_create_or_return_catalogue_item_in_rems_retrieval_fails(mock_get):
title,
rems_base_url,
headers,
True,
)


Expand Down Expand Up @@ -181,4 +186,5 @@ def test_create_or_return_catalogue_item_in_rems_creation_fails(
title,
rems_base_url,
headers,
True,
)
14 changes: 10 additions & 4 deletions tests/test_create_or_return_form_in_rems.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ def test_create_or_return_form_in_rems_exists(mock_get):
rems_base_url = "http://mock-rems-instance.com"
headers = {"Authorization": "Bearer mock_token"}
organization_id = "test-org-id"
form_id = create_or_return_form_in_rems(organization_id, rems_base_url, headers)
form_id = create_or_return_form_in_rems(
organization_id, rems_base_url, headers, True
)

# Assert the function returns the correct form ID
assert form_id == 123
Expand All @@ -36,6 +38,7 @@ def test_create_or_return_form_in_rems_exists(mock_get):
mock_get.assert_called_once_with(
url=f"{rems_base_url}/api/forms?disabled=false&archived=false",
headers=headers,
verify=True,
)


Expand All @@ -62,7 +65,9 @@ def test_create_or_return_form_in_rems_create(mock_load_json, mock_get, mock_pos
rems_base_url = "http://mock-rems-instance.com"
headers = {"Authorization": "Bearer mock_token"}
organization_id = "test-org-id"
form_id = create_or_return_form_in_rems(organization_id, rems_base_url, headers)
form_id = create_or_return_form_in_rems(
organization_id, rems_base_url, headers, True
)

# Assert the function returns the newly created form ID
assert form_id == 456
Expand All @@ -82,6 +87,7 @@ def test_create_or_return_form_in_rems_create(mock_load_json, mock_get, mock_pos
url=f"{rems_base_url}/api/forms/create",
json=expected_form,
headers=headers,
verify=True,
)


Expand All @@ -99,7 +105,7 @@ def test_create_or_return_form_in_rems_retrieval_fails(mock_get):
with pytest.raises(
RuntimeError, match="Workflow retrieval failed: Internal Server Error"
):
create_or_return_form_in_rems(organization_id, rems_base_url, headers)
create_or_return_form_in_rems(organization_id, rems_base_url, headers, True)


# Test when form creation fails with a non-200 status code
Expand Down Expand Up @@ -128,4 +134,4 @@ def test_create_or_return_form_in_rems_creation_fails(
headers = {"Authorization": "Bearer mock_token"}
organization_id = "test-org-id"
with pytest.raises(RuntimeError, match="Workflow creation failed: Bad Request"):
create_or_return_form_in_rems(organization_id, rems_base_url, headers)
create_or_return_form_in_rems(organization_id, rems_base_url, headers, True)
Loading