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
51 changes: 51 additions & 0 deletions annofabapi/util/annotation_specs.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ class AttributeDefinition(TypedDict):
choices: list[AttributeChoice] | None


class InspectionPhrase(TypedDict):
"""定型指摘です。"""

id: str
text: InternationalizationMessage


class LabelDefinition(TypedDict):
"""アノテーション仕様上のラベル定義です。"""

Expand Down Expand Up @@ -261,6 +268,30 @@ def get_label(labels: list[LabelDefinition], *, label_id: str | None = None, lab
return result[0]


def get_inspection_phrase(
inspection_phrases: list[InspectionPhrase],
*,
inspection_phrase_id: str,
) -> InspectionPhrase:
"""
定型指摘を取得します。

Args:
inspection_phrases: 定型指摘のリスト
inspection_phrase_id: 定型指摘ID

Raises:
ValueError: 引数に合致する定型指摘が見つからない。または複数見つかった。
"""
result = [e for e in inspection_phrases if e["id"] == inspection_phrase_id]

if len(result) == 0:
raise ValueError(f"定型指摘が見つかりませんでした。 :: inspection_phrase_id='{inspection_phrase_id}'")
if len(result) > 1:
raise ValueError(f"定型指摘が複数({len(result)}件)見つかりました。 :: inspection_phrase_id='{inspection_phrase_id}'")
return result[0]


class AnnotationSpecsAccessor:
"""
アノテーション仕様の情報にアクセスするためのクラス。
Expand All @@ -273,6 +304,7 @@ def __init__(self, annotation_specs: dict[str, Any]) -> None:
self.annotation_specs = annotation_specs
self.labels: list[LabelDefinition] = annotation_specs["labels"]
self.additionals: list[AttributeDefinition] = annotation_specs["additionals"]
self.inspection_phrases: list[InspectionPhrase] = annotation_specs["inspection_phrases"]

def get_attribute(
self, *, attribute_id: str | None = None, attribute_name: str | None = None, label: LabelDefinition | None = None
Expand Down Expand Up @@ -304,3 +336,22 @@ def get_label(self, *, label_id: str | None = None, label_name: str | None = Non

"""
return get_label(self.labels, label_id=label_id, label_name=label_name)

def get_inspection_phrase(
self,
*,
inspection_phrase_id: str,
) -> InspectionPhrase:
"""
定型指摘を取得します。

Args:
inspection_phrase_id: 定型指摘ID

Raises:
ValueError: 引数に合致する定型指摘が見つからない。または複数見つかった。
"""
return get_inspection_phrase(
self.inspection_phrases,
inspection_phrase_id=inspection_phrase_id,
)
47 changes: 47 additions & 0 deletions tests/util/test_annotation_specs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
from annofabapi.util.annotation_specs import (
AnnotationSpecsAccessor,
AttributeChoice,
InspectionPhrase,
LabelNameHolder,
Lang,
NameHolder,
get_attribute_name_en,
get_choice,
get_choice_name_en,
get_english_message,
get_inspection_phrase,
get_label_name_en,
get_message_with_lang,
)
Expand Down Expand Up @@ -105,6 +107,26 @@ def setup_method(self):
{"additional_data_definition_id": "1", "name": {"messages": [{"lang": "en-US", "message": "Color"}]}},
{"additional_data_definition_id": "2", "name": {"messages": [{"lang": "en-US", "message": "Size"}]}},
],
"inspection_phrases": [
{
"id": "inspection_phrase_id_1",
"text": {
"messages": [
{"lang": "ja-JP", "message": "画像がぼやけています。"},
{"lang": "en-US", "message": "The image is blurry."},
]
},
},
{
"id": "inspection_phrase_id_2",
"text": {
"messages": [
{"lang": "ja-JP", "message": "対象物が隠れています。"},
{"lang": "en-US", "message": "The object is occluded."},
]
},
},
],
}
self.accessor = AnnotationSpecsAccessor(self.annotation_specs)

Expand Down Expand Up @@ -147,6 +169,31 @@ def test_get_attribute_by_id_and_label__not_found(self):
with pytest.raises(ValueError):
self.accessor.get_attribute(attribute_id="1", label=label)

def test_get_inspection_phrase_by_id(self):
inspection_phrase = self.accessor.get_inspection_phrase(inspection_phrase_id="inspection_phrase_id_1")
assert inspection_phrase["id"] == "inspection_phrase_id_1"
assert get_message_with_lang(inspection_phrase["text"], Lang.EN_US) == "The image is blurry."

def test_get_inspection_phrase_not_found(self):
with pytest.raises(ValueError):
self.accessor.get_inspection_phrase(inspection_phrase_id="inspection_phrase_id_3")


class Test__get_inspection_phrase:
def setup_method(self):
self.inspection_phrases: list[InspectionPhrase] = [
{"id": "1", "text": {"messages": [{"lang": "en-US", "message": "Blurry image"}]}},
{"id": "2", "text": {"messages": [{"lang": "en-US", "message": "Occluded object"}]}},
]

def test_get_inspection_phrase_by_id(self):
inspection_phrase = get_inspection_phrase(self.inspection_phrases, inspection_phrase_id="1")
assert inspection_phrase["id"] == "1"

def test_get_inspection_phrase_not_found(self):
with pytest.raises(ValueError):
get_inspection_phrase(self.inspection_phrases, inspection_phrase_id="3")
Comment on lines +193 to +195


class Test__get_choice:
def setup_method(self):
Expand Down