Add projects.get_task_parents

This commit is contained in:
allegroai 2021-01-05 18:49:25 +02:00
parent 88836fae66
commit 64c63d2560
5 changed files with 112 additions and 2 deletions

View File

@ -15,3 +15,7 @@ class GetHyperParamReq(ProjectReq):
class ProjectTagsRequest(TagsRequest):
projects = ListField(str)
class ProjectTaskParentsRequest(ProjectReq):
projects = ListField(str)

View File

@ -1,7 +1,10 @@
from collections import defaultdict
from enum import Enum
from operator import itemgetter
from typing import Sequence, Dict
from mongoengine import Q
from apiserver.config_repo import config
from apiserver.database.model.model import Model
from apiserver.database.model.task.task import Task
@ -61,3 +64,24 @@ class OrgBLL:
def _get_tags_cache_for_entity(self, entity: Tags) -> _TagsCache:
return self._task_tags if entity == Tags.Task else self._model_tags
@classmethod
def get_parent_tasks(
cls, company_id: str, projects: Sequence[str]
) -> Sequence[dict]:
"""
Get list of unique parent tasks sorted by task name for the passed company projects
If projects is None or empty then get parents for all the company tasks
"""
query = Q(company=company_id)
if projects:
query &= Q(project__in=projects)
parent_ids = set(Task.objects(query).distinct("parent"))
if not parent_ids:
return []
parents = [
{"id": task.id, "name": task.name}
for task in Task.objects(id__in=parent_ids).only("id", "name")
]
return sorted(parents, key=itemgetter("name"))

View File

@ -638,4 +638,41 @@ make_private {
}
}
}
}
get_task_parents {
"2.12" {
description: "Get unique parent tasks for the tasks in the specified pprojects"
request {
type: object
properties {
projects {
description: "The list of projects which task parents are retieved. If not passed or empty then all the projects are searched"
type: array
items { type: string }
}
}
}
response {
type: object
properties {
parents {
description: "The list of unique task parents sorted by their names"
type: array
items {
type: object
properties {
id {
description: "The ID of the parent task"
type: string
}
name {
description: "The name of the parent task"
type: string
}
}
}
}
}
}
}
}

View File

@ -13,6 +13,7 @@ from apiserver.apimodels.projects import (
GetHyperParamReq,
ProjectReq,
ProjectTagsRequest,
ProjectTaskParentsRequest,
)
from apiserver.bll.organization import OrgBLL, Tags
from apiserver.bll.project import ProjectBLL
@ -22,7 +23,11 @@ from apiserver.database.model import EntityVisibility
from apiserver.database.model.model import Model
from apiserver.database.model.project import Project
from apiserver.database.model.task.task import Task, TaskStatus
from apiserver.database.utils import parse_from_call, get_options, get_company_or_none_constraint
from apiserver.database.utils import (
parse_from_call,
get_options,
get_company_or_none_constraint,
)
from apiserver.service_repo import APICall, endpoint
from apiserver.services.utils import (
conform_tag_fields,
@ -438,3 +443,16 @@ def make_public(call: APICall, company_id, request: MakePublicRequest):
call.result.data = Project.set_public(
company_id, ids=request.ids, invalid_cls=InvalidProjectId, enabled=False
)
@endpoint(
"projects.get_task_parents",
min_version="2.12",
request_data_model=ProjectTaskParentsRequest,
)
def get_task_parents(
call: APICall, company_id: str, request: ProjectTaskParentsRequest
):
call.result.data = {
"parents": org_bll.get_parent_tasks(company_id, projects=request.projects)
}

View File

@ -4,9 +4,36 @@ from apiserver.tests.automated import TestService
class TestProjectTags(TestService):
def setUp(self, version="2.8"):
def setUp(self, version="2.12"):
super().setUp(version=version)
def test_task_parent(self):
# stand alone task
parent_sa_name = "Test parent parent standalone"
parent_sa = self.new_task(name=parent_sa_name)
self.new_task(name="Test parent task standalone", parent=parent_sa)
# tasks in projects
parent_name = "Test parent parent"
parent = self.new_task(name=parent_name)
p1 = self.create_temp("projects", name="Test parents1", description="test")
self.new_task(project=p1, name="Test parent task1", parent=parent)
p2 = self.create_temp("projects", name="Test parents2", description="test")
self.new_task(project=p1, name="Test parent task2", parent=parent)
parents = self.api.projects.get_task_parents(projects=[p1, p2]).parents
self.assertEqual([{"id": parent, "name": parent_name}], parents)
res = self.api.projects.get_task_parents()
parents = [p for p in res.parents if p.id in (parent, parent_sa)]
self.assertEqual(
[
{"id": parent, "name": parent_name},
{"id": parent_sa, "name": parent_sa_name},
],
parents,
)
def test_project_tags(self):
tags_1 = ["Test tag 1", "Test tag 2"]
tags_2 = ["Test tag 3", "Test tag 4"]