diff --git a/darwin/future/core/client.py b/darwin/future/core/client.py index 7e6d4387b..8b113beb1 100644 --- a/darwin/future/core/client.py +++ b/darwin/future/core/client.py @@ -10,7 +10,7 @@ from requests.adapters import HTTPAdapter, Retry from darwin.future.core.types.common import JSONType, QueryString -from darwin.future.exceptions import NotFound, Unauthorized +from darwin.future.exceptions import NotFound, Unauthorized, UnprocessibleEntity class TeamsConfig(BaseModel): @@ -245,3 +245,5 @@ def raise_for_darwin_exception(response: requests.Response) -> None: raise Unauthorized(response) if response.status_code == 404: raise NotFound(response) + if response.status_code == 422: + raise UnprocessibleEntity(response) diff --git a/darwin/future/core/items/archive_items.py b/darwin/future/core/items/archive_items.py new file mode 100644 index 000000000..898f8e921 --- /dev/null +++ b/darwin/future/core/items/archive_items.py @@ -0,0 +1,44 @@ +from typing import Dict, List +from uuid import UUID + +from darwin.future.core.client import ClientCore +from darwin.future.core.types.common import JSONType +from darwin.future.data_objects.typing import UnknownType + + +def archive_list_of_items( + api_client: ClientCore, + team_slug: str, + dataset_id: int, + item_ids: List[UUID], + filters: Dict[str, UnknownType] = {}, +) -> JSONType: + """ + Archive specified items + + Parameters + ---------- + client: Client + The client to use for the request + team_slug: str + The slug of the team containing the items + dataset_id: int + The ID of the dataset containing the items + item_ids: List[UUID] + The IDs of the items to be archived + filters: Dict[str, UnknownType] + Dataset filter parameters + + Returns + ------- + JSONType + """ + payload = { + "filters": { + "dataset_ids": [dataset_id], + "item_ids": [str(item_id) for item_id in item_ids], + **filters, + } + } + + return api_client.post(f"/v2/teams/{team_slug}/items/archive", data=payload) diff --git a/darwin/future/exceptions.py b/darwin/future/exceptions.py index 72f5e760d..c33310306 100644 --- a/darwin/future/exceptions.py +++ b/darwin/future/exceptions.py @@ -69,6 +69,10 @@ class NotFound(DarwinException): pass +class UnprocessibleEntity(DarwinException): + pass + + class Unauthorized(DarwinException): pass diff --git a/darwin/future/tests/core/items/test_archive_items.py b/darwin/future/tests/core/items/test_archive_items.py new file mode 100644 index 000000000..da5b3740c --- /dev/null +++ b/darwin/future/tests/core/items/test_archive_items.py @@ -0,0 +1,54 @@ +from unittest.mock import Mock +from uuid import UUID + +import pytest +import responses + +from darwin.exceptions import DarwinException +from darwin.future.core.client import ClientCore +from darwin.future.core.items.archive_items import archive_list_of_items +from darwin.future.tests.core.fixtures import * + + +@responses.activate +def test_archive_items_including_filters(base_client: ClientCore) -> None: + # Define the expected response + responses.add( + responses.POST, + base_client.config.api_endpoint + "v2/teams/test-team/items/archive", + json={"affected_item_count": 2}, + ) + + # Call the function + response = archive_list_of_items( + api_client=base_client, + team_slug="test-team", + dataset_id=000000, + item_ids=[ + UUID("00000000-0000-0000-0000-000000000000"), + UUID("00000000-0000-0000-0000-000000000000"), + ], + filters={ + "not_statuses": ["uploading", "annotate"], + "not_assignees": [123, 456, 789], + }, + ) + + # Check that the response mathces what we expect + assert response == {"affected_item_count": 2} + + +def test_archive_items_with_error_response() -> None: + api_client = Mock(spec=ClientCore) + api_client.post.side_effect = DarwinException("Something went wrong") + + with pytest.raises(DarwinException): + archive_list_of_items( + api_client=api_client, + team_slug="test-team", + dataset_id=000000, + item_ids=[ + UUID("00000000-0000-0000-0000-000000000000"), + UUID("00000000-0000-0000-0000-000000000000"), + ], + )