annofabcli 1.114.2__py3-none-any.whl → 1.114.4__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.
Files changed (63) hide show
  1. annofabcli/annotation/list_annotation.py +4 -4
  2. annofabcli/annotation/list_annotation_count.py +4 -4
  3. annofabcli/annotation_specs/export_annotation_specs.py +4 -4
  4. annofabcli/annotation_specs/get_annotation_specs_with_attribute_id_replaced.py +4 -4
  5. annofabcli/annotation_specs/get_annotation_specs_with_choice_id_replaced.py +4 -4
  6. annofabcli/annotation_specs/get_annotation_specs_with_label_id_replaced.py +4 -4
  7. annofabcli/annotation_specs/list_annotation_specs_attribute.py +7 -7
  8. annofabcli/annotation_specs/list_annotation_specs_choice.py +9 -9
  9. annofabcli/annotation_specs/list_annotation_specs_history.py +2 -2
  10. annofabcli/annotation_specs/list_annotation_specs_label.py +8 -8
  11. annofabcli/annotation_specs/list_annotation_specs_label_attribute.py +7 -7
  12. annofabcli/annotation_specs/list_label_color.py +2 -2
  13. annofabcli/annotation_zip/list_annotation_3d_bounding_box.py +8 -8
  14. annofabcli/annotation_zip/list_annotation_bounding_box_2d.py +8 -8
  15. annofabcli/annotation_zip/list_polygon_annotation.py +8 -8
  16. annofabcli/annotation_zip/list_polyline_annotation.py +8 -8
  17. annofabcli/annotation_zip/list_range_annotation.py +8 -8
  18. annofabcli/annotation_zip/list_single_point_annotation.py +8 -8
  19. annofabcli/annotation_zip/validate_annotation.py +2 -2
  20. annofabcli/comment/list_all_comment.py +8 -8
  21. annofabcli/comment/list_comment.py +8 -8
  22. annofabcli/common/cli.py +3 -3
  23. annofabcli/common/enums.py +1 -1
  24. annofabcli/common/pandas.py +4 -3
  25. annofabcli/common/utils.py +10 -10
  26. annofabcli/common/visualize.py +3 -3
  27. annofabcli/filesystem/mask_user_info.py +3 -2
  28. annofabcli/input_data/list_all_input_data.py +11 -22
  29. annofabcli/input_data/list_all_input_data_merged_task.py +7 -7
  30. annofabcli/input_data/list_input_data.py +67 -18
  31. annofabcli/instruction/list_instruction_history.py +2 -2
  32. annofabcli/job/list_job.py +2 -2
  33. annofabcli/job/list_last_job.py +2 -2
  34. annofabcli/my_account/get_my_account.py +4 -4
  35. annofabcli/organization/list_organization.py +5 -5
  36. annofabcli/organization_member/list_organization_member.py +4 -4
  37. annofabcli/project/list_project.py +9 -9
  38. annofabcli/project_member/list_users.py +4 -4
  39. annofabcli/statistics/list_annotation_area.py +8 -8
  40. annofabcli/statistics/list_annotation_attribute.py +8 -8
  41. annofabcli/statistics/list_annotation_attribute_filled_count.py +11 -11
  42. annofabcli/statistics/list_annotation_count.py +8 -8
  43. annofabcli/statistics/list_annotation_duration.py +8 -8
  44. annofabcli/statistics/list_video_duration.py +6 -6
  45. annofabcli/statistics/summarize_task_count_by_task_id_group.py +2 -2
  46. annofabcli/statistics/summarize_task_count_by_user.py +2 -2
  47. annofabcli/statistics/visualization/dataframe/project_performance.py +2 -1
  48. annofabcli/statistics/visualization/dataframe/task.py +25 -6
  49. annofabcli/supplementary/list_supplementary_data.py +2 -2
  50. annofabcli/task/list_all_tasks.py +8 -18
  51. annofabcli/task/list_all_tasks_added_task_history.py +6 -6
  52. annofabcli/task/list_tasks.py +73 -37
  53. annofabcli/task/list_tasks_added_task_history.py +25 -16
  54. annofabcli/task_count/list_by_phase.py +7 -1
  55. annofabcli/task_history/list_all_task_history.py +6 -6
  56. annofabcli/task_history/list_task_history.py +6 -6
  57. annofabcli/task_history_event/list_all_task_history_event.py +6 -6
  58. annofabcli/task_history_event/list_worktime.py +6 -6
  59. {annofabcli-1.114.2.dist-info → annofabcli-1.114.4.dist-info}/METADATA +2 -2
  60. {annofabcli-1.114.2.dist-info → annofabcli-1.114.4.dist-info}/RECORD +63 -63
  61. {annofabcli-1.114.2.dist-info → annofabcli-1.114.4.dist-info}/WHEEL +0 -0
  62. {annofabcli-1.114.2.dist-info → annofabcli-1.114.4.dist-info}/entry_points.txt +0 -0
  63. {annofabcli-1.114.2.dist-info → annofabcli-1.114.4.dist-info}/licenses/LICENSE +0 -0
