annofabcli 1.113.0__py3-none-any.whl → 1.113.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.
@@ -68,7 +68,7 @@ class DumpAnnotationMain:
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: int | None = None, task_history_index: int | None = None) -> bool:
71
+ def dump_annotation_for_task(self, task_id: str, output_dir: Path, *, task_index: int | None = None, task_history_index: int | None = None, task_history_id: str | None = None) -> bool:
72
72
  """
73
73
  タスク配下のアノテーションをファイルに保存する。
74
74
 
@@ -85,23 +85,23 @@ class DumpAnnotationMain:
85
85
  logger.warning(f"task_id = '{task_id}' のタスクは存在しません。スキップします。")
86
86
  return False
87
87
 
88
- task_history_id: str | None = None
88
+ actual_task_history_id: str | None = task_history_id
89
89
  if task_history_index is not None:
90
90
  task_histories, _ = self.service.api.get_task_histories(self.project_id, task_id)
91
91
  if task_history_index >= len(task_histories):
92
92
  logger.warning(f"task_id='{task_id}' :: task_history_index='{task_history_index}'のタスク履歴は存在しません。タスク履歴は{len(task_histories)}件です。スキップします。")
93
93
  return False
94
- task_history_id = task_histories[task_history_index]["task_history_id"]
94
+ actual_task_history_id = task_histories[task_history_index]["task_history_id"]
95
95
 
96
96
  input_data_id_list = task["input_data_id_list"]
97
97
  task_dir = output_dir / task_id
98
98
  task_dir.mkdir(exist_ok=True, parents=True)
99
- logger.debug(f"{logger_prefix}task_id = '{task_id}' のアノテーション情報を '{task_dir}' ディレクトリに保存します。 :: task_history_id='{task_history_id}'")
99
+ logger.debug(f"{logger_prefix}task_id = '{task_id}' のアノテーション情報を '{task_dir}' ディレクトリに保存します。 :: task_history_id='{actual_task_history_id}'")
100
100
 
101
101
  is_failure = False
102
102
  for input_data_id in input_data_id_list:
103
103
  try:
104
- self.dump_annotation_for_input_data(task_id, input_data_id, task_dir=task_dir, task_history_id=task_history_id)
104
+ self.dump_annotation_for_input_data(task_id, input_data_id, task_dir=task_dir, task_history_id=actual_task_history_id)
105
105
  except Exception:
106
106
  logger.warning(f"タスク'{task_id}', 入力データ'{input_data_id}' のアノテーション情報のダンプに失敗しました。", exc_info=True)
107
107
  is_failure = True
@@ -109,15 +109,15 @@ class DumpAnnotationMain:
109
109
 
110
110
  return not is_failure
111
111
 
112
- def dump_annotation_for_task_wrapper(self, tpl: tuple[int, str], output_dir: Path, *, task_history_index: int | None = None) -> bool:
112
+ def dump_annotation_for_task_wrapper(self, tpl: tuple[int, str], output_dir: Path, *, task_history_index: int | None = None, task_history_id: str | None = None) -> bool:
113
113
  task_index, task_id = tpl
114
114
  try:
115
- return self.dump_annotation_for_task(task_id, output_dir=output_dir, task_index=task_index, task_history_index=task_history_index)
115
+ return self.dump_annotation_for_task(task_id, output_dir=output_dir, task_index=task_index, task_history_index=task_history_index, task_history_id=task_history_id)
116
116
  except Exception: # pylint: disable=broad-except
117
117
  logger.warning(f"タスク'{task_id}'のアノテーション情報のダンプに失敗しました。", exc_info=True)
118
118
  return False
119
119
 
120
- def dump_annotation(self, task_id_list: list[str], output_dir: Path, *, task_history_index: int | None = None, parallelism: int | None = None) -> None:
120
+ def dump_annotation(self, task_id_list: list[str], output_dir: Path, *, task_history_index: int | None = None, task_history_id: str | None = None, parallelism: int | None = None) -> None:
121
121
  project_title = self.facade.get_project_title(self.project_id)
122
122
  logger.info(f"プロジェクト'{project_title}'に対して、タスク{len(task_id_list)} 件のアノテーションをファイルに保存します。")
123
123
 
@@ -126,7 +126,7 @@ class DumpAnnotationMain:
126
126
  success_count = 0
127
127
 
128
128
  if parallelism is not None:
129
- func = functools.partial(self.dump_annotation_for_task_wrapper, task_history_index=task_history_index, output_dir=output_dir)
129
+ func = functools.partial(self.dump_annotation_for_task_wrapper, task_history_index=task_history_index, task_history_id=task_history_id, output_dir=output_dir)
130
130
  with multiprocessing.Pool(parallelism) as pool:
131
131
  result_bool_list = pool.map(func, enumerate(task_id_list))
132
132
  success_count = len([e for e in result_bool_list if e])
@@ -134,7 +134,7 @@ class DumpAnnotationMain:
134
134
  else:
135
135
  for task_index, task_id in enumerate(task_id_list):
136
136
  try:
137
- result = self.dump_annotation_for_task(task_id, output_dir=output_dir, task_history_index=task_history_index, task_index=task_index)
137
+ result = self.dump_annotation_for_task(task_id, output_dir=output_dir, task_history_index=task_history_index, task_history_id=task_history_id, task_index=task_index)
138
138
  if result:
139
139
  success_count += 1
140
140
  except Exception:
@@ -157,7 +157,7 @@ class DumpAnnotation(CommandLine):
157
157
  super().validate_project(project_id, project_member_roles=None)
158
158
 
159
159
  main_obj = DumpAnnotationMain(self.service, project_id)
160
- main_obj.dump_annotation(task_id_list, output_dir=output_dir, parallelism=args.parallelism, task_history_index=args.task_history_index)
160
+ main_obj.dump_annotation(task_id_list, output_dir=output_dir, parallelism=args.parallelism, task_history_index=args.task_history_index, task_history_id=args.task_history_id)
161
161
 
162
162
 
163
163
  def main(args: argparse.Namespace) -> None:
@@ -174,12 +174,19 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
174
174
 
175
175
  parser.add_argument("-o", "--output_dir", type=str, required=True, help="出力先ディレクトリのパス")
176
176
 
177
- parser.add_argument(
177
+ task_history_group = parser.add_mutually_exclusive_group()
178
+ task_history_group.add_argument(
178
179
  "--task_history_index",
179
180
  type=int,
180
181
  help="指定したタスク履歴のインデックス(ゼロ始まり)で付与されたアノテーション情報をダンプします。過去のアノテーション結果をダンプする場合に指定します。"
181
182
  "ただし、過去のアノテーションデータは30日間しか保持されません。30日より前に更新されたアノテーションをダンプした場合は、アノテーションが0件の状態でダンプされます。",
182
183
  )
184
+ task_history_group.add_argument(
185
+ "--task_history_id",
186
+ type=str,
187
+ help="指定したタスク履歴IDで付与されたアノテーション情報をダンプします。過去のアノテーション結果をダンプする場合に指定します。"
188
+ "ただし、過去のアノテーションデータは30日間しか保持されません。30日より前に更新されたアノテーションをダンプした場合は、アノテーションが0件の状態でダンプされます。",
189
+ )
183
190
 
184
191
  parser.add_argument(
185
192
  "--parallelism",
@@ -1,5 +1,6 @@
1
1
  import argparse
2
2
  import logging
3
+ import math
3
4
  import sys
4
5
  import tempfile
5
6
  from collections.abc import Collection
@@ -65,6 +66,9 @@ class Annotation3DBoundingBoxInfo(DataClassJsonMixin):
65
66
  top_z: float
66
67
  """天面のZ座標(location.z + height/2)。回転は考慮していない。"""
67
68
 
69
+ horizontal_distance: float
70
+ """原点(0, 0)からのXY平面上の距離(sqrt(location.x² + location.y²))"""
71
+
68
72
  attributes: dict[str, str | int | bool]
69
73
  """属性情報"""
70
74
 
@@ -96,6 +100,7 @@ def get_annotation_3d_bounding_box_info_list(simple_annotation: dict[str, Any],
96
100
  footprint_area = width * depth
97
101
  bottom_z = location.z - height / 2
98
102
  top_z = location.z + height / 2
103
+ horizontal_distance = math.hypot(location.x, location.y)
99
104
 
100
105
  result.append(
101
106
  Annotation3DBoundingBoxInfo(
@@ -116,6 +121,7 @@ def get_annotation_3d_bounding_box_info_list(simple_annotation: dict[str, Any],
116
121
  footprint_area=footprint_area,
117
122
  bottom_z=bottom_z,
118
123
  top_z=top_z,
124
+ horizontal_distance=horizontal_distance,
119
125
  attributes=detail["attributes"],
120
126
  updated_datetime=simple_annotation["updated_datetime"],
121
127
  )
@@ -177,6 +183,7 @@ def create_df(
177
183
  "footprint_area",
178
184
  "bottom_z",
179
185
  "top_z",
186
+ "horizontal_distance",
180
187
  ]
181
188
 
182
189
  if len(tmp_annotation_bbox_list) == 0:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: annofabcli
3
- Version: 1.113.0
3
+ Version: 1.113.1
4
4
  Summary: Utility Command Line Interface for AnnoFab
5
5
  Author: Kurusugawa Computer Inc.
6
6
  License: MIT
@@ -10,7 +10,7 @@ annofabcli/annotation/copy_annotation.py,sha256=8ayliCb3XCsswEW_E_blmSR1aLt00Swf
10
10
  annofabcli/annotation/create_classification_annotation.py,sha256=OVMFyL-CrZH444V1EkaTt068cEG834LIfdMDAspn3PA,18577
11
11
  annofabcli/annotation/delete_annotation.py,sha256=NCA8e9FQsqaCVcQmteRQcLoNrzAcoRdpFoiWjZhswSY,25124
12
12
  annofabcli/annotation/download_annotation_zip.py,sha256=o2p2TfK8-jz15TWrkWxhX9eAnoATHjxkTy44q-BbI14,3265
13
- annofabcli/annotation/dump_annotation.py,sha256=60oxLofG9nXh6813HxN9JjAFbEiCaAgb55KU92j_khE,9949
13
+ annofabcli/annotation/dump_annotation.py,sha256=AWEAR4Q38Oo9yA6plo51F7_ZSxwfuaxQeFDZ66gsiIA,10844
14
14
  annofabcli/annotation/import_annotation.py,sha256=cbTLD2BZjZ2xCDvRriCHkVz2Twdnbm0r2igtLHw9tMI,35849
15
15
  annofabcli/annotation/list_annotation.py,sha256=ymxek1dTntctXaoe6KmcKwzdcRmAZllM81lnsK2J7U8,10687
16
16
  annofabcli/annotation/list_annotation_count.py,sha256=4WjvwyB8rXS9gxtRI-kDbezDEBjptybEl7k_lbRiGWk,6454
@@ -35,7 +35,7 @@ annofabcli/annotation_specs/list_label_color.py,sha256=bWiuNvqHuw6-Jh_q43-Y-46sr
35
35
  annofabcli/annotation_specs/put_label_color.py,sha256=3op1Kck5TBn-ORIDmQOGgZGmfm_c4nmRuJy4g0vkEGQ,5956
36
36
  annofabcli/annotation_specs/subcommand_annotation_specs.py,sha256=jOPgWLEmb721kxknmzlXLIFuvWwlaX17PJATfQDH5lo,2643
37
37
  annofabcli/annotation_zip/__init__.py,sha256=wAeKgkUYvgzdGFS3iJ3h0WogWbg9i-0c4xSg-mzbBpY,64
38
- annofabcli/annotation_zip/list_annotation_3d_bounding_box.py,sha256=VbUL-h8VUEaitLQE966wG2El9xa_debaHU-Z1tlcHP4,14450
38
+ annofabcli/annotation_zip/list_annotation_3d_bounding_box.py,sha256=UtPA1WQ348_3CasK6BhVsYuYPo2J94idMpq2qapeKvA,14738
39
39
  annofabcli/annotation_zip/list_annotation_bounding_box_2d.py,sha256=05Et3MOTRShY-h9TLWD4LtMGTaw_2Sd2AFcL5wddOAI,13435
40
40
  annofabcli/annotation_zip/list_polygon_annotation.py,sha256=SZ00hSaDpDm9dfY8kayLtgibBRT0ocrYCBY3OQIeTqc,15580
41
41
  annofabcli/annotation_zip/list_polyline_annotation.py,sha256=0xTXr5jdOGnKhb_afGj40u3e4QEyX3tVFdRqViBj4-k,15835
@@ -224,8 +224,8 @@ annofabcli/task_history_event/download_task_history_event_json.py,sha256=lWyOoS2
224
224
  annofabcli/task_history_event/list_all_task_history_event.py,sha256=M8FEeZpgIb1QK01feZRHPvAAoR6K3Ztif7GICGjZoV0,6813
225
225
  annofabcli/task_history_event/list_worktime.py,sha256=k6Hgy0pE2w5BtyUePN-LAyTbw0W2RMU4retwa6rC2uU,15497
226
226
  annofabcli/task_history_event/subcommand_task_history_event.py,sha256=dFllzpm8plnnwADwTV74h-R2LOA7rZW-xd2YnSkwTHo,1229
227
- annofabcli-1.113.0.dist-info/METADATA,sha256=_lKgu_x8NnCzOdPmMGBuDqD6azydU-3-g9FP4Vd8peA,4949
228
- annofabcli-1.113.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
229
- annofabcli-1.113.0.dist-info/entry_points.txt,sha256=C2uSUc-kkLJpoK_mDL5FEMAdorLEMPfwSf8VBMYnIFM,56
230
- annofabcli-1.113.0.dist-info/licenses/LICENSE,sha256=pcqWYfxFtxBzhvKp3x9MXNM4xciGb2eFewaRhXUNHlo,1081
231
- annofabcli-1.113.0.dist-info/RECORD,,
227
+ annofabcli-1.113.1.dist-info/METADATA,sha256=Hv4z7jgkKuMPnAHF4jp-ecpL63KheapP0LR8_Gt-r0g,4949
228
+ annofabcli-1.113.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
229
+ annofabcli-1.113.1.dist-info/entry_points.txt,sha256=C2uSUc-kkLJpoK_mDL5FEMAdorLEMPfwSf8VBMYnIFM,56
230
+ annofabcli-1.113.1.dist-info/licenses/LICENSE,sha256=pcqWYfxFtxBzhvKp3x9MXNM4xciGb2eFewaRhXUNHlo,1081
231
+ annofabcli-1.113.1.dist-info/RECORD,,