Skip to content

Commit

Permalink
adding archive and delete endpoints (#59)
Browse files Browse the repository at this point in the history
* lint

* tests

* line length
  • Loading branch information
dyf authored Feb 6, 2024
1 parent 4eff679 commit 83e0463
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 0 deletions.
1 change: 1 addition & 0 deletions doc_template/source/conf.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Configuration file for the Sphinx documentation builder."""

#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
Expand Down
1 change: 1 addition & 0 deletions src/aind_codeocean_api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
"""Python wrapper of CodeOcean's REST API"""

__version__ = "0.4.1"
50 changes: 50 additions & 0 deletions src/aind_codeocean_api/codeocean.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Module to interface with Code Ocean's backend.
"""

import json
import logging
from enum import Enum
Expand All @@ -23,6 +24,7 @@ class CodeOceanClient:
class _URLStrings(Enum):
"""Enum class for CodeOcean's url strings"""

ARCHIVE = "archive"
CAPSULES = "capsules"
COMPUTATIONS = "computations"
DATA_ASSETS = "data_assets"
Expand Down Expand Up @@ -553,3 +555,51 @@ def update_permissions(
)
response = requests.post(url, json=permissions, auth=(self.token, ""))
return response

def archive_data_asset(
self, data_asset_id: str, archive: bool = True
) -> requests.models.Response:
"""
This will archive or unarchive a data asset using a PATCH request to
the Code Ocean API.
Parameters
---------------
data_asset_id : string
ID of the data asset
Returns
---------------
requests.models.Response
"""

url = (
f"{self.asset_url}/{data_asset_id}/"
f"{self._URLStrings.ARCHIVE.value}"
)
response = requests.patch(
url, params={"archive": archive}, auth=(self.token, "")
)
return response

def delete_data_asset(
self, data_asset_id: str
) -> requests.models.Response:
"""
This will delete a data asset using a DELETE request to the Code Ocean
API.
Parameters
---------------
data_asset_id : string
ID of the data asset
Returns
---------------
requests.models.Response
"""

url = f"{self.asset_url}/{data_asset_id}"

response = requests.delete(url, auth=(self.token, ""))
return response
1 change: 1 addition & 0 deletions src/aind_codeocean_api/credentials.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Basic CodeOcean Credentials Handling."""

import functools
import json
import os
Expand Down
74 changes: 74 additions & 0 deletions tests/test_codeocean_requests.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Tests CodeOcean API python interface"""

import json
import unittest
from typing import Any, Callable, List
Expand Down Expand Up @@ -85,11 +86,29 @@ def request_put_response(url: str, json: dict) -> MockResponse:
status_code=200, content=success_message, url=url
)

def request_patch_response(url: str) -> MockResponse:
"""Mock a patch response"""
success_message = map_input_to_success_message(url)
return MockResponse(
status_code=202, content=success_message, url=url
)

def request_delete_response(url: str) -> MockResponse:
"""Mock a delete response"""
success_message = map_input_to_success_message(url)
return MockResponse(
status_code=204, content=success_message, url=url
)

# TODO: Change these to enums
if req_type == "post":
return request_post_response
elif req_type == "get":
return request_get_response
elif req_type == "patch":
return request_patch_response
elif req_type == "delete":
return request_delete_response
else:
return request_put_response

Expand Down Expand Up @@ -990,6 +1009,61 @@ def request_post_response(json: dict) -> MockResponse:
)
self.assertEqual(response.status_code, 204)

@mock.patch("requests.patch")
def test_archive_data_asset(
self, mock_api_patch: unittest.mock.MagicMock
) -> None:
"""Tests the response of archiving a data asset"""

def map_to_success_message(_) -> dict:
"""Map to a success message"""
return ""

mocked_success_patch = self.mock_success_response(
map_to_success_message, req_type="patch"
)

example_data_asset_id = "da8dd108-2a10-471d-82b9-1e671b107bf8"
expected_url = (
f"{self.co_client.asset_url}/"
"{example_data_asset_id}/archive?archive=True"
)

mock_api_patch.return_value = mocked_success_patch(url=expected_url)

response = self.co_client.archive_data_asset(
data_asset_id=example_data_asset_id, archive=True
)

self.assertEqual(response.url, expected_url)
self.assertEqual(response.status_code, 202)

@mock.patch("requests.delete")
def test_delete_data_asset(
self, mock_api_delete: unittest.mock.MagicMock
) -> None:
"""Tests the response of deleting a data asset"""

def map_to_success_message(_) -> dict:
"""Map to a success message"""
return ""

mocked_success_delete = self.mock_success_response(
map_to_success_message, req_type="delete"
)

example_data_asset_id = "da8dd108-2a10-471d-82b9-1e671b107bf8"
expected_url = f"{self.co_client.asset_url}/{example_data_asset_id}"

mock_api_delete.return_value = mocked_success_delete(url=expected_url)

response = self.co_client.delete_data_asset(
data_asset_id=example_data_asset_id
)

self.assertEqual(response.url, expected_url)
self.assertEqual(response.status_code, 204)


if __name__ == "__main__":
unittest.main()
1 change: 1 addition & 0 deletions tests/test_credentials.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Tests credentials loader."""

import json
import os
import unittest
Expand Down

0 comments on commit 83e0463

Please sign in to comment.