@@ -17,7 +17,7 @@ import annofabcli.common.cli
17
17
  from annofabcli.common.annofab.annotation_zip import lazy_parse_simple_annotation_by_input_data
18
18
  from annofabcli.common.cli import COMMAND_LINE_ERROR_STATUS_CODE, ArgumentParser, CommandLine, build_annofabapi_resource_and_login, get_list_from_args
19
19
  from annofabcli.common.download import DownloadingFile
20
- from annofabcli.common.enums import FormatArgument
20
+ from annofabcli.common.enums import OutputFormat
21
21
  from annofabcli.common.facade import (
22
22
  AnnofabApiFacade,
23
23
  TaskQuery,
@@ -147,7 +147,7 @@ def create_df(
147
147
  def print_range_annotation(
148
148
  annotation_path: Path,
149
149
  output_file: Path,
150
- output_format: FormatArgument,
150
+ output_format: OutputFormat,
151
151
  *,
152
152
  target_task_ids: Collection[str] | None = None,
153
153
  task_query: TaskQuery | None = None,
@@ -162,12 +162,12 @@ def print_range_annotation(
162
162
 
163
163
  logger.info(f"{len(range_annotation_list)} 件の区間アノテーションの情報を出力します。 :: output='{output_file}'")
164
164
 
165
- if output_format == FormatArgument.CSV:
165
+ if output_format == OutputFormat.CSV:
166
166
  df = create_df(range_annotation_list)
167
167
  print_csv(df, output_file)
168
168
 
169
- elif output_format in [FormatArgument.PRETTY_JSON, FormatArgument.JSON]:
170
- json_is_pretty = output_format == FormatArgument.PRETTY_JSON
169
+ elif output_format in [OutputFormat.PRETTY_JSON, OutputFormat.JSON]:
170
+ json_is_pretty = output_format == OutputFormat.PRETTY_JSON
171
171
  # DataClassJsonMixinを使用したtoJSON処理
172
172
  print_json(
173
173
  [e.to_dict(encode_json=True) for e in range_annotation_list],
@@ -212,7 +212,7 @@ class ListRangeAnnotation(CommandLine):
212
212
  label_name_list = get_list_from_args(args.label_name) if args.label_name is not None else None
213
213
 
214
214
  output_file: Path = args.output
215
- output_format = FormatArgument(args.format)
215
+ output_format = OutputFormat(args.format)
216
216
 
217
217
  downloading_obj = DownloadingFile(self.service)
218
218
 
@@ -266,8 +266,8 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
266
266
  group.add_argument("-p", "--project_id", type=str, help="project_id。アノテーションZIPをダウンロードします。")
267
267
 
268
268
  argument_parser.add_format(
269
- choices=[FormatArgument.CSV, FormatArgument.JSON, FormatArgument.PRETTY_JSON],
270
- default=FormatArgument.CSV,
269
+ choices=[OutputFormat.CSV, OutputFormat.JSON, OutputFormat.PRETTY_JSON],
270
+ default=OutputFormat.CSV,
271
271
  )
272
272
 
273
273
  argument_parser.add_output()
@@ -15,7 +15,7 @@ import annofabcli.common.cli
15
15
  from annofabcli.common.annofab.annotation_zip import lazy_parse_simple_annotation_by_input_data
16
16
  from annofabcli.common.cli import COMMAND_LINE_ERROR_STATUS_CODE, ArgumentParser, CommandLine, build_annofabapi_resource_and_login, get_list_from_args
17
17
  from annofabcli.common.download import DownloadingFile
18
- from annofabcli.common.enums import FormatArgument
18
+ from annofabcli.common.enums import OutputFormat
19
19
  from annofabcli.common.facade import (
20
20
  AnnofabApiFacade,
21
21
  TaskQuery,
@@ -136,7 +136,7 @@ def create_df(
136
136
  def print_annotation_single_point(
137
137
  annotation_path: Path,
138
138
  output_file: Path,
139
- output_format: FormatArgument,
139
+ output_format: OutputFormat,
140
140
  *,
141
141
  target_task_ids: Collection[str] | None = None,
142
142
  task_query: TaskQuery | None = None,
@@ -151,12 +151,12 @@ def print_annotation_single_point(
151
151
 
152
152
  logger.info(f"{len(annotation_point_list)} 件の点アノテーションの情報を出力します。 :: output='{output_file}'")
153
153
 
154
- if output_format == FormatArgument.CSV:
154
+ if output_format == OutputFormat.CSV:
155
155
  df = create_df(annotation_point_list)
156
156
  print_csv(df, output_file)
157
157
 
158
- elif output_format in [FormatArgument.PRETTY_JSON, FormatArgument.JSON]:
159
- json_is_pretty = output_format == FormatArgument.PRETTY_JSON
158
+ elif output_format in [OutputFormat.PRETTY_JSON, OutputFormat.JSON]:
159
+ json_is_pretty = output_format == OutputFormat.PRETTY_JSON
160
160
  # DataClassJsonMixinを使用したtoJSON処理
161
161
  print_json(
162
162
  [e.to_dict(encode_json=True) for e in annotation_point_list],
@@ -201,7 +201,7 @@ class ListAnnotationSinglePoint(CommandLine):
201
201
  label_name_list = get_list_from_args(args.label_name) if args.label_name is not None else None
202
202
 
203
203
  output_file: Path = args.output
204
- output_format = FormatArgument(args.format)
204
+ output_format = OutputFormat(args.format)
205
205
 
206
206
  downloading_obj = DownloadingFile(self.service)
207
207
 
@@ -256,8 +256,8 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
256
256
  group.add_argument("-p", "--project_id", type=str, help="project_id。アノテーションZIPをダウンロードします。")
257
257
 
258
258
  argument_parser.add_format(
259
- choices=[FormatArgument.CSV, FormatArgument.JSON, FormatArgument.PRETTY_JSON],
260
- default=FormatArgument.CSV,
259
+ choices=[OutputFormat.CSV, OutputFormat.JSON, OutputFormat.PRETTY_JSON],
260
+ default=OutputFormat.CSV,
261
261
  )
262
262
 
263
263
  argument_parser.add_output()
@@ -19,7 +19,7 @@ import annofabcli.common.cli
19
19
  from annofabcli.common.annofab.annotation_zip import lazy_parse_simple_annotation_by_input_data
20
20
  from annofabcli.common.cli import COMMAND_LINE_ERROR_STATUS_CODE, ArgumentParser, CommandLine, build_annofabapi_resource_and_login
21
21
  from annofabcli.common.download import DownloadingFile
22
- from annofabcli.common.enums import FormatArgument
22
+ from annofabcli.common.enums import OutputFormat
23
23
  from annofabcli.common.facade import AnnofabApiFacade, TaskQuery, match_annotation_with_task_query
24
24
  from annofabcli.common.utils import print_csv, print_json
25
25
 
@@ -377,7 +377,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
377
377
  ),
378
378
  )
379
379
 
380
- argument_parser.add_format(choices=[FormatArgument.CSV, FormatArgument.JSON], default=FormatArgument.CSV)
380
+ argument_parser.add_format(choices=[OutputFormat.CSV, OutputFormat.JSON], default=OutputFormat.CSV)
381
381
  argument_parser.add_output()
382
382
 
383
383
  parser.set_defaults(subcommand_func=main)
@@ -20,7 +20,7 @@ import annofabcli.common.cli
20
20
  from annofabcli.comment.list_comment import create_empty_df_comment, create_reply_counter
21
21
  from annofabcli.common.cli import ArgumentParser, CommandLine, build_annofabapi_resource_and_login
22
22
  from annofabcli.common.download import DownloadingFile
23
- from annofabcli.common.enums import FormatArgument
23
+ from annofabcli.common.enums import OutputFormat
24
24
  from annofabcli.common.facade import AnnofabApiFacade
25
25
  from annofabcli.common.utils import print_according_to_format, print_csv
26
26
  from annofabcli.common.visualize import AddProps
@@ -125,8 +125,8 @@ class ListAllComment(CommandLine):
125
125
 
126
126
  logger.info(f"コメントの件数: {len(comment_list)}")
127
127
 
128
- output_format = FormatArgument(args.format)
129
- if output_format == FormatArgument.CSV:
128
+ output_format = OutputFormat(args.format)
129
+ if output_format == OutputFormat.CSV:
130
130
  if len(comment_list) > 0:
131
131
  df = pandas.json_normalize(comment_list)
132
132
  else:
@@ -168,12 +168,12 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
168
168
 
169
169
  argument_parser.add_format(
170
170
  choices=[
171
- FormatArgument.CSV,
172
- FormatArgument.JSON,
173
- FormatArgument.PRETTY_JSON,
174
- FormatArgument.COMMENT_ID_LIST,
171
+ OutputFormat.CSV,
172
+ OutputFormat.JSON,
173
+ OutputFormat.PRETTY_JSON,
174
+ OutputFormat.COMMENT_ID_LIST,
175
175
  ],
176
- default=FormatArgument.CSV,
176
+ default=OutputFormat.CSV,
177
177
  )
178
178
  argument_parser.add_output()
179
179
 
@@ -11,7 +11,7 @@ from annofabapi.models import Comment, CommentType
11
11
 
12
12
  import annofabcli.common.cli
13
13
  from annofabcli.common.cli import ArgumentParser, CommandLine, build_annofabapi_resource_and_login
14
- from annofabcli.common.enums import FormatArgument
14
+ from annofabcli.common.enums import OutputFormat
15
15
  from annofabcli.common.facade import AnnofabApiFacade
16
16
  from annofabcli.common.utils import print_according_to_format, print_csv
17
17
  from annofabcli.common.visualize import AddProps
@@ -101,8 +101,8 @@ class ListingComments(CommandLine):
101
101
 
102
102
  logger.info(f"コメントの件数: {len(comment_list)}")
103
103
 
104
- output_format = FormatArgument(args.format)
105
- if output_format == FormatArgument.CSV:
104
+ output_format = OutputFormat(args.format)
105
+ if output_format == OutputFormat.CSV:
106
106
  if len(comment_list) > 0:
107
107
  df = pandas.json_normalize(comment_list)
108
108
  else:
@@ -138,12 +138,12 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
138
138
 
139
139
  argument_parser.add_format(
140
140
  choices=[
141
- FormatArgument.CSV,
142
- FormatArgument.JSON,
143
- FormatArgument.PRETTY_JSON,
144
- FormatArgument.COMMENT_ID_LIST,
141
+ OutputFormat.CSV,
142
+ OutputFormat.JSON,
143
+ OutputFormat.PRETTY_JSON,
144
+ OutputFormat.COMMENT_ID_LIST,
145
145
  ],
146
- default=FormatArgument.CSV,
146
+ default=OutputFormat.CSV,
147
147
  )
148
148
  argument_parser.add_output()
149
149
 
annofabcli/common/cli.py CHANGED
@@ -21,7 +21,7 @@ from annofabapi.exceptions import AnnofabApiException
21
21
  from annofabapi.models import OrganizationMemberRole, ProjectMemberRole
22
22
  from more_itertools import first_true
23
23
 
24
- from annofabcli.common.enums import FormatArgument
24
+ from annofabcli.common.enums import OutputFormat
25
25
  from annofabcli.common.exceptions import AnnofabCliException, AuthenticationError
26
26
  from annofabcli.common.facade import AnnofabApiFacade
27
27
  from annofabcli.common.typing import InputDataSize
@@ -408,7 +408,7 @@ class ArgumentParser:
408
408
 
409
409
  self.parser.add_argument("-i", "--input_data_id", type=str, required=required, nargs="+", help=help_message)
410
410
 
411
- def add_format(self, choices: list[FormatArgument], default: FormatArgument, help_message: str | None = None) -> None:
411
+ def add_format(self, choices: list[OutputFormat], default: OutputFormat, help_message: str | None = None) -> None:
412
412
  """
413
413
  '--format` 引数を追加
414
414
  """
@@ -529,7 +529,7 @@ class CommandLineWithoutWebapi:
529
529
  print_csv(df, output=self.output)
530
530
 
531
531
  def print_according_to_format(self, target: Any) -> None: # noqa: ANN401
532
- print_according_to_format(target, format=FormatArgument(self.str_format), output=self.output)
532
+ print_according_to_format(target, format=OutputFormat(self.str_format), output=self.output)
533
533
 
534
534
 
535
535
  class PrettyHelpFormatter(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter):
@@ -1,7 +1,7 @@
1
1
  from enum import Enum
2
2
 
3
3
 
4
- class FormatArgument(Enum):
4
+ class OutputFormat(Enum):
5
5
  """
6
6
  表示するフォーマット ``--format`` で指定できる値
7
7
 
@@ -9,9 +9,10 @@ def get_frequency_of_monthend() -> str:
9
9
  https://github.com/pandas-dev/pandas/issues/9586
10
10
  """
11
11
  tmp = pandas.__version__.split(".")
12
- major = tmp[0]
13
- minor = tmp[1]
12
+ major = int(tmp[0])
13
+ minor = int(tmp[1])
14
14
 
15
- if int(major) >= 2 and int(minor) >= 2:
15
+ # pandas 3.0以上、または pandas 2.2以上の場合は"ME"を返す
16
+ if major >= 3 or (major == 2 and minor >= 2):
16
17
  return "ME"
17
18
  return "M"
@@ -11,7 +11,7 @@ import dateutil.parser
11
11
  import isodate
12
12
  import pandas
13
13
 
14
- from annofabcli.common.enums import FormatArgument
14
+ from annofabcli.common.enums import OutputFormat
15
15
 
16
16
  logger = logging.getLogger(__name__)
17
17
 
@@ -105,7 +105,7 @@ def print_id_list(id_list: list[Any], output: str | Path | None) -> None:
105
105
 
106
106
  def print_according_to_format(
107
107
  target: Any, # noqa: ANN401
108
- format: FormatArgument, # noqa: A002
108
+ format: OutputFormat, # noqa: A002
109
109
  output: str | Path | None = None,
110
110
  ) -> None:
111
111
  """
@@ -119,33 +119,33 @@ def print_according_to_format(
119
119
 
120
120
  """
121
121
 
122
- if format == FormatArgument.PRETTY_JSON:
122
+ if format == OutputFormat.PRETTY_JSON:
123
123
  print_json(target, is_pretty=True, output=output)
124
124
 
125
- elif format == FormatArgument.JSON:
125
+ elif format == OutputFormat.JSON:
126
126
  print_json(target, is_pretty=False, output=output)
127
127
 
128
- elif format == FormatArgument.CSV:
128
+ elif format == OutputFormat.CSV:
129
129
  df = pandas.DataFrame(target)
130
130
  print_csv(df, output=output)
131
131
 
132
- elif format == FormatArgument.TASK_ID_LIST:
132
+ elif format == OutputFormat.TASK_ID_LIST:
133
133
  task_id_list = [e["task_id"] for e in target]
134
134
  print_id_list(task_id_list, output)
135
135
 
136
- elif format == FormatArgument.PROJECT_ID_LIST:
136
+ elif format == OutputFormat.PROJECT_ID_LIST:
137
137
  project_id_list = [e["project_id"] for e in target]
138
138
  print_id_list(project_id_list, output)
139
139
 
140
- elif format == FormatArgument.INPUT_DATA_ID_LIST:
140
+ elif format == OutputFormat.INPUT_DATA_ID_LIST:
141
141
  input_data_id_list = [e["input_data_id"] for e in target]
142
142
  print_id_list(input_data_id_list, output)
143
143
 
144
- elif format == FormatArgument.USER_ID_LIST:
144
+ elif format == OutputFormat.USER_ID_LIST:
145
145
  user_id_list = [e["user_id"] for e in target]
146
146
  print_id_list(user_id_list, output)
147
147
 
148
- elif format == FormatArgument.INSPECTION_ID_LIST:
148
+ elif format == OutputFormat.INSPECTION_ID_LIST:
149
149
  inspection_id_list = [e["inspection_id"] for e in target]
150
150
  print_id_list(inspection_id_list, output)
151
151
 
@@ -375,10 +375,10 @@ class AddProps:
375
375
 
376
376
  * user_id
377
377
  * username
378
- * request.user_id
379
- * request.username
378
+ * `request`キー配下のdictに、`user_id`と`username`を追加する.
380
379
 
381
380
  """
382
381
  self._add_user_info(task_history_event)
383
- self._add_user_info(task_history_event["request"])
382
+ if task_history_event.get("request") is not None:
383
+ self._add_user_info(task_history_event["request"])
384
384
  return task_history_event
@@ -4,8 +4,8 @@ from functools import partial
4
4
  from pathlib import Path
5
5
  from typing import Any
6
6
 
7
- import numpy
8
7
  import pandas
8
+ from pandas.api.types import is_string_dtype
9
9
 
10
10
  import annofabcli.common.cli
11
11
  from annofabcli.common.cli import ArgumentParser, CommandLineWithoutWebapi, get_list_from_args
@@ -160,7 +160,8 @@ def replace_by_columns( # noqa: ANN201
160
160
  df[sub_column] = df.apply(get_username_func, axis=1)
161
161
 
162
162
  # 列の型を合わせないとreplaceに失敗するため, dtype を確認する
163
- if df[main_column].dtype == numpy.dtype("object"):
163
+ # pandas 3.0対応: is_string_dtypeを使用してobject型と新しいstring型の両方に対応
164
+ if is_string_dtype(df[main_column].dtype):
164
165
  df[main_column] = df[main_column].replace(replacement_dict)
165
166
 
166
167
 
@@ -9,16 +9,15 @@ from pathlib import Path
9
9
  from typing import Any
10
10
 
11
11
  import annofabapi
12
- import pandas
13
12
  from annofabapi.dataclass.input import InputData
14
13
  from annofabapi.models import ProjectMemberRole
15
14
 
16
15
  import annofabcli.common.cli
17
- from annofabcli.common.cli import ArgumentParser, CommandLine, build_annofabapi_resource_and_login, print_according_to_format, print_csv
16
+ from annofabcli.common.cli import ArgumentParser, CommandLine, build_annofabapi_resource_and_login
18
17
  from annofabcli.common.download import DownloadingFile
19
- from annofabcli.common.enums import FormatArgument
18
+ from annofabcli.common.enums import OutputFormat
20
19
  from annofabcli.common.facade import AnnofabApiFacade, InputDataQuery, match_input_data_with_query
21
- from annofabcli.input_data.list_input_data import AddingDetailsToInputData
20
+ from annofabcli.input_data.list_input_data import AddingDetailsToInputData, print_input_data_list
22
21
  from annofabcli.input_data.utils import remove_unnecessary_keys_from_input_data
23
22
 
24
23
  logger = logging.getLogger(__name__)
@@ -144,20 +143,10 @@ class ListAllInputData(CommandLine):
144
143
  temp_dir=temp_dir,
145
144
  )
146
145
 
147
- logger.debug(f"入力データ一覧の件数: {len(input_data_list)}")
146
+ logger.info(f"入力データ一覧の件数: {len(input_data_list)}")
148
147
 
149
- if len(input_data_list) > 0:
150
- output_format = FormatArgument(args.format)
151
- if output_format == FormatArgument.CSV:
152
- # pandas.DataFrameでなくpandas.json_normalizeを使う理由:
153
- # ネストしたオブジェクトを`system_metadata.input_duration`のような列名でアクセスできるようにするため
154
- df = pandas.json_normalize(input_data_list)
155
- print_csv(df, output=args.output)
156
- else:
157
- print_according_to_format(input_data_list, format=output_format, output=args.output)
158
-
159
- else:
160
- logger.info("入力データ一覧の件数が0件のため、出力しません。")
148
+ output_format = OutputFormat(args.format)
149
+ print_input_data_list(input_data_list, output_format=output_format, output_file=args.output)
161
150
 
162
151
 
163
152
  def main(args: argparse.Namespace) -> None:
@@ -220,12 +209,12 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
220
209
 
221
210
  argument_parser.add_format(
222
211
  choices=[
223
- FormatArgument.CSV,
224
- FormatArgument.JSON,
225
- FormatArgument.PRETTY_JSON,
226
- FormatArgument.INPUT_DATA_ID_LIST,
212
+ OutputFormat.CSV,
213
+ OutputFormat.JSON,
214
+ OutputFormat.PRETTY_JSON,
215
+ OutputFormat.INPUT_DATA_ID_LIST,
227
216
  ],
228
- default=FormatArgument.CSV,
217
+ default=OutputFormat.CSV,
229
218
  )
230
219
  argument_parser.add_output()
231
220
 
@@ -21,7 +21,7 @@ from annofabcli.common.cli import (
21
21
  get_list_from_args,
22
22
  )
23
23
  from annofabcli.common.download import DownloadingFile
24
- from annofabcli.common.enums import FormatArgument
24
+ from annofabcli.common.enums import OutputFormat
25
25
  from annofabcli.common.facade import AnnofabApiFacade, InputDataQuery, match_input_data_with_query
26
26
  from annofabcli.common.utils import print_csv
27
27
  from annofabcli.input_data.utils import remove_unnecessary_keys_from_input_data
@@ -191,11 +191,11 @@ class ListInputDataMergedTask(CommandLine):
191
191
 
192
192
  logger.debug(f"入力データ {len(filtered_input_data_list_with_merged_task)} 件を出力します。")
193
193
 
194
- if self.str_format == FormatArgument.CSV.value:
194
+ if self.str_format == OutputFormat.CSV.value:
195
195
  df_input_data = create_df_input_data_with_merged_task(filtered_input_data_list_with_merged_task)
196
196
  print_csv(df_input_data, output=args.output)
197
197
 
198
- elif self.str_format in [FormatArgument.JSON.value, FormatArgument.PRETTY_JSON.value]:
198
+ elif self.str_format in [OutputFormat.JSON.value, OutputFormat.PRETTY_JSON.value]:
199
199
  self.print_according_to_format(filtered_input_data_list_with_merged_task)
200
200
 
201
201
 
@@ -262,11 +262,11 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
262
262
 
263
263
  argument_parser.add_format(
264
264
  choices=[
265
- FormatArgument.CSV,
266
- FormatArgument.JSON,
267
- FormatArgument.PRETTY_JSON,
265
+ OutputFormat.CSV,
266
+ OutputFormat.JSON,
267
+ OutputFormat.PRETTY_JSON,
268
268
  ],
269
- default=FormatArgument.CSV,
269
+ default=OutputFormat.CSV,
270
270
  )
271
271
  argument_parser.add_output()
272
272
 
@@ -1,6 +1,7 @@
1
1
  import argparse
2
2
  import logging
3
3
  import urllib.parse
4
+ from pathlib import Path
4
5
  from typing import Any
5
6
 
6
7
  import annofabapi
@@ -8,14 +9,71 @@ import pandas
8
9
  from annofabapi.models import InputData
9
10
 
10
11
  import annofabcli.common.cli
11
- from annofabcli.common.cli import ArgumentParser, CommandLine, build_annofabapi_resource_and_login, print_according_to_format, print_csv
12
- from annofabcli.common.enums import FormatArgument
12
+ from annofabcli.common.cli import ArgumentParser, CommandLine, build_annofabapi_resource_and_login
13
+ from annofabcli.common.enums import OutputFormat
13
14
  from annofabcli.common.facade import AnnofabApiFacade
15
+ from annofabcli.common.utils import get_columns_with_priority, print_csv, print_id_list, print_json
14
16
  from annofabcli.input_data.utils import remove_unnecessary_keys_from_input_data
15
17
 
16
18
  logger = logging.getLogger(__name__)
17
19
 
18
20
 
21
+ def print_input_data_list(
22
+ input_data_list: list[dict[str, Any]],
23
+ output_format: OutputFormat,
24
+ output_file: Path | None,
25
+ ) -> None:
26
+ """
27
+ 入力データ一覧を指定されたフォーマットで出力する。
28
+
29
+ Args:
30
+ input_data_list: 入力データ一覧
31
+ output_format: 出力フォーマット
32
+ output_file: 出力先
33
+ """
34
+ input_data_prior_columns = [
35
+ "organization_id",
36
+ "input_data_set_id",
37
+ "project_id",
38
+ "input_data_id",
39
+ "input_data_name",
40
+ "input_data_path",
41
+ "url",
42
+ "etag",
43
+ "updated_datetime",
44
+ "sign_required",
45
+ ]
46
+
47
+ if output_format == OutputFormat.CSV:
48
+ if len(input_data_list) > 0:
49
+ # pandas.DataFrameでなくpandas.json_normalizeを使う理由:
50
+ # ネストしたオブジェクトを`system_metadata.input_duration`のような列名でアクセスできるようにするため
51
+ df = pandas.json_normalize(input_data_list)
52
+
53
+ # system_metadata.*列とmetadata.*列を検出して優先列リストに追加
54
+ # 順序: input_data_prior_columns → system_metadata.* → metadata.*
55
+ system_metadata_columns = sorted([col for col in df.columns if col.startswith("system_metadata.")])
56
+ metadata_columns = sorted([col for col in df.columns if col.startswith("metadata.")])
57
+ prior_columns_with_metadata = input_data_prior_columns + system_metadata_columns + metadata_columns
58
+ columns = get_columns_with_priority(df, prior_columns=prior_columns_with_metadata)
59
+ print_csv(df[columns], output=output_file)
60
+ else:
61
+ df = pandas.DataFrame(columns=input_data_prior_columns)
62
+ print_csv(df, output=output_file)
63
+
64
+ elif output_format == OutputFormat.PRETTY_JSON:
65
+ print_json(input_data_list, is_pretty=True, output=output_file)
66
+
67
+ elif output_format == OutputFormat.JSON:
68
+ print_json(input_data_list, is_pretty=False, output=output_file)
69
+
70
+ elif output_format == OutputFormat.INPUT_DATA_ID_LIST:
71
+ input_data_id_list = [e["input_data_id"] for e in input_data_list]
72
+ print_id_list(input_data_id_list, output=output_file)
73
+ else:
74
+ raise ValueError(f"{output_format}は対応していないフォーマットです。")
75
+
76
+
19
77
  class AddingDetailsToInputData:
20
78
  """
21
79
  入力データに詳細情報を追加するためのクラス
@@ -173,17 +231,8 @@ class ListInputData(CommandLine):
173
231
  if len(input_data_list) == 10_000:
174
232
  logger.warning("入力データ一覧は10,000件で打ち切られている可能性があります。")
175
233
 
176
- output_format = FormatArgument(args.format)
177
- if len(input_data_list) > 0:
178
- if output_format == FormatArgument.CSV:
179
- # pandas.DataFrameでなくpandas.json_normalizeを使う理由:
180
- # ネストしたオブジェクトを`system_metadata.input_duration`のような列名でアクセスできるようにするため
181
- df = pandas.json_normalize(input_data_list)
182
- print_csv(df, output=args.output)
183
- else:
184
- print_according_to_format(input_data_list, format=output_format, output=args.output)
185
- else:
186
- logger.info("入力データの件数が0件のため、出力しません。")
234
+ output_format = OutputFormat(args.format)
235
+ print_input_data_list(input_data_list, output_format=output_format, output_file=args.output)
187
236
 
188
237
 
189
238
  def main(args: argparse.Namespace) -> None:
@@ -223,12 +272,12 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
223
272
 
224
273
  argument_parser.add_format(
225
274
  choices=[
226
- FormatArgument.CSV,
227
- FormatArgument.JSON,
228
- FormatArgument.PRETTY_JSON,
229
- FormatArgument.INPUT_DATA_ID_LIST,
275
+ OutputFormat.CSV,
276
+ OutputFormat.JSON,
277
+ OutputFormat.PRETTY_JSON,
278
+ OutputFormat.INPUT_DATA_ID_LIST,
230
279
  ],
231
- default=FormatArgument.CSV,
280
+ default=OutputFormat.CSV,
232
281
  )
233
282
  argument_parser.add_output()
234
283
 
@@ -4,7 +4,7 @@ from typing import Any
4
4
 
5
5
  import annofabcli.common.cli
6
6
  from annofabcli.common.cli import ArgumentParser, CommandLine, build_annofabapi_resource_and_login
7
- from annofabcli.common.enums import FormatArgument
7
+ from annofabcli.common.enums import OutputFormat
8
8
  from annofabcli.common.facade import AnnofabApiFacade
9
9
  from annofabcli.common.visualize import AddProps
10
10
 
@@ -40,7 +40,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
40
40
 
41
41
  argument_parser.add_output()
42
42
 
43
- argument_parser.add_format(choices=[FormatArgument.CSV, FormatArgument.JSON, FormatArgument.PRETTY_JSON], default=FormatArgument.CSV)
43
+ argument_parser.add_format(choices=[OutputFormat.CSV, OutputFormat.JSON, OutputFormat.PRETTY_JSON], default=OutputFormat.CSV)
44
44
 
45
45
  parser.set_defaults(subcommand_func=main)
46
46
 
@@ -7,7 +7,7 @@ from annofabapi.models import ProjectJobInfo, ProjectJobType
7
7
 
8
8
  import annofabcli.common.cli
9
9
  from annofabcli.common.cli import ArgumentParser, CommandLine, build_annofabapi_resource_and_login
10
- from annofabcli.common.enums import FormatArgument
10
+ from annofabcli.common.enums import OutputFormat
11
11
  from annofabcli.common.facade import AnnofabApiFacade
12
12
 
13
13
  logger = logging.getLogger(__name__)
@@ -77,7 +77,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
77
77
  help="ジョブタイプを指定します。指定できる値については https://annofab-cli.readthedocs.io/ja/latest/user_guide/command_line_options.html#job-type を参照してください。",
78
78
  )
79
79
 
80
- argument_parser.add_format(choices=[FormatArgument.CSV, FormatArgument.JSON, FormatArgument.PRETTY_JSON], default=FormatArgument.CSV)
80
+ argument_parser.add_format(choices=[OutputFormat.CSV, OutputFormat.JSON, OutputFormat.PRETTY_JSON], default=OutputFormat.CSV)
81
81
  argument_parser.add_output()
82
82
 
83
83
  parser.set_defaults(subcommand_func=main)
@@ -12,7 +12,7 @@ from annofabcli.common.cli import (
12
12
  CommandLine,
13
13
  build_annofabapi_resource_and_login,
14
14
  )
15
- from annofabcli.common.enums import FormatArgument
15
+ from annofabcli.common.enums import OutputFormat
16
16
  from annofabcli.common.facade import AnnofabApiFacade
17
17
 
18
18
  logger = logging.getLogger(__name__)
@@ -157,7 +157,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
157
157
  help="プロジェクトに関する詳細情報を表示します( ``task_last_updated_datetime, annotation_specs_last_updated_datetime`` )",
158
158
  )
159
159
 
160
- argument_parser.add_format(choices=[FormatArgument.CSV, FormatArgument.JSON, FormatArgument.PRETTY_JSON], default=FormatArgument.CSV)
160
+ argument_parser.add_format(choices=[OutputFormat.CSV, OutputFormat.JSON, OutputFormat.PRETTY_JSON], default=OutputFormat.CSV)
161
161
  argument_parser.add_output()
162
162
 
163
163
  parser.set_defaults(subcommand_func=main)
@@ -7,7 +7,7 @@ import annofabcli.common.cli
7
7
  from annofabcli.common.cli import (
8
8
  ArgumentParser,
9
9
  CommandLine,
10
- FormatArgument,
10
+ OutputFormat,
11
11
  build_annofabapi_resource_and_login,
12
12
  )
13
13
  from annofabcli.common.facade import AnnofabApiFacade
@@ -32,10 +32,10 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
32
32
 
33
33
  argument_parser.add_format(
34
34
  choices=[
35
- FormatArgument.JSON,
36
- FormatArgument.PRETTY_JSON,
35
+ OutputFormat.JSON,
36
+ OutputFormat.PRETTY_JSON,
37
37
  ],
38
- default=FormatArgument.PRETTY_JSON,
38
+ default=OutputFormat.PRETTY_JSON,
39
39
  )
40
40
 
41
41
  argument_parser.add_output()