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
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:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check this parses with the doc generation tool.

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")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't need this to be a ValueError, this could be an assert.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Urgh, I just merged this before I got email about your comments :(
But this code is copied from other similar functions, so that keeps it consistent with them anyway.

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)