annofabcli 1.111.2__py3-none-any.whl → 1.113.0__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/__main__.py +1 -2
- annofabcli/annotation/annotation_query.py +10 -10
- annofabcli/annotation/change_annotation_attributes.py +10 -10
- annofabcli/annotation/change_annotation_attributes_per_annotation.py +4 -5
- annofabcli/annotation/change_annotation_properties.py +14 -14
- annofabcli/annotation/copy_annotation.py +6 -6
- annofabcli/annotation/create_classification_annotation.py +7 -7
- annofabcli/annotation/delete_annotation.py +9 -9
- annofabcli/annotation/download_annotation_zip.py +1 -3
- annofabcli/annotation/dump_annotation.py +8 -8
- annofabcli/annotation/import_annotation.py +13 -13
- annofabcli/annotation/list_annotation.py +9 -9
- annofabcli/annotation/list_annotation_count.py +2 -3
- annofabcli/annotation/merge_segmentation.py +6 -6
- annofabcli/annotation/remove_segmentation_overlap.py +5 -5
- annofabcli/annotation/restore_annotation.py +7 -7
- annofabcli/annotation/subcommand_annotation.py +1 -2
- annofabcli/annotation_specs/add_attribute_restriction.py +4 -5
- annofabcli/annotation_specs/attribute_restriction.py +8 -8
- annofabcli/annotation_specs/export_annotation_specs.py +4 -5
- annofabcli/annotation_specs/get_annotation_specs_with_attribute_id_replaced.py +3 -4
- annofabcli/annotation_specs/get_annotation_specs_with_choice_id_replaced.py +3 -4
- annofabcli/annotation_specs/get_annotation_specs_with_label_id_replaced.py +3 -4
- annofabcli/annotation_specs/list_annotation_specs_attribute.py +9 -10
- annofabcli/annotation_specs/list_annotation_specs_choice.py +9 -10
- annofabcli/annotation_specs/list_annotation_specs_history.py +3 -3
- annofabcli/annotation_specs/list_annotation_specs_label.py +8 -9
- annofabcli/annotation_specs/list_annotation_specs_label_attribute.py +10 -11
- annofabcli/annotation_specs/list_attribute_restriction.py +2 -4
- annofabcli/annotation_specs/list_label_color.py +2 -3
- annofabcli/annotation_specs/put_label_color.py +3 -4
- annofabcli/annotation_specs/subcommand_annotation_specs.py +1 -3
- annofabcli/annotation_zip/list_annotation_3d_bounding_box.py +365 -0
- annofabcli/annotation_zip/list_annotation_bounding_box_2d.py +37 -38
- annofabcli/annotation_zip/list_polygon_annotation.py +390 -0
- annofabcli/annotation_zip/list_polyline_annotation.py +402 -0
- annofabcli/annotation_zip/list_range_annotation.py +25 -15
- annofabcli/annotation_zip/list_single_point_annotation.py +25 -34
- annofabcli/annotation_zip/subcommand_annotation_zip.py +7 -2
- annofabcli/annotation_zip/validate_annotation.py +8 -7
- annofabcli/comment/delete_comment.py +4 -6
- annofabcli/comment/download_comment_json.py +4 -6
- annofabcli/comment/list_all_comment.py +5 -6
- annofabcli/comment/list_comment.py +3 -4
- annofabcli/comment/put_comment.py +9 -10
- annofabcli/comment/put_comment_simply.py +5 -6
- annofabcli/comment/put_inspection_comment.py +1 -3
- annofabcli/comment/put_inspection_comment_simply.py +1 -3
- annofabcli/comment/put_onhold_comment.py +1 -3
- annofabcli/comment/put_onhold_comment_simply.py +1 -3
- annofabcli/comment/subcommand_comment.py +1 -3
- annofabcli/common/bokeh.py +4 -4
- annofabcli/common/cli.py +18 -17
- annofabcli/common/download.py +28 -29
- annofabcli/common/facade.py +37 -38
- annofabcli/common/image.py +14 -14
- annofabcli/common/utils.py +8 -8
- annofabcli/common/visualize.py +13 -13
- annofabcli/experimental/list_out_of_range_annotation_for_movie.py +3 -4
- annofabcli/experimental/subcommand_experimental.py +1 -3
- annofabcli/filesystem/draw_annotation.py +27 -27
- annofabcli/filesystem/filter_annotation.py +9 -10
- annofabcli/filesystem/mask_user_info.py +15 -15
- annofabcli/filesystem/merge_annotation.py +9 -9
- annofabcli/filesystem/subcommand_filesystem.py +1 -3
- annofabcli/input_data/copy_input_data.py +8 -9
- annofabcli/input_data/delete_input_data.py +3 -3
- annofabcli/input_data/delete_metadata_key_of_input_data.py +3 -5
- annofabcli/input_data/download_input_data_json.py +4 -6
- annofabcli/input_data/list_all_input_data.py +9 -9
- annofabcli/input_data/list_all_input_data_merged_task.py +5 -5
- annofabcli/input_data/list_input_data.py +5 -5
- annofabcli/input_data/put_input_data.py +6 -6
- annofabcli/input_data/put_input_data_with_zip.py +3 -4
- annofabcli/input_data/subcommand_input_data.py +1 -3
- annofabcli/input_data/update_input_data.py +6 -8
- annofabcli/input_data/update_metadata_of_input_data.py +3 -5
- annofabcli/instruction/copy_instruction.py +5 -6
- annofabcli/instruction/download_instruction.py +5 -6
- annofabcli/instruction/list_instruction_history.py +3 -3
- annofabcli/instruction/subcommand_instruction.py +1 -3
- annofabcli/instruction/upload_instruction.py +3 -4
- annofabcli/job/delete_job.py +2 -3
- annofabcli/job/list_job.py +5 -5
- annofabcli/job/list_last_job.py +4 -4
- annofabcli/job/subcommand_job.py +1 -3
- annofabcli/job/wait_job.py +4 -5
- annofabcli/my_account/get_my_account.py +2 -3
- annofabcli/my_account/subcommand_my_account.py +1 -3
- annofabcli/organization/list_organization.py +2 -3
- annofabcli/organization/subcommand_organization.py +1 -3
- annofabcli/organization_member/change_organization_member.py +3 -4
- annofabcli/organization_member/delete_organization_member.py +3 -4
- annofabcli/organization_member/invite_organization_member.py +1 -3
- annofabcli/organization_member/list_organization_member.py +3 -3
- annofabcli/organization_member/subcommand_organization_member.py +1 -3
- annofabcli/project/change_organization_of_project.py +4 -4
- annofabcli/project/change_project_status.py +4 -4
- annofabcli/project/copy_project.py +5 -5
- annofabcli/project/create_project.py +8 -8
- annofabcli/project/diff_projects.py +4 -5
- annofabcli/project/list_project.py +5 -5
- annofabcli/project/put_project.py +2 -3
- annofabcli/project/subcommand_project.py +1 -2
- annofabcli/project/update_configuration.py +4 -4
- annofabcli/project/update_project.py +6 -8
- annofabcli/project_member/change_project_members.py +8 -8
- annofabcli/project_member/copy_project_members.py +4 -4
- annofabcli/project_member/drop_project_members.py +2 -3
- annofabcli/project_member/invite_project_members.py +1 -3
- annofabcli/project_member/list_users.py +2 -3
- annofabcli/project_member/put_project_members.py +6 -6
- annofabcli/project_member/subcommand_project_member.py +1 -3
- annofabcli/stat_visualization/mask_visualization_dir.py +8 -9
- annofabcli/stat_visualization/merge_visualization_dir.py +6 -7
- annofabcli/stat_visualization/subcommand_stat_visualization.py +1 -2
- annofabcli/stat_visualization/summarize_whole_performance_csv.py +1 -2
- annofabcli/stat_visualization/write_graph.py +2 -3
- annofabcli/stat_visualization/write_performance_rating_csv.py +20 -27
- annofabcli/statistics/histogram.py +5 -6
- annofabcli/statistics/linegraph.py +13 -14
- annofabcli/statistics/list_annotation_area.py +38 -13
- annofabcli/statistics/list_annotation_attribute.py +9 -10
- annofabcli/statistics/list_annotation_attribute_filled_count.py +30 -31
- annofabcli/statistics/list_annotation_count.py +57 -58
- annofabcli/statistics/list_annotation_duration.py +33 -34
- annofabcli/statistics/list_video_duration.py +4 -5
- annofabcli/statistics/list_worktime.py +4 -4
- annofabcli/statistics/scatter.py +9 -8
- annofabcli/statistics/subcommand_statistics.py +1 -4
- annofabcli/statistics/summarize_task_count.py +4 -6
- annofabcli/statistics/summarize_task_count_by_task_id_group.py +2 -4
- annofabcli/statistics/summarize_task_count_by_user.py +1 -3
- annofabcli/statistics/visualization/dataframe/annotation_count.py +5 -4
- annofabcli/statistics/visualization/dataframe/annotation_duration.py +2 -3
- annofabcli/statistics/visualization/dataframe/cumulative_productivity.py +15 -17
- annofabcli/statistics/visualization/dataframe/productivity_per_date.py +17 -19
- annofabcli/statistics/visualization/dataframe/project_performance.py +3 -12
- annofabcli/statistics/visualization/dataframe/task.py +11 -12
- annofabcli/statistics/visualization/dataframe/task_worktime_by_phase_user.py +9 -10
- annofabcli/statistics/visualization/dataframe/user_performance.py +21 -19
- annofabcli/statistics/visualization/dataframe/whole_performance.py +3 -4
- annofabcli/statistics/visualization/dataframe/whole_productivity_per_date.py +12 -14
- annofabcli/statistics/visualization/dataframe/worktime_per_date.py +11 -13
- annofabcli/statistics/visualization/filtering_query.py +7 -7
- annofabcli/statistics/visualization/project_dir.py +27 -14
- annofabcli/statistics/visualize_annotation_count.py +22 -23
- annofabcli/statistics/visualize_annotation_duration.py +21 -22
- annofabcli/statistics/visualize_statistics.py +36 -33
- annofabcli/statistics/visualize_video_duration.py +18 -20
- annofabcli/supplementary/delete_supplementary_data.py +5 -5
- annofabcli/supplementary/list_supplementary_data.py +4 -4
- annofabcli/supplementary/put_supplementary_data.py +9 -9
- annofabcli/supplementary/subcommand_supplementary.py +1 -3
- annofabcli/task/cancel_acceptance.py +16 -17
- annofabcli/task/change_operator.py +10 -12
- annofabcli/task/change_status_to_break.py +7 -9
- annofabcli/task/change_status_to_on_hold.py +10 -12
- annofabcli/task/complete_tasks.py +17 -18
- annofabcli/task/copy_tasks.py +3 -5
- annofabcli/task/delete_metadata_key_of_task.py +4 -6
- annofabcli/task/delete_tasks.py +7 -7
- annofabcli/task/download_task_json.py +4 -6
- annofabcli/task/list_all_tasks.py +8 -8
- annofabcli/task/list_all_tasks_added_task_history.py +14 -13
- annofabcli/task/list_tasks.py +7 -7
- annofabcli/task/list_tasks_added_task_history.py +10 -10
- annofabcli/task/put_tasks.py +5 -6
- annofabcli/task/put_tasks_by_count.py +2 -3
- annofabcli/task/reject_tasks.py +18 -20
- annofabcli/task/subcommand_task.py +1 -3
- annofabcli/task/update_metadata_of_task.py +5 -6
- annofabcli/task_history/download_task_history_json.py +4 -6
- annofabcli/task_history/list_all_task_history.py +6 -7
- annofabcli/task_history/list_task_history.py +4 -5
- annofabcli/task_history/subcommand_task_history.py +1 -3
- annofabcli/task_history_event/download_task_history_event_json.py +4 -6
- annofabcli/task_history_event/list_all_task_history_event.py +7 -7
- annofabcli/task_history_event/list_worktime.py +17 -16
- annofabcli/task_history_event/subcommand_task_history_event.py +1 -2
- {annofabcli-1.111.2.dist-info → annofabcli-1.113.0.dist-info}/METADATA +9 -15
- annofabcli-1.113.0.dist-info/RECORD +231 -0
- {annofabcli-1.111.2.dist-info → annofabcli-1.113.0.dist-info}/WHEEL +1 -1
- annofabcli-1.111.2.dist-info/RECORD +0 -228
- {annofabcli-1.111.2.dist-info → annofabcli-1.113.0.dist-info}/entry_points.txt +0 -0
- {annofabcli-1.111.2.dist-info → annofabcli-1.113.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -4,13 +4,12 @@ import json
|
|
|
4
4
|
import logging
|
|
5
5
|
import zipfile
|
|
6
6
|
from pathlib import Path
|
|
7
|
-
from typing import Any
|
|
7
|
+
from typing import Any
|
|
8
8
|
|
|
9
9
|
import annofabapi
|
|
10
10
|
import pandas
|
|
11
11
|
from annofabapi.parser import SimpleAnnotationZipParser
|
|
12
12
|
|
|
13
|
-
import annofabcli
|
|
14
13
|
import annofabcli.common.cli
|
|
15
14
|
from annofabcli.common.cli import ArgumentParser, CommandLine, build_annofabapi_resource_and_login
|
|
16
15
|
from annofabcli.common.download import DownloadingFile
|
|
@@ -59,7 +58,7 @@ class ListOutOfRangeAnnotationForMovieMain:
|
|
|
59
58
|
project_id: str,
|
|
60
59
|
task_list: list[dict[str, Any]],
|
|
61
60
|
input_data_list: list[dict[str, Any]],
|
|
62
|
-
annotation_zip:
|
|
61
|
+
annotation_zip: Path | None,
|
|
63
62
|
) -> pandas.DataFrame:
|
|
64
63
|
if annotation_zip is None:
|
|
65
64
|
logger.info(f"{len(task_list)} 件のアノテーション情報をWebAPIで取得します。")
|
|
@@ -123,7 +122,7 @@ class ListOutOfRangeAnnotationForMovieMain:
|
|
|
123
122
|
def list_out_of_range_annotation_for_movie(
|
|
124
123
|
self,
|
|
125
124
|
project_id: str,
|
|
126
|
-
task_id_list:
|
|
125
|
+
task_id_list: list[str] | None,
|
|
127
126
|
parse_annotation_zip: bool = False, # noqa: FBT001, FBT002
|
|
128
127
|
) -> pandas.DataFrame:
|
|
129
128
|
cache_dir = annofabcli.common.utils.get_cache_dir()
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import argparse
|
|
2
|
-
from typing import Optional
|
|
3
2
|
|
|
4
|
-
import annofabcli
|
|
5
3
|
import annofabcli.common.cli
|
|
6
4
|
from annofabcli.experimental import list_out_of_range_annotation_for_movie
|
|
7
5
|
|
|
@@ -13,7 +11,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
13
11
|
list_out_of_range_annotation_for_movie.add_parser(subparsers)
|
|
14
12
|
|
|
15
13
|
|
|
16
|
-
def add_parser(subparsers:
|
|
14
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
17
15
|
subcommand_name = "experimental"
|
|
18
16
|
subcommand_help = "アルファ版のサブコマンド"
|
|
19
17
|
description = "アルファ版のサブコマンド。予告なしに削除されたり、コマンドライン引数が変わったりします。"
|
|
@@ -4,17 +4,17 @@ import argparse
|
|
|
4
4
|
import json
|
|
5
5
|
import logging
|
|
6
6
|
import sys
|
|
7
|
-
from collections.abc import Collection, Iterator
|
|
7
|
+
from collections.abc import Callable, Collection, Iterator
|
|
8
8
|
from dataclasses import dataclass
|
|
9
9
|
from pathlib import Path
|
|
10
|
-
from typing import Any
|
|
10
|
+
from typing import Any
|
|
11
11
|
|
|
12
12
|
import pandas
|
|
13
13
|
from annofabapi.parser import SimpleAnnotationParser, lazy_parse_simple_annotation_dir, lazy_parse_simple_annotation_zip
|
|
14
14
|
from dataclasses_json import DataClassJsonMixin
|
|
15
15
|
from PIL import Image, ImageColor, ImageDraw
|
|
16
16
|
|
|
17
|
-
import annofabcli
|
|
17
|
+
import annofabcli.common.cli
|
|
18
18
|
from annofabcli.common.cli import (
|
|
19
19
|
COMMAND_LINE_ERROR_STATUS_CODE,
|
|
20
20
|
ArgumentParser,
|
|
@@ -27,7 +27,7 @@ from annofabcli.common.facade import TaskQuery, match_annotation_with_task_query
|
|
|
27
27
|
logger = logging.getLogger(__name__)
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
Color =
|
|
30
|
+
Color = str | tuple[int, int, int]
|
|
31
31
|
IsParserFunc = Callable[[SimpleAnnotationParser], bool]
|
|
32
32
|
|
|
33
33
|
|
|
@@ -59,10 +59,10 @@ class DrawingAnnotationForOneImage:
|
|
|
59
59
|
|
|
60
60
|
def __init__(
|
|
61
61
|
self,
|
|
62
|
-
label_color_dict:
|
|
63
|
-
target_label_names:
|
|
64
|
-
polyline_labels:
|
|
65
|
-
drawing_options:
|
|
62
|
+
label_color_dict: dict[str, Color] | None = None,
|
|
63
|
+
target_label_names: Collection[str] | None = None,
|
|
64
|
+
polyline_labels: Collection[str] | None = None,
|
|
65
|
+
drawing_options: DrawingOptions | None = None,
|
|
66
66
|
) -> None:
|
|
67
67
|
self.label_color_dict = label_color_dict if label_color_dict is not None else {}
|
|
68
68
|
self.target_label_names = set(target_label_names) if target_label_names is not None else None
|
|
@@ -161,9 +161,9 @@ class DrawingAnnotationForOneImage:
|
|
|
161
161
|
def main( # noqa: ANN201
|
|
162
162
|
self,
|
|
163
163
|
parser: SimpleAnnotationParser,
|
|
164
|
-
image_file:
|
|
164
|
+
image_file: Path | None,
|
|
165
165
|
output_file: Path,
|
|
166
|
-
image_size:
|
|
166
|
+
image_size: tuple[int, int] | None = None,
|
|
167
167
|
):
|
|
168
168
|
"""画像にアノテーションを描画したファイルを出力する。
|
|
169
169
|
|
|
@@ -190,9 +190,9 @@ class DrawingAnnotationForOneImage:
|
|
|
190
190
|
|
|
191
191
|
|
|
192
192
|
def create_is_target_parser_func(
|
|
193
|
-
task_ids:
|
|
194
|
-
task_query:
|
|
195
|
-
) ->
|
|
193
|
+
task_ids: Collection[str] | None = None,
|
|
194
|
+
task_query: TaskQuery | None = None,
|
|
195
|
+
) -> IsParserFunc | None:
|
|
196
196
|
if task_ids is None and task_query is None:
|
|
197
197
|
return None
|
|
198
198
|
|
|
@@ -215,17 +215,17 @@ def create_is_target_parser_func(
|
|
|
215
215
|
|
|
216
216
|
def draw_annotation_all( # noqa: ANN201, PLR0913
|
|
217
217
|
iter_parser: Iterator[SimpleAnnotationParser],
|
|
218
|
-
image_dir:
|
|
219
|
-
input_data_id_relation_dict:
|
|
218
|
+
image_dir: Path | None,
|
|
219
|
+
input_data_id_relation_dict: dict[str, str] | None,
|
|
220
220
|
output_dir: Path,
|
|
221
221
|
*,
|
|
222
|
-
target_task_ids:
|
|
223
|
-
task_query:
|
|
224
|
-
label_color_dict:
|
|
225
|
-
target_label_names:
|
|
226
|
-
polyline_labels:
|
|
227
|
-
drawing_options:
|
|
228
|
-
default_image_size:
|
|
222
|
+
target_task_ids: Collection[str] | None = None,
|
|
223
|
+
task_query: TaskQuery | None = None,
|
|
224
|
+
label_color_dict: dict[str, Color] | None = None,
|
|
225
|
+
target_label_names: Collection[str] | None = None,
|
|
226
|
+
polyline_labels: Collection[str] | None = None,
|
|
227
|
+
drawing_options: DrawingOptions | None = None,
|
|
228
|
+
default_image_size: tuple[int, int] | None = None,
|
|
229
229
|
):
|
|
230
230
|
drawing = DrawingAnnotationForOneImage(
|
|
231
231
|
label_color_dict=label_color_dict,
|
|
@@ -251,7 +251,7 @@ def draw_annotation_all( # noqa: ANN201, PLR0913
|
|
|
251
251
|
logger.warning(f"input_data_id='{input_data_id}'に対応する画像ファイルのパスが見つかりませんでした。")
|
|
252
252
|
continue
|
|
253
253
|
|
|
254
|
-
image_file:
|
|
254
|
+
image_file: Path | None = None
|
|
255
255
|
if image_dir is not None and input_data_id_relation_dict is not None:
|
|
256
256
|
image_file = image_dir / input_data_id_relation_dict[input_data_id]
|
|
257
257
|
if not image_file.exists():
|
|
@@ -291,7 +291,7 @@ class DrawAnnotation(CommandLineWithoutWebapi):
|
|
|
291
291
|
def main(self) -> None:
|
|
292
292
|
args = self.args
|
|
293
293
|
|
|
294
|
-
default_image_size:
|
|
294
|
+
default_image_size: tuple[int, int] | None = None
|
|
295
295
|
if args.default_image_size is not None:
|
|
296
296
|
default_image_size = annofabcli.common.cli.get_input_data_size(args.default_image_size)
|
|
297
297
|
if default_image_size is None:
|
|
@@ -322,7 +322,7 @@ class DrawAnnotation(CommandLineWithoutWebapi):
|
|
|
322
322
|
else:
|
|
323
323
|
iter_parser = lazy_parse_simple_annotation_dir(annotation_path)
|
|
324
324
|
|
|
325
|
-
input_data_id_relation_dict:
|
|
325
|
+
input_data_id_relation_dict: dict[str, str] | None = None
|
|
326
326
|
if args.input_data_id_csv is not None:
|
|
327
327
|
df = pandas.read_csv(
|
|
328
328
|
args.input_data_id_csv,
|
|
@@ -330,7 +330,7 @@ class DrawAnnotation(CommandLineWithoutWebapi):
|
|
|
330
330
|
header=None,
|
|
331
331
|
names=("input_data_id", "image_path"),
|
|
332
332
|
)
|
|
333
|
-
input_data_id_relation_dict = dict(zip(df["input_data_id"], df["image_path"]))
|
|
333
|
+
input_data_id_relation_dict = dict(zip(df["input_data_id"], df["image_path"], strict=False))
|
|
334
334
|
|
|
335
335
|
task_query = TaskQuery.from_dict(annofabcli.common.cli.get_json_from_args(args.task_query)) if args.task_query is not None else None
|
|
336
336
|
|
|
@@ -439,7 +439,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
439
439
|
parser.set_defaults(subcommand_func=main)
|
|
440
440
|
|
|
441
441
|
|
|
442
|
-
def add_parser(subparsers:
|
|
442
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
443
443
|
subcommand_name = "draw_annotation"
|
|
444
444
|
|
|
445
445
|
subcommand_help = "画像にアノテーションを描画します。"
|
|
@@ -7,11 +7,10 @@ import zipfile
|
|
|
7
7
|
from collections import defaultdict
|
|
8
8
|
from dataclasses import dataclass
|
|
9
9
|
from pathlib import Path
|
|
10
|
-
from typing import Any
|
|
10
|
+
from typing import Any
|
|
11
11
|
|
|
12
12
|
from annofabapi.parser import lazy_parse_simple_annotation_dir, lazy_parse_simple_annotation_zip
|
|
13
13
|
|
|
14
|
-
import annofabcli
|
|
15
14
|
import annofabcli.common.cli
|
|
16
15
|
from annofabcli.common.cli import COMMAND_LINE_ERROR_STATUS_CODE
|
|
17
16
|
from annofabcli.common.facade import TaskQuery, match_annotation_with_task_query
|
|
@@ -21,13 +20,13 @@ logger = logging.getLogger(__name__)
|
|
|
21
20
|
|
|
22
21
|
@dataclass
|
|
23
22
|
class FilterQuery:
|
|
24
|
-
task_query:
|
|
25
|
-
task_id_set:
|
|
26
|
-
exclude_task_id_set:
|
|
27
|
-
input_data_id_set:
|
|
28
|
-
exclude_input_data_id_set:
|
|
29
|
-
input_data_name_set:
|
|
30
|
-
exclude_input_data_name_set:
|
|
23
|
+
task_query: TaskQuery | None = None
|
|
24
|
+
task_id_set: set[str] | None = None
|
|
25
|
+
exclude_task_id_set: set[str] | None = None
|
|
26
|
+
input_data_id_set: set[str] | None = None
|
|
27
|
+
exclude_input_data_id_set: set[str] | None = None
|
|
28
|
+
input_data_name_set: set[str] | None = None
|
|
29
|
+
exclude_input_data_name_set: set[str] | None = None
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
def match_query( # pylint: disable=too-many-return-statements # noqa: PLR0911
|
|
@@ -220,7 +219,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
220
219
|
parser.set_defaults(subcommand_func=main)
|
|
221
220
|
|
|
222
221
|
|
|
223
|
-
def add_parser(subparsers:
|
|
222
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
224
223
|
subcommand_name = "filter_annotation"
|
|
225
224
|
|
|
226
225
|
subcommand_help = "アノテーションzipから特定のファイルを絞り込んで、zip展開します。"
|
|
@@ -2,12 +2,12 @@ import argparse
|
|
|
2
2
|
import logging
|
|
3
3
|
from functools import partial
|
|
4
4
|
from pathlib import Path
|
|
5
|
-
from typing import Any
|
|
5
|
+
from typing import Any
|
|
6
6
|
|
|
7
7
|
import numpy
|
|
8
8
|
import pandas
|
|
9
9
|
|
|
10
|
-
import annofabcli
|
|
10
|
+
import annofabcli.common.cli
|
|
11
11
|
from annofabcli.common.cli import ArgumentParser, CommandLineWithoutWebapi, get_list_from_args
|
|
12
12
|
from annofabcli.common.utils import read_multiheader_csv
|
|
13
13
|
|
|
@@ -98,7 +98,7 @@ def create_masked_name(name: str) -> str:
|
|
|
98
98
|
return _num2alpha(hash_value)
|
|
99
99
|
|
|
100
100
|
|
|
101
|
-
def get_replaced_user_id_set_from_biography(df: pandas.DataFrame, not_masked_location_set:
|
|
101
|
+
def get_replaced_user_id_set_from_biography(df: pandas.DataFrame, not_masked_location_set: set[str] | None = None) -> set[str]:
|
|
102
102
|
if not_masked_location_set is None:
|
|
103
103
|
filtered_df = df
|
|
104
104
|
else:
|
|
@@ -115,7 +115,7 @@ def _get_header_row_count(df: pandas.DataFrame) -> int:
|
|
|
115
115
|
return 1
|
|
116
116
|
|
|
117
117
|
|
|
118
|
-
def _get_tuple_column(df: pandas.DataFrame, column: str) ->
|
|
118
|
+
def _get_tuple_column(df: pandas.DataFrame, column: str) -> str | tuple:
|
|
119
119
|
"""
|
|
120
120
|
列名を返します。ヘッダ行が複数行の場合は、タプルで返します。
|
|
121
121
|
|
|
@@ -136,8 +136,8 @@ def _get_tuple_column(df: pandas.DataFrame, column: str) -> Union[str, tuple]:
|
|
|
136
136
|
def replace_by_columns( # noqa: ANN201
|
|
137
137
|
df: pandas.DataFrame,
|
|
138
138
|
replacement_dict: dict[str, str],
|
|
139
|
-
main_column:
|
|
140
|
-
sub_columns:
|
|
139
|
+
main_column: str | tuple,
|
|
140
|
+
sub_columns: list[Any] | None = None,
|
|
141
141
|
):
|
|
142
142
|
"""引数dfの中のユーザ情報を、指定した列名を元に置換します。
|
|
143
143
|
|
|
@@ -148,7 +148,7 @@ def replace_by_columns( # noqa: ANN201
|
|
|
148
148
|
sub_column: main_columnと同じ値で置換する列(ex: username)
|
|
149
149
|
"""
|
|
150
150
|
|
|
151
|
-
def _get_username(row: pandas.Series, main_column:
|
|
151
|
+
def _get_username(row: pandas.Series, main_column: str | tuple, sub_column: str | tuple) -> str:
|
|
152
152
|
if row[main_column] in replacement_dict:
|
|
153
153
|
return replacement_dict[row[main_column]]
|
|
154
154
|
else:
|
|
@@ -196,7 +196,7 @@ def get_masked_account_id(df: pandas.DataFrame, replace_dict_by_user_id: dict[st
|
|
|
196
196
|
return df.apply(_get_account_id, axis=1)
|
|
197
197
|
|
|
198
198
|
|
|
199
|
-
def get_replaced_biography_set(df: pandas.DataFrame, not_masked_location_set:
|
|
199
|
+
def get_replaced_biography_set(df: pandas.DataFrame, not_masked_location_set: set[str] | None = None) -> set[str]:
|
|
200
200
|
biography_set = set(df["biography"].dropna())
|
|
201
201
|
|
|
202
202
|
if not_masked_location_set is None:
|
|
@@ -209,8 +209,8 @@ def get_replaced_biography_set(df: pandas.DataFrame, not_masked_location_set: Op
|
|
|
209
209
|
|
|
210
210
|
def create_replacement_dict_by_user_id(
|
|
211
211
|
df: pandas.DataFrame,
|
|
212
|
-
not_masked_biography_set:
|
|
213
|
-
not_masked_user_id_set:
|
|
212
|
+
not_masked_biography_set: set[str] | None = None,
|
|
213
|
+
not_masked_user_id_set: set[str] | None = None,
|
|
214
214
|
) -> dict[str, str]:
|
|
215
215
|
"""
|
|
216
216
|
keyが置換対象のuser_id、valueが置換後のマスクされたuser_idであるdictを作成する。
|
|
@@ -227,7 +227,7 @@ def create_replacement_dict_by_user_id(
|
|
|
227
227
|
|
|
228
228
|
def create_replacement_dict_by_biography(
|
|
229
229
|
df: pandas.DataFrame,
|
|
230
|
-
not_masked_biography_set:
|
|
230
|
+
not_masked_biography_set: set[str] | None = None,
|
|
231
231
|
) -> dict[str, str]:
|
|
232
232
|
"""
|
|
233
233
|
keyが置換対象のbiography、valueが置換後のマスクされた biography であるdictを作成する。
|
|
@@ -270,7 +270,7 @@ def replace_biography(df: pandas.DataFrame, replacement_dict_by_user_id: dict[st
|
|
|
270
270
|
user_id_column = _get_tuple_column(df, "user_id")
|
|
271
271
|
biography_column = _get_tuple_column(df, "biography")
|
|
272
272
|
|
|
273
|
-
def _get_biography(row: pandas.Series, user_id_column:
|
|
273
|
+
def _get_biography(row: pandas.Series, user_id_column: str | tuple, biography_column: str | tuple) -> str:
|
|
274
274
|
if row[user_id_column] in replacement_dict_by_user_id:
|
|
275
275
|
# マスク対象のユーザなら biographyをマスクする
|
|
276
276
|
biography = row[biography_column]
|
|
@@ -288,8 +288,8 @@ def replace_biography(df: pandas.DataFrame, replacement_dict_by_user_id: dict[st
|
|
|
288
288
|
def create_masked_user_info_df(
|
|
289
289
|
df: pandas.DataFrame,
|
|
290
290
|
*,
|
|
291
|
-
not_masked_biography_set:
|
|
292
|
-
not_masked_user_id_set:
|
|
291
|
+
not_masked_biography_set: set[str] | None = None,
|
|
292
|
+
not_masked_user_id_set: set[str] | None = None,
|
|
293
293
|
) -> pandas.DataFrame:
|
|
294
294
|
if "user_id" not in df:
|
|
295
295
|
logger.warning("引数`df`に`user_id`列が存在しないため、ユーザ情報をマスクできません。")
|
|
@@ -360,7 +360,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
360
360
|
parser.set_defaults(subcommand_func=main)
|
|
361
361
|
|
|
362
362
|
|
|
363
|
-
def add_parser(subparsers:
|
|
363
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
364
364
|
subcommand_name = "mask_user_info"
|
|
365
365
|
subcommand_help = "CSVに記載されたユーザ情報をマスクします。"
|
|
366
366
|
description = "CSVに記載されたユーザ情報をマスクします。CSVの`user_id`,`username`,`biography`,`account_id` 列をマスクします。"
|
|
@@ -3,9 +3,9 @@ import json
|
|
|
3
3
|
import logging
|
|
4
4
|
import sys
|
|
5
5
|
import zipfile
|
|
6
|
-
from collections.abc import Collection, Iterator
|
|
6
|
+
from collections.abc import Callable, Collection, Iterator
|
|
7
7
|
from pathlib import Path
|
|
8
|
-
from typing import Any
|
|
8
|
+
from typing import Any
|
|
9
9
|
|
|
10
10
|
from annofabapi.parser import (
|
|
11
11
|
SimpleAnnotationDirParser,
|
|
@@ -15,7 +15,7 @@ from annofabapi.parser import (
|
|
|
15
15
|
lazy_parse_simple_annotation_zip,
|
|
16
16
|
)
|
|
17
17
|
|
|
18
|
-
import annofabcli
|
|
18
|
+
import annofabcli.common.cli
|
|
19
19
|
from annofabcli.common.cli import (
|
|
20
20
|
COMMAND_LINE_ERROR_STATUS_CODE,
|
|
21
21
|
ArgumentParser,
|
|
@@ -110,7 +110,7 @@ class MergeAnnotationMain:
|
|
|
110
110
|
json.dump(simple_annotation, f, ensure_ascii=False)
|
|
111
111
|
|
|
112
112
|
@staticmethod
|
|
113
|
-
def _get_parser(annotation_path: Path, zip_file:
|
|
113
|
+
def _get_parser(annotation_path: Path, zip_file: zipfile.ZipFile | None, json_path: Path) -> SimpleAnnotationParser | None:
|
|
114
114
|
if annotation_path.is_dir():
|
|
115
115
|
if (annotation_path / json_path).exists():
|
|
116
116
|
return SimpleAnnotationDirParser(annotation_path / json_path)
|
|
@@ -126,8 +126,8 @@ class MergeAnnotationMain:
|
|
|
126
126
|
|
|
127
127
|
@staticmethod
|
|
128
128
|
def create_is_target_parser_func(
|
|
129
|
-
task_ids:
|
|
130
|
-
) ->
|
|
129
|
+
task_ids: Collection[str] | None = None,
|
|
130
|
+
) -> IsParserFunc | None:
|
|
131
131
|
if task_ids is None:
|
|
132
132
|
return None
|
|
133
133
|
|
|
@@ -147,13 +147,13 @@ class MergeAnnotationMain:
|
|
|
147
147
|
annotation_path1: Path,
|
|
148
148
|
annotation_path2: Path,
|
|
149
149
|
output_dir: Path,
|
|
150
|
-
target_task_ids:
|
|
150
|
+
target_task_ids: Collection[str] | None = None,
|
|
151
151
|
):
|
|
152
152
|
is_target_parser_func = self.create_is_target_parser_func(target_task_ids)
|
|
153
153
|
|
|
154
154
|
iter_parser1 = self.create_iter_parser(annotation_path1)
|
|
155
155
|
|
|
156
|
-
zip_file2:
|
|
156
|
+
zip_file2: zipfile.ZipFile | None = None
|
|
157
157
|
if annotation_path2.is_file():
|
|
158
158
|
zip_file2 = zipfile.ZipFile(str(annotation_path2), "r") # pylint: disable=consider-using-with
|
|
159
159
|
|
|
@@ -244,7 +244,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
244
244
|
parser.set_defaults(subcommand_func=main)
|
|
245
245
|
|
|
246
246
|
|
|
247
|
-
def add_parser(subparsers:
|
|
247
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
248
248
|
subcommand_name = "merge_annotation"
|
|
249
249
|
|
|
250
250
|
subcommand_help = "2つのアノテーションzip(またはzipを展開したディレクトリ)をマージします。"
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import argparse
|
|
2
|
-
from typing import Optional
|
|
3
2
|
|
|
4
|
-
import annofabcli
|
|
5
3
|
import annofabcli.common.cli
|
|
6
4
|
import annofabcli.filesystem.draw_annotation
|
|
7
5
|
import annofabcli.filesystem.filter_annotation
|
|
@@ -19,7 +17,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
19
17
|
annofabcli.filesystem.merge_annotation.add_parser(subparsers)
|
|
20
18
|
|
|
21
19
|
|
|
22
|
-
def add_parser(subparsers:
|
|
20
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
23
21
|
subcommand_name = "filesystem"
|
|
24
22
|
subcommand_help = "ファイル操作関係(Web APIにアクセスしない)のサブコマンド"
|
|
25
23
|
description = "ファイル操作関係(Web APIにアクセスしない)のサブコマンド"
|
|
@@ -7,13 +7,12 @@ import multiprocessing
|
|
|
7
7
|
import sys
|
|
8
8
|
import tempfile
|
|
9
9
|
from pathlib import Path
|
|
10
|
-
from typing import Any
|
|
10
|
+
from typing import Any
|
|
11
11
|
|
|
12
12
|
import annofabapi
|
|
13
13
|
import more_itertools
|
|
14
14
|
from annofabapi.models import ProjectMemberRole
|
|
15
15
|
|
|
16
|
-
import annofabcli
|
|
17
16
|
import annofabcli.common.cli
|
|
18
17
|
from annofabcli.common.cli import (
|
|
19
18
|
COMMAND_LINE_ERROR_STATUS_CODE,
|
|
@@ -49,7 +48,7 @@ class CopyInputDataMain(CommandLineWithConfirm):
|
|
|
49
48
|
|
|
50
49
|
CommandLineWithConfirm.__init__(self, all_yes)
|
|
51
50
|
|
|
52
|
-
def copy_supplementary_data(self, src_supplementary_data: dict[str, Any], last_updated_datetime:
|
|
51
|
+
def copy_supplementary_data(self, src_supplementary_data: dict[str, Any], last_updated_datetime: str | None) -> dict[str, Any]:
|
|
53
52
|
request_body = {
|
|
54
53
|
"supplementary_data_name": src_supplementary_data["supplementary_data_name"],
|
|
55
54
|
"supplementary_data_path": src_supplementary_data["supplementary_data_path"],
|
|
@@ -70,7 +69,7 @@ class CopyInputDataMain(CommandLineWithConfirm):
|
|
|
70
69
|
src_supplementary_data_list: list[dict[str, Any]],
|
|
71
70
|
dest_supplementary_data_list: list[dict[str, Any]],
|
|
72
71
|
*,
|
|
73
|
-
logging_prefix:
|
|
72
|
+
logging_prefix: str | None = None,
|
|
74
73
|
) -> None:
|
|
75
74
|
for src_supplementary_data in src_supplementary_data_list:
|
|
76
75
|
dest_supplementary_data = more_itertools.first_true(
|
|
@@ -93,7 +92,7 @@ class CopyInputDataMain(CommandLineWithConfirm):
|
|
|
93
92
|
f"src_project_id='{self.src_project_id}', dest_project_id='{self.dest_project_id}'"
|
|
94
93
|
)
|
|
95
94
|
|
|
96
|
-
def copy_input_data(self, src_input_data: dict[str, Any], last_updated_datetime:
|
|
95
|
+
def copy_input_data(self, src_input_data: dict[str, Any], last_updated_datetime: str | None) -> dict[str, Any]:
|
|
97
96
|
request_body = {
|
|
98
97
|
"input_data_name": src_input_data["input_data_name"],
|
|
99
98
|
"input_data_path": src_input_data["input_data_path"],
|
|
@@ -108,7 +107,7 @@ class CopyInputDataMain(CommandLineWithConfirm):
|
|
|
108
107
|
self,
|
|
109
108
|
input_data_id: str,
|
|
110
109
|
*,
|
|
111
|
-
input_data_index:
|
|
110
|
+
input_data_index: int | None = None,
|
|
112
111
|
) -> bool:
|
|
113
112
|
def get_confirm_message(supplementary_data_count: int, *, exists_in_dest_project: bool) -> str:
|
|
114
113
|
message = f"入力データ(input_data_id='{input_data_id}')と補助情報{supplementary_data_count}件をコピーしますか?"
|
|
@@ -181,9 +180,9 @@ class CopyInputDataMain(CommandLineWithConfirm):
|
|
|
181
180
|
|
|
182
181
|
def copy_input_data_list(
|
|
183
182
|
self,
|
|
184
|
-
input_data_id_list:
|
|
183
|
+
input_data_id_list: list[str] | None,
|
|
185
184
|
*,
|
|
186
|
-
parallelism:
|
|
185
|
+
parallelism: int | None = None,
|
|
187
186
|
) -> None:
|
|
188
187
|
if input_data_id_list is None:
|
|
189
188
|
input_data_id_list = self.get_all_input_data_id_list(self.src_project_id)
|
|
@@ -298,7 +297,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
298
297
|
parser.set_defaults(subcommand_func=main)
|
|
299
298
|
|
|
300
299
|
|
|
301
|
-
def add_parser(subparsers:
|
|
300
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
302
301
|
subcommand_name = "copy"
|
|
303
302
|
subcommand_help = "入力データと関連する補助情報を別プロジェクトにコピーします。"
|
|
304
303
|
description = (
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import logging
|
|
3
|
-
from typing import Any
|
|
3
|
+
from typing import Any
|
|
4
4
|
|
|
5
5
|
import requests
|
|
6
6
|
from annofabapi.models import ProjectMemberRole
|
|
7
7
|
|
|
8
|
-
import annofabcli
|
|
8
|
+
import annofabcli.common.cli
|
|
9
9
|
from annofabcli.common.cli import ArgumentParser, CommandLine, build_annofabapi_resource_and_login
|
|
10
10
|
from annofabcli.common.facade import AnnofabApiFacade
|
|
11
11
|
|
|
@@ -164,7 +164,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
164
164
|
parser.set_defaults(subcommand_func=main)
|
|
165
165
|
|
|
166
166
|
|
|
167
|
-
def add_parser(subparsers:
|
|
167
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
168
168
|
subcommand_name = "delete"
|
|
169
169
|
subcommand_help = "入力データを削除します。"
|
|
170
170
|
description = "入力データを削除します。"
|
|
@@ -8,12 +8,10 @@ import multiprocessing
|
|
|
8
8
|
import sys
|
|
9
9
|
from collections.abc import Collection
|
|
10
10
|
from functools import partial
|
|
11
|
-
from typing import Optional
|
|
12
11
|
|
|
13
12
|
import annofabapi
|
|
14
13
|
from annofabapi.models import ProjectMemberRole
|
|
15
14
|
|
|
16
|
-
import annofabcli
|
|
17
15
|
import annofabcli.common.cli
|
|
18
16
|
from annofabcli.common.cli import (
|
|
19
17
|
COMMAND_LINE_ERROR_STATUS_CODE,
|
|
@@ -40,7 +38,7 @@ class DeleteMetadataKeyOfInputDataMain(CommandLineWithConfirm):
|
|
|
40
38
|
self.project_id = project_id
|
|
41
39
|
super().__init__(all_yes=all_yes)
|
|
42
40
|
|
|
43
|
-
def delete_metadata_keys_for_one_input_data(self, input_data_id: str, metadata_keys: Collection[str], *, input_data_index:
|
|
41
|
+
def delete_metadata_keys_for_one_input_data(self, input_data_id: str, metadata_keys: Collection[str], *, input_data_index: int | None = None) -> bool:
|
|
44
42
|
"""
|
|
45
43
|
1個の入力データに対して、メタデータのキーを削除します。
|
|
46
44
|
|
|
@@ -100,7 +98,7 @@ class DeleteMetadataKeyOfInputDataMain(CommandLineWithConfirm):
|
|
|
100
98
|
logger.warning(f"input_data_id='{input_data_id}' :: 入力データのメタデータのキーを削除するのに失敗しました。", exc_info=True)
|
|
101
99
|
return False
|
|
102
100
|
|
|
103
|
-
def delete_metadata_keys_for_input_data_list(self, input_data_id_list: list[str], metadata_keys: Collection[str], *, parallelism:
|
|
101
|
+
def delete_metadata_keys_for_input_data_list(self, input_data_id_list: list[str], metadata_keys: Collection[str], *, parallelism: int | None = None) -> None:
|
|
104
102
|
logger.info(f"{len(input_data_id_list)} 件の入力データのメタデータから、キー'{metadata_keys}'を削除します。")
|
|
105
103
|
|
|
106
104
|
success_count = 0
|
|
@@ -185,7 +183,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
185
183
|
parser.set_defaults(subcommand_func=main)
|
|
186
184
|
|
|
187
185
|
|
|
188
|
-
def add_parser(subparsers:
|
|
186
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
189
187
|
subcommand_name = "delete_metadata_key"
|
|
190
188
|
subcommand_help = "入力データのメタデータのキーを削除します。"
|
|
191
189
|
epilog = "オーナロールを持つユーザで実行してください。"
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import logging
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import Optional
|
|
5
4
|
|
|
6
5
|
from annofabapi.models import ProjectMemberRole
|
|
7
6
|
|
|
8
|
-
import annofabcli
|
|
9
7
|
import annofabcli.common.cli
|
|
10
8
|
from annofabcli.common.cli import CommandLine, build_annofabapi_resource_and_login
|
|
11
9
|
from annofabcli.common.download import DownloadingFile
|
|
@@ -15,10 +13,10 @@ logger = logging.getLogger(__name__)
|
|
|
15
13
|
|
|
16
14
|
|
|
17
15
|
class DownloadingInputData(CommandLine):
|
|
18
|
-
def download_input_data_json(self, project_id: str, output_file: Path, is_latest: bool): # noqa:
|
|
16
|
+
def download_input_data_json(self, project_id: str, output_file: Path, is_latest: bool) -> None: # noqa: FBT001
|
|
19
17
|
super().validate_project(project_id, [ProjectMemberRole.OWNER, ProjectMemberRole.TRAINING_DATA_USER])
|
|
20
18
|
project_title = self.facade.get_project_title(project_id)
|
|
21
|
-
logger.info(f"{project_title}
|
|
19
|
+
logger.info(f"project_id='{project_id}'の入力データ全件ファイルをダウンロードします。 :: project_title='{project_title}'")
|
|
22
20
|
|
|
23
21
|
obj = DownloadingFile(self.service)
|
|
24
22
|
obj.download_input_data_json(
|
|
@@ -26,7 +24,7 @@ class DownloadingInputData(CommandLine):
|
|
|
26
24
|
str(output_file),
|
|
27
25
|
is_latest=is_latest,
|
|
28
26
|
)
|
|
29
|
-
logger.info(f"
|
|
27
|
+
logger.info(f"project_id='{project_id}'の入力データ全件ファイルをダウンロードしました。 :: output='{output_file}', project_title='{project_title}'")
|
|
30
28
|
|
|
31
29
|
def main(self) -> None:
|
|
32
30
|
args = self.args
|
|
@@ -58,7 +56,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
58
56
|
parser.set_defaults(subcommand_func=main)
|
|
59
57
|
|
|
60
58
|
|
|
61
|
-
def add_parser(subparsers:
|
|
59
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
62
60
|
subcommand_name = "download"
|
|
63
61
|
subcommand_help = "入力データ全件ファイルをダウンロードします。"
|
|
64
62
|
epilog = "オーナロールまたはアノテーションユーザロールを持つユーザで実行してください。"
|
|
@@ -6,14 +6,14 @@ import json
|
|
|
6
6
|
import logging
|
|
7
7
|
import tempfile
|
|
8
8
|
from pathlib import Path
|
|
9
|
-
from typing import Any
|
|
9
|
+
from typing import Any
|
|
10
10
|
|
|
11
11
|
import annofabapi
|
|
12
12
|
import pandas
|
|
13
13
|
from annofabapi.dataclass.input import InputData
|
|
14
14
|
from annofabapi.models import ProjectMemberRole
|
|
15
15
|
|
|
16
|
-
import annofabcli
|
|
16
|
+
import annofabcli.common.cli
|
|
17
17
|
from annofabcli.common.cli import ArgumentParser, CommandLine, build_annofabapi_resource_and_login, print_according_to_format, print_csv
|
|
18
18
|
from annofabcli.common.download import DownloadingFile
|
|
19
19
|
from annofabcli.common.enums import FormatArgument
|
|
@@ -23,7 +23,7 @@ from annofabcli.input_data.utils import remove_unnecessary_keys_from_input_data
|
|
|
23
23
|
|
|
24
24
|
logger = logging.getLogger(__name__)
|
|
25
25
|
|
|
26
|
-
DatetimeRange = tuple[
|
|
26
|
+
DatetimeRange = tuple[datetime.datetime | None, datetime.datetime | None]
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
class ListInputDataWithJsonMain:
|
|
@@ -33,8 +33,8 @@ class ListInputDataWithJsonMain:
|
|
|
33
33
|
@staticmethod
|
|
34
34
|
def filter_input_data_list(
|
|
35
35
|
input_data: dict[str, Any],
|
|
36
|
-
input_data_id_set:
|
|
37
|
-
input_data_query:
|
|
36
|
+
input_data_id_set: set[str] | None = None,
|
|
37
|
+
input_data_query: InputDataQuery | None = None,
|
|
38
38
|
) -> bool:
|
|
39
39
|
result = True
|
|
40
40
|
|
|
@@ -64,10 +64,10 @@ class ListInputDataWithJsonMain:
|
|
|
64
64
|
def get_input_data_list(
|
|
65
65
|
self,
|
|
66
66
|
project_id: str,
|
|
67
|
-
input_data_json:
|
|
67
|
+
input_data_json: Path | None,
|
|
68
68
|
*,
|
|
69
|
-
input_data_id_list:
|
|
70
|
-
input_data_query:
|
|
69
|
+
input_data_id_list: list[str] | None = None,
|
|
70
|
+
input_data_query: InputDataQuery | None = None,
|
|
71
71
|
contain_parent_task_id_list: bool = False,
|
|
72
72
|
contain_supplementary_data_count: bool = False,
|
|
73
73
|
is_latest: bool = False,
|
|
@@ -209,7 +209,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
209
209
|
parser.set_defaults(subcommand_func=main)
|
|
210
210
|
|
|
211
211
|
|
|
212
|
-
def add_parser(subparsers:
|
|
212
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
213
213
|
subcommand_name = "list_all"
|
|
214
214
|
subcommand_help = "すべての入力データの一覧を出力します。"
|
|
215
215
|
description = "すべての入力データの一覧を出力します。\n出力される入力データは、コマンドを実行した日の02:00(JST)頃の状態です。最新の情報を出力したい場合は、 ``--latest`` を指定してください。"
|