Skip to content

Commit f12ab1c

Browse files
authored
Merge pull request #122 from kurusugawa-computer/add-annotation-dataclass
get_editor_annotation 関係のDataClassを追加
2 parents cfc7c01 + 333ee8d commit f12ab1c

File tree

8 files changed

+248
-26
lines changed

8 files changed

+248
-26
lines changed

Pipfile.lock

+3-19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

annofabapi/__version__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '0.27.0'
1+
__version__ = '0.27.1'

annofabapi/dataclass/annotation.py

+60-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from annofabapi.models import (AdditionalDataDefinitionType, AnnotationDataHoldingType, AnnotationType,
1818
InternationalizationMessage, TaskPhase, TaskStatus)
1919

20-
OneOfstringFullAnnotationData = Dict[str, Any]
20+
OneOfstringFullAnnotationData = Union[str, Dict[str, Any]]
2121
FullAnnotationData = Dict[str, Any]
2222
AdditionalDataValue = Dict[str, Any]
2323

@@ -291,3 +291,62 @@ class SingleAnnotation:
291291

292292
updated_datetime: str
293293
""""""
294+
295+
296+
@dataclass_json
297+
@dataclass
298+
class AnnotationDetail:
299+
"""
300+
301+
"""
302+
annotation_id: str
303+
"""アノテーションID。[値の制約についてはこちら。](#section/API-Convention/APIID)<br> annotation_type が classification の場合は label_id と同じ値が格納されます。 """
304+
305+
account_id: str
306+
""""""
307+
308+
label_id: str
309+
""""""
310+
311+
is_protected: bool
312+
""""""
313+
314+
data_holding_type: AnnotationDataHoldingType
315+
""""""
316+
317+
data: Optional[OneOfstringFullAnnotationData]
318+
"""data_holding_type が inner の場合のみ存在し、annotation_type に応じたデータの値が格納されます。 `string`もしくは`object`の値を指定することができ、`string`の形式は次の通りです。 * annotation_type が bounding_box の場合: 左上x,左上y,右下x,右下y のCSV文字列形式。 * annotation_type が polygon/polyline の場合: x1,y1,x2,y2, ... のCSV文字列形式。 * annotation_type が segmentation または segmentation_v2 の場合: 塗っていないところは rgba(0,0,0,0)、塗ったところは rgba(255,255,255,1) の PNGデータをBase64エンコードしたもの。 * annotation_type が classification の場合: data 属性は存在しない。 * annotation_type が range の場合: 開始時間,終了時間 のCSV文字列形式。 """
319+
320+
path: Optional[str]
321+
"""data_holding_typeがouterの場合のみ存在し、データのパスが格納される (現在はアノテーションIDと等しい)"""
322+
323+
etag: Optional[str]
324+
"""data_holding_typeがouterの場合のみ存在し、データのETagが格納される"""
325+
326+
url: Optional[str]
327+
"""data_holding_typeがouterの場合のみ存在し、データへの一時URLが格納される"""
328+
329+
additional_data_list: List[AdditionalData]
330+
"""各要素は、 [アノテーション仕様](#operation/getAnnotationSpecs)で定義された属性(`additional_data_definitions`内)のいずれかの要素と対応づけます。 各要素は、どの属性なのかを表す`additional_data_definition_id`、値が必要です。値は、属性の種類に対応するキーに格納します(下表)。 <table> <tr><th>アノテーション属性の種類<br>(`additional_data_definition`の`type`)</th><th>属性の値を格納するキー</th><th>データ型</th></tr> <tr><td>`comment` または `tracking`</td><td>`comment`</td><td>string</td></tr> <tr><td>`flag`</td><td>`flag`</td><td>boolean</td></tr> <tr><td>`integer`</td><td>`integer`</td><td>integer</td></tr> <tr><td>`choice` または `select`</td><td>`choice`</td><td>string(選択肢ID)</td></tr> <tr><td>`link`</td><td>`comment`</td><td>string(アノテーションID)</td></tr> </table> """
331+
332+
333+
@dataclass_json
334+
@dataclass
335+
class Annotation:
336+
"""
337+
338+
"""
339+
project_id: str
340+
"""プロジェクトID。[値の制約についてはこちら。](#section/API-Convention/APIID) """
341+
342+
task_id: str
343+
"""タスクID。[値の制約についてはこちら。](#section/API-Convention/APIID) """
344+
345+
input_data_id: str
346+
"""入力データID。[値の制約についてはこちら。](#section/API-Convention/APIID) """
347+
348+
details: List[AnnotationDetail]
349+
""""""
350+
351+
updated_datetime: Optional[str]
352+
"""新規作成時は未指定、更新時は必須(更新前の日時) """

