Skip to content

Commit

Permalink
Add assign batch action SDK (#765)
Browse files Browse the repository at this point in the history
* Add assign batch action SDK
  • Loading branch information
rslota authored Jan 11, 2024
1 parent 869a1d6 commit 08173df
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 0 deletions.
43 changes: 43 additions & 0 deletions darwin/future/core/items/assign_items.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from __future__ import annotations

from darwin.future.core.client import ClientCore
from darwin.future.core.types.common import JSONDict, JSONType


def assign_items(
client: ClientCore,
team_slug: str,
dataset_ids: int | list[int],
assignee_id: int,
workflow_id: str,
filters: JSONDict,
) -> JSONType:
"""
Assign a user to all items matched by filters.
Args:
client (ClientCore): The Darwin Core client.
team_slug (str): The team slug.
dataset_ids (int | list[int]): The dataset ids.
assignee_id (int): The user id to assign.
workflow_id (str): The workflow id that selected items have to belong to.
filters Dict[str, UnknownType]: The parameters of the filter.
Returns:
JSONType: The response data.
"""
assert (
filters
), "No parameters provided, please provide at least one non-dataset id filter"
payload = {
"filters": {
"dataset_ids": dataset_ids
if isinstance(dataset_ids, list)
else [dataset_ids],
**filters,
},
"assignee_id": assignee_id,
"workflow_id": workflow_id,
}

return client.post(f"/v2/teams/{team_slug}/items/assign", data=payload)
26 changes: 26 additions & 0 deletions darwin/future/meta/objects/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from uuid import UUID

from darwin.future.core.items.archive_items import archive_list_of_items
from darwin.future.core.items.assign_items import assign_items
from darwin.future.core.items.delete_items import delete_list_of_items
from darwin.future.core.items.move_items_to_folder import move_list_of_items_to_folder
from darwin.future.core.items.restore_items import restore_list_of_items
Expand Down Expand Up @@ -129,6 +130,31 @@ def set_layout(self, layout: ItemLayout) -> None:
filters = {"item_ids": [str(self.id)]}
set_item_layout(self.client, team_slug, dataset_id, layout, filters)

def assign(self, assignee_id: int, workflow_id: str | None = None) -> None:
if not assignee_id:
raise ValueError("Must specify assignee to assign items to")
if not workflow_id:
# if workflow_id is not specified, get it from the meta_params
# this will be present in the case of a workflow object
if "workflow_id" in self.meta_params:
workflow_id = str(self.meta_params["workflow_id"])
else:
raise ValueError("Must specify workflow_id to set items to")
assert isinstance(workflow_id, str)
team_slug, dataset_id = (
self.meta_params["team_slug"],
self.meta_params["dataset_id"]
if "dataset_id" in self.meta_params
else self.meta_params["dataset_ids"],
)
assert isinstance(team_slug, str)

dataset_id = cast(Union[int, List[int]], dataset_id)
filters = {"item_ids": [str(self.id)]}
assign_items(
self.client, team_slug, dataset_id, assignee_id, workflow_id, filters
)

def tag(self, tag_id: int) -> None:
team_slug, dataset_id = (
self.meta_params["team_slug"],
Expand Down
35 changes: 35 additions & 0 deletions darwin/future/meta/queries/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import Dict, Protocol

from darwin.future.core.items.archive_items import archive_list_of_items
from darwin.future.core.items.assign_items import assign_items
from darwin.future.core.items.delete_items import delete_list_of_items
from darwin.future.core.items.get import list_items
from darwin.future.core.items.move_items_to_folder import move_list_of_items_to_folder
Expand Down Expand Up @@ -249,6 +250,40 @@ def untag(self, tag_id: int) -> None:
filters = {"item_ids": [str(item) for item in ids]}
untag_items(self.client, team_slug, dataset_ids, tag_id, filters)

def assign(self, assignee_id: int, workflow_id: str | None = None) -> None:
if not assignee_id:
raise ValueError("Must specify assignee to assign items to")

if "team_slug" not in self.meta_params:
raise ValueError("Must specify team_slug to query items")
if (
"dataset_ids" not in self.meta_params
and "dataset_id" not in self.meta_params
):
raise ValueError("Must specify dataset_ids to query items")
if not workflow_id:
# if workflow_id is not specified, get it from the meta_params
# this will be present in the case of a workflow object
if "workflow_id" in self.meta_params:
workflow_id = str(self.meta_params["workflow_id"])
else:
raise ValueError("Must specify workflow_id to set items to")
assert isinstance(workflow_id, str)

dataset_ids = (
self.meta_params["dataset_ids"]
if "dataset_ids" in self.meta_params
else self.meta_params["dataset_id"]
)
team_slug = self.meta_params["team_slug"]
self.collect_all()
ids = [item.id for item in self]
filters = {"item_ids": [str(item) for item in ids]}

assign_items(
self.client, team_slug, dataset_ids, assignee_id, workflow_id, filters
)

def set_stage(
self, stage_or_stage_id: hasStage | str, workflow_id: str | None = None
) -> None:
Expand Down
99 changes: 99 additions & 0 deletions darwin/future/tests/core/items/test_assign_items.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import pytest
import responses

from darwin.future.core.client import ClientCore
from darwin.future.core.items.assign_items import assign_items
from darwin.future.exceptions import BadRequest
from darwin.future.tests.core.fixtures import *


@responses.activate
def test_assign_items(base_client: ClientCore) -> None:
team_slug = "test-team"
dataset_ids = [1, 2, 3]
assignee_id = 123456
workflow_id = "123456"
item_ids = [
"00000000-0000-0000-0000-000000000001",
"00000000-0000-0000-0000-000000000002",
]
filters = {"item_ids": item_ids}

responses.add(
responses.POST,
base_client.config.api_endpoint + "v2/teams/test-team/items/assign",
json={"created_commands": 1},
status=200,
)

response = assign_items(
client=base_client,
team_slug=team_slug,
dataset_ids=dataset_ids,
assignee_id=assignee_id,
workflow_id=workflow_id,
filters=filters,
)

assert response == {"created_commands": 1}


@responses.activate
def test_assign_items_filters_error(base_client: ClientCore) -> None:
team_slug = "test-team"
dataset_ids = [1, 2, 3]
assignee_id = 123456
workflow_id = "123456"
filters = {}

responses.add(
responses.POST,
base_client.config.api_endpoint + "v2/teams/test-team/items/assign",
json={"created_commands": 1},
status=200,
)

with pytest.raises(AssertionError) as excinfo:
assign_items(
client=base_client,
team_slug=team_slug,
dataset_ids=dataset_ids,
assignee_id=assignee_id,
workflow_id=workflow_id,
filters=filters,
)
(msg,) = excinfo.value.args
assert (
msg
== "No parameters provided, please provide at least one non-dataset id filter"
)


@responses.activate
def test_assign_items_bad_request_error(base_client: ClientCore) -> None:
team_slug = "test-team"
dataset_ids = [1, 2, 3]
assignee_id = 123456
workflow_id = "123456"
item_ids = [
"00000000-0000-0000-0000-000000000001",
"00000000-0000-0000-0000-000000000002",
]
filters = {"item_ids": item_ids}

responses.add(
responses.POST,
base_client.config.api_endpoint + "v2/teams/test-team/items/assign",
json={"error": "Bad Request"},
status=400,
)

with pytest.raises(BadRequest):
assign_items(
client=base_client,
team_slug=team_slug,
dataset_ids=dataset_ids,
assignee_id=assignee_id,
workflow_id=workflow_id,
filters=filters,
)
27 changes: 27 additions & 0 deletions darwin/future/tests/meta/objects/test_itemmeta.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,3 +362,30 @@ def test_set_stage(item: Item) -> None:
json={},
)
item.set_stage(stage_id, workflow_id)


def test_assign(item: Item) -> None:
with responses.RequestsMock() as rsps:
team_slug = item.meta_params["team_slug"]
dataset_id = item.meta_params["dataset_id"]
assignee_id = 123456
workflow_id = "123456"
rsps.add(
rsps.POST,
item.client.config.api_endpoint + f"v2/teams/{team_slug}/items/assign",
status=200,
match=[
json_params_matcher(
{
"filters": {
"item_ids": [str(item.id)],
"dataset_ids": [dataset_id],
},
"assignee_id": assignee_id,
"workflow_id": workflow_id,
}
)
],
json={},
)
item.assign(assignee_id, workflow_id)

0 comments on commit 08173df

Please sign in to comment.