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.
@@ -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): # noqa: ANN201
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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: annofabcli
3
- Version: 1.106.0
3
+ Version: 1.106.1
4
4
  Summary: Utility Command Line Interface for AnnoFab
5
5
  Author: Kurusugawa Computer Inc.
6
6
  License: MIT
@@ -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=CJ10zJUm9C1M1VhB_ZtdkWPncrZTx9h9JyxmLn7f3lo,8397
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=9UD2ElqodOyOwlvT-yqBVozA_9FivBWGLcEckG9B7m0,6972
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.0.dist-info/METADATA,sha256=FqGLzIdUm7grQhd5oMncx6H3AhyuoUC0Na385BczmS4,5286
213
- annofabcli-1.106.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
214
- annofabcli-1.106.0.dist-info/entry_points.txt,sha256=C2uSUc-kkLJpoK_mDL5FEMAdorLEMPfwSf8VBMYnIFM,56
215
- annofabcli-1.106.0.dist-info/licenses/LICENSE,sha256=pcqWYfxFtxBzhvKp3x9MXNM4xciGb2eFewaRhXUNHlo,1081
216
- annofabcli-1.106.0.dist-info/RECORD,,
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,,