generate/generate.sh

+4-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,10 @@ declare -a model_files=(${MODELS_DIR}/point.py \
124124
${MODELS_DIR}/simple_annotation_detail.py \
125125
${MODELS_DIR}/simple_annotation.py \
126126
${MODELS_DIR}/single_annotation_detail.py \
127-
${MODELS_DIR}/single_annotation.py)
127+
${MODELS_DIR}/single_annotation.py \
128+
${MODELS_DIR}/annotation_detail.py \
129+
${MODELS_DIR}/annotation.py \
130+
)
128131
cat partial-header/dataclass/common.py partial-header/dataclass/annotation.py \
129132
${model_files[@]} > ../annofabapi/dataclass/annotation.py
130133

Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from annofabapi.models import (AnnotationDataHoldingType, InternationalizationMessage, AdditionalDataDefinitionType,
22
AnnotationType, TaskPhase, TaskStatus)
33

4-
OneOfstringFullAnnotationData = Dict[str, Any]
4+
OneOfstringFullAnnotationData = Union[str, Dict[str, Any]]
55
FullAnnotationData = Dict[str, Any]
66
AdditionalDataValue = Dict[str, Any]

tests/data/dataclass/annotation.json

+164
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
{
2+
"project_id": "a2345678-abcd-1234-abcd-1234abcd5678",
3+
"task_id": "sample_1",
4+
"input_data_id": "c6e1c2ec-6c7c-41c6-9639-4244c2ed2839",
5+
"details": [
6+
{
7+
"annotation_id": "9a15fac0-736f-454f-a50d-7da094bc133d",
8+
"account_id": "12345678-abcd-1234-abcd-1234abcd5678",
9+
"label_id": "ded52dcb-bcd6-4e77-9626-61e546f635d0",
10+
"is_protected": false,
11+
"data_holding_type": "inner",
12+
"data": "15,55,12,49,9,43,16,36,21,39,24,53",
13+
"path": null,
14+
"etag": null,
15+
"url": null,
16+
"additional_data_list": [],
17+
"created_datetime": "2019-08-22T12:04:19.256+09:00",
18+
"updated_datetime": "2019-08-22T12:04:19.256+09:00"
19+
},
20+
{
21+
"annotation_id": "762f113a-5e17-4b49-861e-dfbea1dda09d",
22+
"account_id": "12345678-abcd-1234-abcd-1234abcd5678",
23+
"label_id": "2ffb4c74-106b-44ac-81ce-3c3df77518e0",
24+
"is_protected": false,
25+
"data_holding_type": "outer",
26+
"data": null,
27+
"path": "762f113a-5e17-4b49-861e-dfbea1dda09d",
28+
"etag": "\"c4132827dd8cbd28faf3048c6a84ad02\"",
29+
"url": "https://s3.ap-northeast-1.amazonaws.com/annotationfactory.production.annotation/foo1",
30+
"additional_data_list": [],
31+
"created_datetime": "2019-08-22T12:04:19.256+09:00",
32+
"updated_datetime": "2019-08-22T12:04:19.256+09:00"
33+
},
34+
{
35+
"annotation_id": "1e2931d2-de34-4956-ab75-81f710dc0108",
36+
"account_id": "12345678-abcd-1234-abcd-1234abcd5678",
37+
"label_id": "108ce1f7-217b-43e9-a407-8d0ac6aad87e",
38+
"is_protected": false,
39+
"data_holding_type": "outer",
40+
"data": null,
41+
"path": "1e2931d2-de34-4956-ab75-81f710dc0108",
42+
"etag": "\"51add6e8b7684d3c8327de3a70cdad93\"",
43+
"url": "https://s3.ap-northeast-1.amazonaws.com/annotationfactory.production.annotation/foo2",
44+
"additional_data_list": [],
45+
"created_datetime": "2019-08-22T12:04:19.256+09:00",
46+
"updated_datetime": "2019-08-22T12:04:19.256+09:00"
47+
},
48+
{
49+
"annotation_id": "a05019fd-6e23-456b-9971-641a45979d98",
50+
"account_id": "12345678-abcd-1234-abcd-1234abcd5678",
51+
"label_id": "f50aa88d-36c7-43f5-8728-247a49b4f4d8",
52+
"is_protected": false,
53+
"data_holding_type": "inner",
54+
"data": "25,18",
55+
"path": null,
56+
"etag": null,
57+
"url": null,
58+
"additional_data_list": [],
59+
"created_datetime": "2019-08-22T12:04:19.256+09:00",
60+
"updated_datetime": "2019-08-22T12:04:19.256+09:00"
61+
},
62+
{
63+
"annotation_id": "c9c688d1-6c05-4118-94c7-308185cdb60a",
64+
"account_id": "12345678-abcd-1234-abcd-1234abcd5678",
65+
"label_id": "c754f724-5f8c-48eb-81ec-ea77e55efee7",
66+
"is_protected": false,
67+
"data_holding_type": "inner",
68+
"data": "22,29,33,41",
69+
"path": null,
70+
"etag": null,
71+
"url": null,
72+
"additional_data_list": [],
73+
"created_datetime": "2019-08-22T12:04:19.256+09:00",
74+
"updated_datetime": "2019-08-22T12:04:19.256+09:00"
75+
},
76+
{
77+
"annotation_id": "6602c86c-5e22-42b9-b5a4-8a77c7bade01",
78+
"account_id": "12345678-abcd-1234-abcd-1234abcd5678",
79+
"label_id": "15ba7932-24b9-4cf3-95bd-9bf6deede4fa",
80+
"is_protected": false,
81+
"data_holding_type": "inner",
82+
"data": "10,7,36,36",
83+
"path": null,
84+
"etag": null,
85+
"url": null,
86+
"additional_data_list": [
87+
{
88+
"additional_data_definition_id": "e6864d96-78fa-45f3-a786-6c8c900c92ae",
89+
"flag": true,
90+
"integer": null,
91+
"comment": null,
92+
"choice": null
93+
},
94+
{
95+
"additional_data_definition_id": "51e8c91f-5de1-450b-a0f3-94fec582f5ce",
96+
"flag": null,
97+
"integer": null,
98+
"comment": "a05019fd-6e23-456b-9971-641a45979d98",
99+
"choice": null
100+
},
101+
{
102+
"additional_data_definition_id": "aff2855e-2e3d-47a2-8c27-c7652e4dfb2f",
103+
"flag": null,
104+
"integer": 3,
105+
"comment": null,
106+
"choice": null
107+
},
108+
{
109+
"additional_data_definition_id": "7e6a577a-3410-4c8a-9624-2904bb2e6666",
110+
"flag": null,
111+
"integer": null,
112+
"comment": "lena",
113+
"choice": null
114+
},
115+
{
116+
"additional_data_definition_id": "a63a0513-a96e-4c7c-8754-88a24fef9ca9",
117+
"flag": null,
118+
"integer": null,
119+
"comment": "テスト",
120+
"choice": null
121+
},
122+
{
123+
"additional_data_definition_id": "649abf45-1ed7-459a-8282-a58228e9a302",
124+
"flag": null,
125+
"integer": null,
126+
"comment": "6602c86c-5e22-42b9-b5a4-8a77c7bade01",
127+
"choice": null
128+
}
129+
],
130+
"created_datetime": "2019-08-22T12:04:19.256+09:00",
131+
"updated_datetime": "2019-08-22T12:04:33.37+09:00"
132+
},
133+
{
134+
"annotation_id": "5ac0d7d5-6738-4c4b-a69a-cd583ff458e1",
135+
"account_id": "12345678-abcd-1234-abcd-1234abcd5678",
136+
"label_id": "5ac0d7d5-6738-4c4b-a69a-cd583ff458e1",
137+
"is_protected": false,
138+
"data_holding_type": "inner",
139+
"data": null,
140+
"path": null,
141+
"etag": null,
142+
"url": null,
143+
"additional_data_list": [
144+
{
145+
"additional_data_definition_id": "896d7eeb-9c60-4fbf-b7c4-8f4209261049",
146+
"flag": null,
147+
"integer": null,
148+
"comment": null,
149+
"choice": "c9615782-b872-4641-9be4-0fb4f905d966"
150+
},
151+
{
152+
"additional_data_definition_id": "60caffa5-6300-4819-9a99-c43ce49008c2",
153+
"flag": null,
154+
"integer": null,
155+
"comment": null,
156+
"choice": "bdcd4d5b-cecc-4ec9-9038-d9284cd4f475"
157+
}
158+
],
159+
"created_datetime": "2019-08-22T12:04:19.256+09:00",
160+
"updated_datetime": "2019-08-22T12:04:19.256+09:00"
161+
}
162+
],
163+
"updated_datetime": "2019-08-22T14:10:14.758+09:00"
164+
}

