annofabcli 1.106.0__py3-none-any.whl → 1.106.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- annofabcli/annotation/dump_annotation.py +26 -11
- annofabcli/project/copy_project.py +3 -1
- {annofabcli-1.106.0.dist-info → annofabcli-1.106.1.dist-info}/METADATA +1 -1
- {annofabcli-1.106.0.dist-info → annofabcli-1.106.1.dist-info}/RECORD +7 -7
- {annofabcli-1.106.0.dist-info → annofabcli-1.106.1.dist-info}/WHEEL +0 -0
- {annofabcli-1.106.0.dist-info → annofabcli-1.106.1.dist-info}/entry_points.txt +0 -0
- {annofabcli-1.106.0.dist-info → annofabcli-1.106.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -63,12 +63,12 @@ class DumpAnnotationMain:
|
|
|
63
63
|
outer_file_path = outer_dir / f"{annotation_id}"
|
|
64
64
|
self.service.wrapper.download(detail["url"], outer_file_path)
|
|
65
65
|
|
|
66
|
-
def dump_annotation_for_input_data(self, task_id: str, input_data_id: str, task_dir: Path) -> None:
|
|
67
|
-
editor_annotation, _ = self.service.api.get_editor_annotation(self.project_id, task_id, input_data_id, query_params={"v": "2"})
|
|
66
|
+
def dump_annotation_for_input_data(self, task_id: str, input_data_id: str, task_dir: Path, *, task_history_id: Optional[str] = None) -> None:
|
|
67
|
+
editor_annotation, _ = self.service.api.get_editor_annotation(self.project_id, task_id, input_data_id, query_params={"v": "2", "task_history_id": task_history_id})
|
|
68
68
|
json_path = task_dir / f"{input_data_id}.json"
|
|
69
69
|
self.dump_editor_annotation(editor_annotation=editor_annotation, json_path=json_path)
|
|
70
70
|
|
|
71
|
-
def dump_annotation_for_task(self, task_id: str, output_dir: Path, *, task_index: Optional[int] = None) -> bool:
|
|
71
|
+
def dump_annotation_for_task(self, task_id: str, output_dir: Path, *, task_index: Optional[int] = None, task_history_index: Optional[int] = None) -> bool:
|
|
72
72
|
"""
|
|
73
73
|
タスク配下のアノテーションをファイルに保存する。
|
|
74
74
|
|
|
@@ -85,15 +85,23 @@ class DumpAnnotationMain:
|
|
|
85
85
|
logger.warning(f"task_id = '{task_id}' のタスクは存在しません。スキップします。")
|
|
86
86
|
return False
|
|
87
87
|
|
|
88
|
+
task_history_id: Optional[str] = None
|
|
89
|
+
if task_history_index is not None:
|
|
90
|
+
task_histories, _ = self.service.api.get_task_histories(self.project_id, task_id)
|
|
91
|
+
if task_history_index >= len(task_histories):
|
|
92
|
+
logger.warning(f"task_id='{task_id}' :: task_history_index='{task_history_index}'のタスク履歴は存在しません。タスク履歴は{len(task_histories)}件です。スキップします。")
|
|
93
|
+
return False
|
|
94
|
+
task_history_id = task_histories[task_history_index]["task_history_id"]
|
|
95
|
+
|
|
88
96
|
input_data_id_list = task["input_data_id_list"]
|
|
89
97
|
task_dir = output_dir / task_id
|
|
90
98
|
task_dir.mkdir(exist_ok=True, parents=True)
|
|
91
|
-
logger.debug(f"{logger_prefix}task_id = '{task_id}' のアノテーション情報を '{task_dir}' ディレクトリに保存します。")
|
|
99
|
+
logger.debug(f"{logger_prefix}task_id = '{task_id}' のアノテーション情報を '{task_dir}' ディレクトリに保存します。 :: task_history_id='{task_history_id}'")
|
|
92
100
|
|
|
93
101
|
is_failure = False
|
|
94
102
|
for input_data_id in input_data_id_list:
|
|
95
103
|
try:
|
|
96
|
-
self.dump_annotation_for_input_data(task_id, input_data_id, task_dir=task_dir)
|
|
104
|
+
self.dump_annotation_for_input_data(task_id, input_data_id, task_dir=task_dir, task_history_id=task_history_id)
|
|
97
105
|
except Exception:
|
|
98
106
|
logger.warning(f"タスク'{task_id}', 入力データ'{input_data_id}' のアノテーション情報のダンプに失敗しました。", exc_info=True)
|
|
99
107
|
is_failure = True
|
|
@@ -101,15 +109,15 @@ class DumpAnnotationMain:
|
|
|
101
109
|
|
|
102
110
|
return not is_failure
|
|
103
111
|
|
|
104
|
-
def dump_annotation_for_task_wrapper(self, tpl: tuple[int, str], output_dir: Path) -> bool:
|
|
112
|
+
def dump_annotation_for_task_wrapper(self, tpl: tuple[int, str], output_dir: Path, *, task_history_index: Optional[int] = None) -> bool:
|
|
105
113
|
task_index, task_id = tpl
|
|
106
114
|
try:
|
|
107
|
-
return self.dump_annotation_for_task(task_id, output_dir=output_dir, task_index=task_index)
|
|
115
|
+
return self.dump_annotation_for_task(task_id, output_dir=output_dir, task_index=task_index, task_history_index=task_history_index)
|
|
108
116
|
except Exception: # pylint: disable=broad-except
|
|
109
117
|
logger.warning(f"タスク'{task_id}'のアノテーション情報のダンプに失敗しました。", exc_info=True)
|
|
110
118
|
return False
|
|
111
119
|
|
|
112
|
-
def dump_annotation(self, task_id_list: list[str], output_dir: Path, parallelism: Optional[int] = None)
|
|
120
|
+
def dump_annotation(self, task_id_list: list[str], output_dir: Path, *, task_history_index: Optional[int] = None, parallelism: Optional[int] = None) -> None:
|
|
113
121
|
project_title = self.facade.get_project_title(self.project_id)
|
|
114
122
|
logger.info(f"プロジェクト'{project_title}'に対して、タスク{len(task_id_list)} 件のアノテーションをファイルに保存します。")
|
|
115
123
|
|
|
@@ -118,7 +126,7 @@ class DumpAnnotationMain:
|
|
|
118
126
|
success_count = 0
|
|
119
127
|
|
|
120
128
|
if parallelism is not None:
|
|
121
|
-
func = functools.partial(self.dump_annotation_for_task_wrapper, output_dir=output_dir)
|
|
129
|
+
func = functools.partial(self.dump_annotation_for_task_wrapper, task_history_index=task_history_index, output_dir=output_dir)
|
|
122
130
|
with multiprocessing.Pool(parallelism) as pool:
|
|
123
131
|
result_bool_list = pool.map(func, enumerate(task_id_list))
|
|
124
132
|
success_count = len([e for e in result_bool_list if e])
|
|
@@ -126,7 +134,7 @@ class DumpAnnotationMain:
|
|
|
126
134
|
else:
|
|
127
135
|
for task_index, task_id in enumerate(task_id_list):
|
|
128
136
|
try:
|
|
129
|
-
result = self.dump_annotation_for_task(task_id, output_dir=output_dir, task_index=task_index)
|
|
137
|
+
result = self.dump_annotation_for_task(task_id, output_dir=output_dir, task_history_index=task_history_index, task_index=task_index)
|
|
130
138
|
if result:
|
|
131
139
|
success_count += 1
|
|
132
140
|
except Exception:
|
|
@@ -149,7 +157,7 @@ class DumpAnnotation(CommandLine):
|
|
|
149
157
|
super().validate_project(project_id, project_member_roles=None)
|
|
150
158
|
|
|
151
159
|
main_obj = DumpAnnotationMain(self.service, project_id)
|
|
152
|
-
main_obj.dump_annotation(task_id_list, output_dir=output_dir, parallelism=args.parallelism)
|
|
160
|
+
main_obj.dump_annotation(task_id_list, output_dir=output_dir, parallelism=args.parallelism, task_history_index=args.task_history_index)
|
|
153
161
|
|
|
154
162
|
|
|
155
163
|
def main(args: argparse.Namespace) -> None:
|
|
@@ -166,6 +174,13 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
166
174
|
|
|
167
175
|
parser.add_argument("-o", "--output_dir", type=str, required=True, help="出力先ディレクトリのパス")
|
|
168
176
|
|
|
177
|
+
parser.add_argument(
|
|
178
|
+
"--task_history_index",
|
|
179
|
+
type=int,
|
|
180
|
+
help="指定したタスク履歴のインデックス(ゼロ始まり)で付与されたアノテーション情報をダンプします。過去のアノテーション結果をダンプする場合に指定します。"
|
|
181
|
+
"ただし、過去のアノテーションデータは30日間しか保持されません。30日より前に更新されたアノテーションをダンプした場合は、アノテーションが0件の状態でダンプされます。",
|
|
182
|
+
)
|
|
183
|
+
|
|
169
184
|
parser.add_argument(
|
|
170
185
|
"--parallelism",
|
|
171
186
|
type=int,
|
|
@@ -83,6 +83,8 @@ class CopyProject(CommandLine):
|
|
|
83
83
|
|
|
84
84
|
if copied_targets is not None:
|
|
85
85
|
logger.info(f"コピー対象: {[e.value for e in copied_targets]}")
|
|
86
|
+
else:
|
|
87
|
+
logger.info("コピー対象: None")
|
|
86
88
|
|
|
87
89
|
confirm_message = f"プロジェクト'{src_project_title}'(project_id='{src_project_id}')を、プロジェクト'{dest_title}'(project_id='{dest_project_id}') にコピーしますか?"
|
|
88
90
|
if not self.confirm_processing(confirm_message):
|
|
@@ -111,7 +113,7 @@ class CopyProject(CommandLine):
|
|
|
111
113
|
max_job_access=DEFAULT_WAIT_OPTIONS.max_tries,
|
|
112
114
|
)
|
|
113
115
|
if result:
|
|
114
|
-
logger.info("
|
|
116
|
+
logger.info(f"プロジェクト'{src_project_title}'のコピーが完了しました。 :: dest_project_id='{dest_project_id}', dest_project_title='{dest_title}'")
|
|
115
117
|
else:
|
|
116
118
|
logger.info("プロジェクトのコピーは実行中 または 失敗しました。")
|
|
117
119
|
|
|
@@ -9,7 +9,7 @@ annofabcli/annotation/change_annotation_properties.py,sha256=Kp_LZ5sSoVmmjGE80AB
|
|
|
9
9
|
annofabcli/annotation/copy_annotation.py,sha256=Pih2k3vvpgfT3Ovb3gZw2L_8fK_ws_wKR7ARYG5hG_8,18407
|
|
10
10
|
annofabcli/annotation/delete_annotation.py,sha256=hQApNrx2Ci1bBWk0dRGA0oJkIgDHwl6Jy0-33gYF6jo,22989
|
|
11
11
|
annofabcli/annotation/download_annotation_zip.py,sha256=P_ZpdqIaSFEmB8jjpdykcRhh2tVlHxSlXFrYreJjShE,3282
|
|
12
|
-
annofabcli/annotation/dump_annotation.py,sha256=
|
|
12
|
+
annofabcli/annotation/dump_annotation.py,sha256=Q-p6f5XBs7khDgrfY5Q3CGLBMKEerJWO_CQ8_73UXVM,9972
|
|
13
13
|
annofabcli/annotation/import_annotation.py,sha256=39w-LwhNrT4-20NR5Hy-cn_cUFVVWVnMp9x1d8aITn0,33369
|
|
14
14
|
annofabcli/annotation/list_annotation.py,sha256=uKcOuGC7lzd6vVbzizkiZtYdXJ7EzY0iifuiqKl2wQM,10707
|
|
15
15
|
annofabcli/annotation/list_annotation_count.py,sha256=T9fbaoxWeDJIVgW_YgHRldbwrVZWiE-57lfJrDQrj80,6474
|
|
@@ -114,7 +114,7 @@ annofabcli/organization_member/subcommand_organization_member.py,sha256=iK-Y4PxG
|
|
|
114
114
|
annofabcli/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
115
115
|
annofabcli/project/change_organization_of_project.py,sha256=yeR8Xu4nmvrA4jGfsPDmFxf-qJxvEVQAvluierJRMxc,11300
|
|
116
116
|
annofabcli/project/change_project_status.py,sha256=AQQFFYjUnwrFshuYS_xSGyLAp2lJ-7SSIuaigPTLBYk,8657
|
|
117
|
-
annofabcli/project/copy_project.py,sha256=
|
|
117
|
+
annofabcli/project/copy_project.py,sha256=O1TooJ0VVbRP84d4Y-8e6Z7pKMwhBEwPu3EBv15hPlY,7131
|
|
118
118
|
annofabcli/project/diff_projects.py,sha256=OsR0otV6MOCbUgGEDsYganu5cuHYZbpHbBAqujwBAw8,16531
|
|
119
119
|
annofabcli/project/list_project.py,sha256=OWnbCyShI4ceugxML8kSAD2nkyld5MlpXfbvQu2__4Y,10367
|
|
120
120
|
annofabcli/project/put_project.py,sha256=dsRJfx2ga4mmYci40q91UzXeQN6m_3fMU9mrcFRpY9Q,6033
|
|
@@ -209,8 +209,8 @@ annofabcli/task_history_event/download_task_history_event_json.py,sha256=hQLVbQ0
|
|
|
209
209
|
annofabcli/task_history_event/list_all_task_history_event.py,sha256=EeKMyPUxGwYCFtWQHHW954ZserGm8lUqrwNnV1iX9X4,6830
|
|
210
210
|
annofabcli/task_history_event/list_worktime.py,sha256=Y7Pu5DP7scPf7HPt6CTiTvB1_5_Nfi1bStUIaCpkhII,15507
|
|
211
211
|
annofabcli/task_history_event/subcommand_task_history_event.py,sha256=mJVJoT4RXk4HWnY7-Nrsl4If-gtaIIEXd2z7eFZwM2I,1260
|
|
212
|
-
annofabcli-1.106.
|
|
213
|
-
annofabcli-1.106.
|
|
214
|
-
annofabcli-1.106.
|
|
215
|
-
annofabcli-1.106.
|
|
216
|
-
annofabcli-1.106.
|
|
212
|
+
annofabcli-1.106.1.dist-info/METADATA,sha256=Yn9OyrfluKXXvCiFDNavFc3UnA3wnd6i1gYTRI43V0M,5286
|
|
213
|
+
annofabcli-1.106.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
214
|
+
annofabcli-1.106.1.dist-info/entry_points.txt,sha256=C2uSUc-kkLJpoK_mDL5FEMAdorLEMPfwSf8VBMYnIFM,56
|
|
215
|
+
annofabcli-1.106.1.dist-info/licenses/LICENSE,sha256=pcqWYfxFtxBzhvKp3x9MXNM4xciGb2eFewaRhXUNHlo,1081
|
|
216
|
+
annofabcli-1.106.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|