tests/test_dataclass.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import configparser
22
import os
3-
from distutils.util import strtobool
43
from pathlib import Path
54

65
import annofabapi
76
import annofabapi.utils
8-
from annofabapi.dataclass.annotation import SimpleAnnotation, SingleAnnotation
7+
from annofabapi.dataclass.annotation import Annotation, SimpleAnnotation, SingleAnnotation
98
from annofabapi.dataclass.annotation_specs import AnnotationSpecsV1
109
from annofabapi.dataclass.input import InputData
1110
from annofabapi.dataclass.inspection import Inspection
@@ -43,6 +42,11 @@
4342

4443

4544
class TestAnnotation:
45+
def test_get_editor_annotation(self):
46+
dict_obj, _ = service.api.get_editor_annotation(project_id, task_id, input_data_id)
47+
dataclass_obj = Annotation.from_dict(dict_obj)
48+
assert type(dataclass_obj) == Annotation
49+
4650
def test_simple_annotation(self):
4751
annotation_list = service.wrapper.get_all_annotation_list(project_id,
4852
query_params={'query': {

tests/test_local_dataclass.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import os
44
from pathlib import Path
55

6-
from annofabapi.dataclass.annotation import FullAnnotation, SimpleAnnotation
6+
from annofabapi.dataclass.annotation import Annotation, FullAnnotation, SimpleAnnotation
77
from annofabapi.dataclass.annotation_specs import AnnotationSpecsV1
88
from annofabapi.dataclass.input import InputData
99
from annofabapi.dataclass.inspection import Inspection
@@ -29,6 +29,14 @@
2929

3030

3131
class TestAnnotation:
32+
def test_annotation(self):
33+
json_path = test_dir / "annotation.json"
34+
with json_path.open(encoding="utf-8") as f:
35+
dict_obj = json.load(f)
36+
print(dict_obj)
37+
dataclass_obj = Annotation.from_dict(dict_obj)
38+
assert type(dataclass_obj) == Annotation
39+
3240
def test_simple_annotation_for_image(self):
3341
simple_annotaion_json = test_dir / "simple-annotation.json"
3442
with simple_annotaion_json.open(encoding="utf-8") as f:

0 commit comments

Comments
 (0)