annofabcli 1.98.0__tar.gz → 1.100.0__tar.gz

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 (212) hide show
  1. {annofabcli-1.98.0 → annofabcli-1.100.0}/PKG-INFO +1 -1
  2. annofabcli-1.100.0/annofabcli/__version__.py +1 -0
  3. annofabcli-1.100.0/annofabcli/annotation_specs/add_attribute_restriction.py +158 -0
  4. annofabcli-1.98.0/annofabcli/annotation_specs/list_attribute_restriction.py → annofabcli-1.100.0/annofabcli/annotation_specs/attribute_restriction.py +44 -154
  5. annofabcli-1.100.0/annofabcli/annotation_specs/list_attribute_restriction.py +149 -0
  6. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation_specs/put_label_color.py +5 -0
  7. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation_specs/subcommand_annotation_specs.py +2 -0
  8. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/comment/delete_comment.py +3 -0
  9. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/comment/put_inspection_comment.py +3 -0
  10. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/comment/put_onhold_comment.py +3 -0
  11. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/input_data/change_input_data_name.py +4 -1
  12. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/input_data/put_input_data.py +4 -0
  13. annofabcli-1.100.0/annofabcli/statistics/list_annotation_attribute_filled_count.py +684 -0
  14. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/list_annotation_count.py +80 -37
  15. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/list_annotation_duration.py +18 -18
  16. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/subcommand_statistics.py +3 -0
  17. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/list_tasks_added_task_history.py +141 -156
  18. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/put_tasks.py +9 -4
  19. {annofabcli-1.98.0 → annofabcli-1.100.0}/pyproject.toml +1 -1
  20. annofabcli-1.98.0/annofabcli/__version__.py +0 -1
  21. {annofabcli-1.98.0 → annofabcli-1.100.0}/LICENSE +0 -0
  22. {annofabcli-1.98.0 → annofabcli-1.100.0}/README.md +0 -0
  23. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/__init__.py +0 -0
  24. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/__main__.py +0 -0
  25. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation/__init__.py +0 -0
  26. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation/annotation_query.py +0 -0
  27. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation/change_annotation_attributes.py +0 -0
  28. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation/change_annotation_properties.py +0 -0
  29. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation/copy_annotation.py +0 -0
  30. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation/delete_annotation.py +0 -0
  31. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation/download_annotation_zip.py +0 -0
  32. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation/dump_annotation.py +0 -0
  33. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation/import_annotation.py +0 -0
  34. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation/list_annotation.py +0 -0
  35. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation/list_annotation_count.py +0 -0
  36. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation/merge_segmentation.py +0 -0
  37. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation/remove_segmentation_overlap.py +0 -0
  38. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation/restore_annotation.py +0 -0
  39. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation/subcommand_annotation.py +0 -0
  40. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation_specs/__init__.py +0 -0
  41. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation_specs/export_annotation_specs.py +0 -0
  42. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation_specs/get_annotation_specs_with_attribute_id_replaced.py +0 -0
  43. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation_specs/get_annotation_specs_with_choice_id_replaced.py +0 -0
  44. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation_specs/get_annotation_specs_with_label_id_replaced.py +0 -0
  45. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation_specs/list_annotation_specs_attribute.py +0 -0
  46. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation_specs/list_annotation_specs_choice.py +0 -0
  47. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation_specs/list_annotation_specs_history.py +0 -0
  48. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation_specs/list_annotation_specs_label.py +0 -0
  49. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/annotation_specs/list_label_color.py +0 -0
  50. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/comment/__init__.py +0 -0
  51. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/comment/download_comment_json.py +0 -0
  52. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/comment/list_all_comment.py +0 -0
  53. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/comment/list_comment.py +0 -0
  54. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/comment/put_comment.py +0 -0
  55. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/comment/put_comment_simply.py +0 -0
  56. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/comment/put_inspection_comment_simply.py +0 -0
  57. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/comment/put_onhold_comment_simply.py +0 -0
  58. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/comment/subcommand_comment.py +0 -0
  59. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/comment/utils.py +0 -0
  60. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/common/__init__.py +0 -0
  61. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/common/annofab/__init__.py +0 -0
  62. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/common/annofab/project.py +0 -0
  63. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/common/bokeh.py +0 -0
  64. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/common/cli.py +0 -0
  65. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/common/dataclasses.py +0 -0
  66. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/common/download.py +0 -0
  67. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/common/enums.py +0 -0
  68. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/common/exceptions.py +0 -0
  69. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/common/facade.py +0 -0
  70. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/common/image.py +0 -0
  71. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/common/pandas.py +0 -0
  72. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/common/type_util.py +0 -0
  73. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/common/typing.py +0 -0
  74. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/common/utils.py +0 -0
  75. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/common/visualize.py +0 -0
  76. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/data/logging.yaml +0 -0
  77. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/experimental/__init__.py +0 -0
  78. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/experimental/list_out_of_range_annotation_for_movie.py +0 -0
  79. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/experimental/subcommand_experimental.py +0 -0
  80. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/filesystem/__init__.py +0 -0
  81. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/filesystem/draw_annotation.py +0 -0
  82. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/filesystem/filter_annotation.py +0 -0
  83. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/filesystem/mask_user_info.py +0 -0
  84. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/filesystem/merge_annotation.py +0 -0
  85. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/filesystem/subcommand_filesystem.py +0 -0
  86. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/input_data/__init__.py +0 -0
  87. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/input_data/copy_input_data.py +0 -0
  88. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/input_data/delete_input_data.py +0 -0
  89. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/input_data/delete_metadata_key_of_input_data.py +0 -0
  90. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/input_data/download_input_data_json.py +0 -0
  91. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/input_data/list_all_input_data.py +0 -0
  92. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/input_data/list_all_input_data_merged_task.py +0 -0
  93. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/input_data/list_input_data.py +0 -0
  94. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/input_data/put_input_data_with_zip.py +0 -0
  95. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/input_data/subcommand_input_data.py +0 -0
  96. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/input_data/update_metadata_of_input_data.py +0 -0
  97. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/input_data/utils.py +0 -0
  98. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/instruction/__init__.py +0 -0
  99. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/instruction/copy_instruction.py +0 -0
  100. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/instruction/download_instruction.py +0 -0
  101. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/instruction/list_instruction_history.py +0 -0
  102. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/instruction/subcommand_instruction.py +0 -0
  103. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/instruction/upload_instruction.py +0 -0
  104. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/job/__init__.py +0 -0
  105. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/job/delete_job.py +0 -0
  106. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/job/list_job.py +0 -0
  107. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/job/list_last_job.py +0 -0
  108. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/job/subcommand_job.py +0 -0
  109. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/job/wait_job.py +0 -0
  110. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/my_account/__init__.py +0 -0
  111. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/my_account/get_my_account.py +0 -0
  112. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/my_account/subcommand_my_account.py +0 -0
  113. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/organization/__init__.py +0 -0
  114. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/organization/list_organization.py +0 -0
  115. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/organization/subcommand_organization.py +0 -0
  116. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/organization_member/__init__.py +0 -0
  117. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/organization_member/change_organization_member.py +0 -0
  118. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/organization_member/delete_organization_member.py +0 -0
  119. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/organization_member/invite_organization_member.py +0 -0
  120. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/organization_member/list_organization_member.py +0 -0
  121. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/organization_member/subcommand_organization_member.py +0 -0
  122. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/project/__init__.py +0 -0
  123. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/project/change_project_status.py +0 -0
  124. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/project/copy_project.py +0 -0
  125. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/project/diff_projects.py +0 -0
  126. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/project/list_project.py +0 -0
  127. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/project/put_project.py +0 -0
  128. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/project/subcommand_project.py +0 -0
  129. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/project_member/__init__.py +0 -0
  130. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/project_member/change_project_members.py +0 -0
  131. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/project_member/copy_project_members.py +0 -0
  132. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/project_member/drop_project_members.py +0 -0
  133. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/project_member/invite_project_members.py +0 -0
  134. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/project_member/list_users.py +0 -0
  135. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/project_member/put_project_members.py +0 -0
  136. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/project_member/subcommand_project_member.py +0 -0
  137. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/py.typed +0 -0
  138. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/stat_visualization/__init__.py +0 -0
  139. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/stat_visualization/mask_visualization_dir.py +0 -0
  140. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/stat_visualization/merge_visualization_dir.py +0 -0
  141. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/stat_visualization/subcommand_stat_visualization.py +0 -0
  142. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/stat_visualization/summarize_whole_performance_csv.py +0 -0
  143. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/stat_visualization/write_graph.py +0 -0
  144. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/stat_visualization/write_performance_rating_csv.py +0 -0
  145. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/__init__.py +0 -0
  146. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/histogram.py +0 -0
  147. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/linegraph.py +0 -0
  148. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/list_annotation_attribute.py +0 -0
  149. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/list_video_duration.py +0 -0
  150. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/list_worktime.py +0 -0
  151. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/scatter.py +0 -0
  152. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/summarize_task_count.py +0 -0
  153. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/summarize_task_count_by_task_id_group.py +0 -0
  154. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/summarize_task_count_by_user.py +0 -0
  155. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/__init__.py +0 -0
  156. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/dataframe/__init__.py +0 -0
  157. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/dataframe/actual_worktime.py +0 -0
  158. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/dataframe/annotation_count.py +0 -0
  159. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/dataframe/cumulative_productivity.py +0 -0
  160. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/dataframe/custom_production_volume.py +0 -0
  161. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/dataframe/input_data_count.py +0 -0
  162. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/dataframe/inspection_comment_count.py +0 -0
  163. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/dataframe/productivity_per_date.py +0 -0
  164. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/dataframe/project_performance.py +0 -0
  165. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/dataframe/task.py +0 -0
  166. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/dataframe/task_history.py +0 -0
  167. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/dataframe/task_worktime_by_phase_user.py +0 -0
  168. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/dataframe/user.py +0 -0
  169. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/dataframe/user_performance.py +0 -0
  170. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/dataframe/whole_performance.py +0 -0
  171. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/dataframe/whole_productivity_per_date.py +0 -0
  172. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/dataframe/worktime_per_date.py +0 -0
  173. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/filtering_query.py +0 -0
  174. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/model.py +0 -0
  175. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/project_dir.py +0 -0
  176. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualization/visualization_source_files.py +0 -0
  177. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualize_annotation_count.py +0 -0
  178. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualize_annotation_duration.py +0 -0
  179. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualize_statistics.py +0 -0
  180. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/statistics/visualize_video_duration.py +0 -0
  181. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/supplementary/__init__.py +0 -0
  182. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/supplementary/delete_supplementary_data.py +0 -0
  183. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/supplementary/list_supplementary_data.py +0 -0
  184. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/supplementary/put_supplementary_data.py +0 -0
  185. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/supplementary/subcommand_supplementary.py +0 -0
  186. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/__init__.py +0 -0
  187. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/cancel_acceptance.py +0 -0
  188. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/change_operator.py +0 -0
  189. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/change_status_to_break.py +0 -0
  190. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/change_status_to_on_hold.py +0 -0
  191. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/complete_tasks.py +0 -0
  192. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/copy_tasks.py +0 -0
  193. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/delete_metadata_key_of_task.py +0 -0
  194. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/delete_tasks.py +0 -0
  195. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/download_task_json.py +0 -0
  196. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/list_all_tasks.py +0 -0
  197. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/list_all_tasks_added_task_history.py +0 -0
  198. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/list_tasks.py +0 -0
  199. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/put_tasks_by_count.py +0 -0
  200. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/reject_tasks.py +0 -0
  201. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/subcommand_task.py +0 -0
  202. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task/update_metadata_of_task.py +0 -0
  203. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task_history/__init__.py +0 -0
  204. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task_history/download_task_history_json.py +0 -0
  205. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task_history/list_all_task_history.py +0 -0
  206. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task_history/list_task_history.py +0 -0
  207. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task_history/subcommand_task_history.py +0 -0
  208. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task_history_event/__init__.py +0 -0
  209. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task_history_event/download_task_history_event_json.py +0 -0
  210. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task_history_event/list_all_task_history_event.py +0 -0
  211. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task_history_event/list_worktime.py +0 -0
  212. {annofabcli-1.98.0 → annofabcli-1.100.0}/annofabcli/task_history_event/subcommand_task_history_event.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: annofabcli
3
- Version: 1.98.0
3
+ Version: 1.100.0
4
4
  Summary: Utility Command Line Interface for AnnoFab
5
5
  Home-page: https://github.com/kurusugawa-computer/annofab-cli
6
6
  License: MIT
@@ -0,0 +1 @@
1
+ __version__ = "1.100.0" # `poetry-dynamic-versioning`を使ってGitHubのバージョンタグを取得している。変更不要
@@ -0,0 +1,158 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import copy
5
+ import json
6
+ import logging
7
+ import sys
8
+ from typing import Any, Optional
9
+
10
+ import annofabapi
11
+
12
+ import annofabcli
13
+ import annofabcli.common.cli
14
+ from annofabcli.annotation_specs.attribute_restriction import AttributeRestrictionMessage, OutputFormat
15
+ from annofabcli.common.cli import (
16
+ COMMAND_LINE_ERROR_STATUS_CODE,
17
+ CommandLine,
18
+ CommandLineWithConfirm,
19
+ build_annofabapi_resource_and_login,
20
+ get_json_from_args,
21
+ )
22
+ from annofabcli.common.facade import AnnofabApiFacade
23
+
24
+ logger = logging.getLogger(__name__)
25
+
26
+
27
+ def create_comment_from_restriction_text(restriction_text_list: list[str]) -> str:
28
+ """
29
+ 属性制約のテキストから、アノテーション仕様変更時のコメントを生成する
30
+ """
31
+ return "以下の属性制約を追加しました。\n" + "\n".join(restriction_text_list)
32
+
33
+
34
+ class AddAttributeRestrictionMain(CommandLineWithConfirm):
35
+ def __init__(
36
+ self,
37
+ service: annofabapi.Resource,
38
+ *,
39
+ project_id: str,
40
+ all_yes: bool,
41
+ ) -> None:
42
+ self.service = service
43
+ CommandLineWithConfirm.__init__(self, all_yes)
44
+ self.project_id = project_id
45
+
46
+ def add_restrictions(self, restrictions: list[dict[str, Any]], comment: Optional[str] = None) -> bool:
47
+ old_annotation_specs, _ = self.service.api.get_annotation_specs(self.project_id, query_params={"v": "3"})
48
+ old_restrictions = old_annotation_specs["restrictions"]
49
+
50
+ msg_obj = AttributeRestrictionMessage(
51
+ labels=old_annotation_specs["labels"],
52
+ additionals=old_annotation_specs["additionals"],
53
+ output_format=OutputFormat.TEXT,
54
+ raise_if_not_found=True,
55
+ )
56
+
57
+ new_restrictions = []
58
+ new_restriction_text_list = []
59
+ for index, restriction in enumerate(restrictions):
60
+ try:
61
+ restriction_text = msg_obj.get_restriction_text(restriction["additional_data_definition_id"], restriction["condition"])
62
+ except ValueError as e:
63
+ logger.warning(
64
+ f"{index + 1}件目 :: 次の属性制約は存在しないIDが含まれていたため、アノテーション仕様に追加しません。 :: "
65
+ f"restriction=`{restriction}`, error_message=`{e!s}`"
66
+ )
67
+ continue
68
+
69
+ if restriction in old_restrictions:
70
+ logger.warning(f"{index + 1}件目 :: 次の属性制約は既に存在するため、アノテーション仕様に追加しません。 :: `{restriction_text}`")
71
+ continue
72
+
73
+ if not self.confirm_processing(f"次の属性制約を追加しますか? :: `{restriction_text}`"):
74
+ continue
75
+
76
+ logger.debug(f"{index + 1}件目 :: 次の属性制約を追加します。 :: `{restriction_text}`")
77
+ new_restrictions.append(restriction)
78
+ new_restriction_text_list.append(restriction_text)
79
+
80
+ if len(new_restrictions) == 0:
81
+ logger.info("追加する属性制約はないため、アノテーション仕様を変更しません。")
82
+ return False
83
+
84
+ if not self.confirm_processing(f"{len(new_restrictions)} 件の属性制約を追加して、アノテーション仕様を変更します。よろしいですか? "):
85
+ return False
86
+
87
+ request_body = copy.deepcopy(old_annotation_specs)
88
+ request_body["restrictions"].extend(restrictions)
89
+ if comment is None:
90
+ comment = create_comment_from_restriction_text(new_restriction_text_list)
91
+ request_body["comment"] = comment
92
+ request_body["last_updated_datetime"] = old_annotation_specs["updated_datetime"]
93
+ self.service.api.put_annotation_specs(self.project_id, query_params={"v": "3"}, request_body=request_body)
94
+ logger.info(f"{len(new_restrictions)} 件の属性制約をアノテーション仕様に追加しました。")
95
+ return True
96
+
97
+
98
+ class AddAttributeRestriction(CommandLine):
99
+ COMMON_MESSAGE = "annofabcli annotation_specs add_restriction: error:"
100
+
101
+ def get_history_id_from_before_index(self, project_id: str, before: int) -> Optional[str]:
102
+ histories, _ = self.service.api.get_annotation_specs_histories(project_id)
103
+ if before + 1 > len(histories):
104
+ logger.warning(f"アノテーション仕様の履歴は{len(histories)}個のため、最新より{before}個前のアノテーション仕様は見つかりませんでした。")
105
+ return None
106
+ history = histories[-(before + 1)]
107
+ return history["history_id"]
108
+
109
+ def main(self) -> None:
110
+ args = self.args
111
+
112
+ restrictions = get_json_from_args(args.json)
113
+ if not isinstance(restrictions, list):
114
+ print(f"{self.COMMON_MESSAGE}: error: JSON形式が不正です。オブジェクトの配列を指定してください。", file=sys.stderr) # noqa: T201
115
+ sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
116
+
117
+ obj = AddAttributeRestrictionMain(self.service, project_id=args.project_id, all_yes=args.yes)
118
+ obj.add_restrictions(restrictions, comment=args.comment)
119
+
120
+
121
+ def parse_args(parser: argparse.ArgumentParser) -> None:
122
+ parser.add_argument("-p", "--project_id", help="対象のプロジェクトのproject_idを指定します。", required=True)
123
+
124
+ sample_json = [
125
+ {
126
+ "additional_data_definition_id": "a1",
127
+ "condition": {"value": "true", "_type": "Equals"},
128
+ }
129
+ ]
130
+ parser.add_argument(
131
+ "--json",
132
+ type=str,
133
+ required=True,
134
+ help="追加する属性の制約情報のJSONを指定します。"
135
+ "JSON形式は ... を参照してください。\n"
136
+ f"(例) ``{json.dumps(sample_json)}``\n"
137
+ "``file://`` を先頭に付けるとjsonファイルを指定できます。",
138
+ )
139
+
140
+ parser.add_argument("--comment", type=str, help="アノテーション仕様の変更時に指定できるコメント。未指定の場合、自動でコメントが生成されます。")
141
+
142
+ parser.set_defaults(subcommand_func=main)
143
+
144
+
145
+ def main(args: argparse.Namespace) -> None:
146
+ service = build_annofabapi_resource_and_login(args)
147
+ facade = AnnofabApiFacade(service)
148
+ AddAttributeRestriction(service, facade, args).main()
149
+
150
+
151
+ def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
152
+ subcommand_name = "add_attribute_restriction"
153
+
154
+ subcommand_help = "アノテーション仕様に属性の制約を追加します。"
155
+ description = subcommand_help + "アノテーション仕様画面では設定できない「属性間の制約」を追加するときに有用です。"
156
+ parser = annofabcli.common.cli.add_parser(subparsers, subcommand_name, subcommand_help, description=description)
157
+ parse_args(parser)
158
+ return parser
@@ -1,31 +1,16 @@
1
- from __future__ import annotations
2
-
3
- import argparse
4
- import json
5
1
  import logging
6
- import sys
7
2
  from collections.abc import Collection
8
3
  from enum import Enum
9
- from pathlib import Path
10
4
  from typing import Any, Optional
11
5
 
12
6
  from more_itertools import first_true
13
7
 
14
- import annofabcli
15
- import annofabcli.common.cli
16
- from annofabcli.common.cli import (
17
- COMMAND_LINE_ERROR_STATUS_CODE,
18
- ArgumentParser,
19
- CommandLine,
20
- build_annofabapi_resource_and_login,
21
- get_list_from_args,
22
- )
23
8
  from annofabcli.common.facade import AnnofabApiFacade
24
9
 
25
10
  logger = logging.getLogger(__name__)
26
11
 
27
12
 
28
- class FormatArgument(Enum):
13
+ class OutputFormat(Enum):
29
14
  """
30
15
  表示するフォーマット ``--format`` で指定できる値
31
16
 
@@ -38,13 +23,17 @@ class FormatArgument(Enum):
38
23
  DETAILED_TEXT = "detailed_text"
39
24
 
40
25
 
41
- class ListAttributeRestrictionMain:
26
+ class AttributeRestrictionMessage:
42
27
  """
43
- アノテーション仕様の制約から自然言語で書かれたメッセージを生成します。
28
+ アノテーション仕様の属性制約情報から、自然言語で書かれたメッセージを生成する
44
29
 
45
30
  Args:
46
31
  labels: アノテーション仕様のラベル情報
47
32
  additionals: アノテーション仕様の属性情報
33
+ raise_if_not_found: 属性やラベルが見つからなかった場合に例外を発生させるかどうか
34
+ format: 属性制約の表示フォーマット
35
+ - `text`: 属性IDを隠したシンプルなテキスト
36
+ - `detailed_text`: 属性IDなどの詳細情報を表示したテキスト
48
37
 
49
38
  """
50
39
 
@@ -52,20 +41,29 @@ class ListAttributeRestrictionMain:
52
41
  self,
53
42
  labels: list[dict[str, Any]],
54
43
  additionals: list[dict[str, Any]],
55
- format: FormatArgument = FormatArgument.DETAILED_TEXT, # noqa: A002 # pylint: disable=redefined-builtin
44
+ *,
45
+ raise_if_not_found: bool = False,
46
+ output_format: OutputFormat = OutputFormat.DETAILED_TEXT, # pylint: disable=redefined-builtin
56
47
  ) -> None:
57
48
  self.attribute_dict = {e["additional_data_definition_id"]: e for e in additionals}
58
49
  self.label_dict = {e["label_id"]: e for e in labels}
59
- self.format = format
50
+ self.output_format = output_format
51
+ self.raise_if_not_found = raise_if_not_found
60
52
 
61
53
  def get_labels_text(self, label_ids: Collection[str]) -> str:
62
54
  label_message_list = []
63
55
  for label_id in label_ids:
64
56
  label = self.label_dict.get(label_id)
65
- label_name = AnnofabApiFacade.get_label_name_en(label) if label is not None else ""
57
+ if label is not None:
58
+ label_name = AnnofabApiFacade.get_label_name_en(label)
59
+ else:
60
+ logger.warning(f"ラベルIDが'{label_id}'であるラベルは存在しません。")
61
+ if self.raise_if_not_found:
62
+ raise ValueError(f"ラベルIDが'{label_id}'であるラベルは存在しません。")
63
+ label_name = ""
66
64
 
67
65
  label_message = f"'{label_name}'"
68
- if self.format == FormatArgument.DETAILED_TEXT:
66
+ if self.output_format == OutputFormat.DETAILED_TEXT:
69
67
  label_message = f"{label_message} (id='{label_id}')"
70
68
  label_message_list.append(label_message)
71
69
 
@@ -89,11 +87,19 @@ class ListAttributeRestrictionMain:
89
87
  if choice is not None:
90
88
  choice_name = AnnofabApiFacade.get_choice_name_en(choice)
91
89
  tmp = f"'{value}'"
92
- if self.format == FormatArgument.DETAILED_TEXT:
90
+ if self.output_format == OutputFormat.DETAILED_TEXT:
93
91
  tmp = f"{tmp} (name='{choice_name}')"
94
92
  return tmp
95
93
 
96
94
  else:
95
+ message = (
96
+ f"選択肢IDが'{value}'である選択肢は存在しません。 :: "
97
+ f"属性名='{AnnofabApiFacade.get_additional_data_definition_name_en(attribute)}', "
98
+ f"属性ID='{attribute['additional_data_definition_id']}'"
99
+ )
100
+ logger.warning(message)
101
+ if self.raise_if_not_found:
102
+ raise ValueError(message)
97
103
  return f"'{value}'"
98
104
  else:
99
105
  return f"'{value}'"
@@ -120,12 +126,15 @@ class ListAttributeRestrictionMain:
120
126
  attribute = self.attribute_dict.get(attribute_id)
121
127
  if attribute is not None:
122
128
  subject = f"'{AnnofabApiFacade.get_additional_data_definition_name_en(attribute)}'"
123
- if self.format == FormatArgument.DETAILED_TEXT:
129
+ if self.output_format == OutputFormat.DETAILED_TEXT:
124
130
  subject = f"{subject} (id='{attribute_id}', type='{attribute['type']}')"
125
131
  else:
126
- logger.warning(f"属性IDが'{attribute_id}'の属性は存在しません。")
132
+ logger.warning(f"属性IDが'{attribute_id}'である属性は存在しません。")
133
+ if self.raise_if_not_found:
134
+ raise ValueError(f"属性IDが'{attribute_id}'である属性は存在しません。")
135
+
127
136
  subject = "''"
128
- if self.format == FormatArgument.DETAILED_TEXT:
137
+ if self.output_format == OutputFormat.DETAILED_TEXT:
129
138
  subject = f"{subject} (id='{attribute_id}')"
130
139
 
131
140
  if str_type == "CanInput":
@@ -152,7 +161,7 @@ class ListAttributeRestrictionMain:
152
161
  verb = "DOES NOT MATCH"
153
162
  str_object = f"'{condition['value']}'"
154
163
  else:
155
- raise RuntimeError(f"{str_type=}はサポートしていません。")
164
+ raise ValueError(f"condition._type='{str_type}'はサポートしていません。")
156
165
 
157
166
  tmp = f"{subject} {verb}"
158
167
  if str_object != "":
@@ -212,6 +221,14 @@ class ListAttributeRestrictionMain:
212
221
  target_attribute_names: Optional[Collection[str]] = None,
213
222
  target_label_names: Optional[Collection[str]] = None,
214
223
  ) -> list[str]:
224
+ """
225
+ 複数の属性制約から自然言語で記載されたメッセージのlistを返します。
226
+
227
+ Args:
228
+ restrictions: 属性制約のリスト
229
+ target_attribute_names: 取得対象のラベル名(英語)のlist
230
+ target_label_names: 取得対象の属性名(英語)のlist
231
+ """
215
232
  if target_attribute_names is not None or target_label_names is not None:
216
233
  target_attribute_ids = self.get_target_attribute_ids(target_attribute_names=target_attribute_names, target_label_names=target_label_names)
217
234
  return [
@@ -221,130 +238,3 @@ class ListAttributeRestrictionMain:
221
238
  ]
222
239
  else:
223
240
  return [self.get_restriction_text(e["additional_data_definition_id"], e["condition"]) for e in restrictions]
224
-
225
-
226
- class ListAttributeRestriction(CommandLine):
227
- COMMON_MESSAGE = "annofabcli annotation_specs list_restriction: error:"
228
-
229
- def get_history_id_from_before_index(self, project_id: str, before: int) -> Optional[str]:
230
- histories, _ = self.service.api.get_annotation_specs_histories(project_id)
231
- if before + 1 > len(histories):
232
- logger.warning(f"アノテーション仕様の履歴は{len(histories)}個のため、最新より{before}個前のアノテーション仕様は見つかりませんでした。")
233
- return None
234
- history = histories[-(before + 1)]
235
- return history["history_id"]
236
-
237
- def main(self) -> None:
238
- args = self.args
239
-
240
- if args.project_id is not None:
241
- history_id = None
242
- if args.history_id is not None:
243
- history_id = args.history_id
244
-
245
- if args.before is not None:
246
- history_id = self.get_history_id_from_before_index(args.project_id, args.before)
247
- if history_id is None:
248
- print( # noqa: T201
249
- f"{self.COMMON_MESSAGE} argument --before: 最新より{args.before}個前のアノテーション仕様は見つかりませんでした。",
250
- file=sys.stderr,
251
- )
252
- sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
253
-
254
- query_params = {"v": "3"}
255
- if history_id is not None:
256
- query_params["history_id"] = history_id
257
-
258
- annotation_specs, _ = self.service.api.get_annotation_specs(args.project_id, query_params=query_params)
259
- elif args.annotation_json_path is not None:
260
- with args.annotation_json_path.open() as f:
261
- annotation_specs = json.load(f)
262
-
263
- else:
264
- raise RuntimeError("'--project_id'か'--annotation_specs_json'のどちらかを指定する必要があります。")
265
-
266
- main_obj = ListAttributeRestrictionMain(
267
- labels=annotation_specs["labels"],
268
- additionals=annotation_specs["additionals"],
269
- format=FormatArgument(args.format),
270
- )
271
- target_attribute_names = get_list_from_args(args.attribute_name) if args.attribute_name is not None else None
272
- target_label_names = get_list_from_args(args.label_name) if args.label_name is not None else None
273
- restriction_text_list = main_obj.get_restriction_text_list(
274
- annotation_specs["restrictions"],
275
- target_attribute_names=target_attribute_names,
276
- target_label_names=target_label_names,
277
- )
278
-
279
- annofabcli.common.utils.output_string("\n".join(restriction_text_list), args.output)
280
-
281
-
282
- def parse_args(parser: argparse.ArgumentParser) -> None:
283
- argument_parser = ArgumentParser(parser)
284
-
285
- required_group = parser.add_mutually_exclusive_group(required=True)
286
- required_group.add_argument(
287
- "-p", "--project_id", help="対象のプロジェクトのproject_idを指定します。APIで取得したアノテーション仕様情報を元に出力します。"
288
- )
289
- required_group.add_argument(
290
- "--annotation_specs_json",
291
- type=Path,
292
- help="指定したアノテーション仕様のJSONファイルを指定します。"
293
- "JSONファイルに記載された情報を元に出力します。ただしアノテーション仕様の ``format_version`` は ``3`` である必要があります。",
294
- )
295
-
296
- # 過去のアノテーション仕様を参照するためのオプション
297
- old_annotation_specs_group = parser.add_mutually_exclusive_group()
298
- old_annotation_specs_group.add_argument(
299
- "--history_id",
300
- type=str,
301
- help=(
302
- "出力したいアノテーション仕様のhistory_idを指定してください。 "
303
- "history_idは ``annotation_specs list_history`` コマンドで確認できます。 "
304
- "指定しない場合は、最新のアノテーション仕様が出力されます。 "
305
- ),
306
- )
307
-
308
- old_annotation_specs_group.add_argument(
309
- "--before",
310
- type=int,
311
- help=(
312
- "出力したい過去のアノテーション仕様が、最新よりいくつ前のアノテーション仕様であるかを指定してください。 "
313
- "たとえば ``1`` を指定した場合、最新より1個前のアノテーション仕様を出力します。 "
314
- "指定しない場合は、最新のアノテーション仕様が出力されます。 "
315
- ),
316
- )
317
-
318
- parser.add_argument("--attribute_name", type=str, nargs="+", help="指定した属性名(英語)の属性の制約を出力します。")
319
- parser.add_argument("--label_name", type=str, nargs="+", help="指定したラベル名(英語)のラベルに紐づく属性の制約を出力します。")
320
- argument_parser.add_output()
321
-
322
- parser.add_argument(
323
- "-f",
324
- "--format",
325
- type=str,
326
- choices=[e.value for e in FormatArgument],
327
- default=FormatArgument.TEXT.value,
328
- help=f"出力フォーマット\n"
329
- "\n"
330
- f"* {FormatArgument.TEXT.value}: 英語名のみ出力する形式\n"
331
- f"* {FormatArgument.DETAILED_TEXT.value}: 属性IDや属性種類などの詳細情報を出力する形式\n",
332
- )
333
-
334
- parser.set_defaults(subcommand_func=main)
335
-
336
-
337
- def main(args: argparse.Namespace) -> None:
338
- service = build_annofabapi_resource_and_login(args)
339
- facade = AnnofabApiFacade(service)
340
- ListAttributeRestriction(service, facade, args).main()
341
-
342
-
343
- def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
344
- subcommand_name = "list_attribute_restriction"
345
-
346
- subcommand_help = "アノテーション仕様の属性の制約情報を出力します。"
347
-
348
- parser = annofabcli.common.cli.add_parser(subparsers, subcommand_name, subcommand_help)
349
- parse_args(parser)
350
- return parser
@@ -0,0 +1,149 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import json
5
+ import logging
6
+ import sys
7
+ from pathlib import Path
8
+ from typing import Optional
9
+
10
+ import annofabcli
11
+ import annofabcli.common.cli
12
+ from annofabcli.annotation_specs.attribute_restriction import AttributeRestrictionMessage, OutputFormat
13
+ from annofabcli.common.cli import (
14
+ COMMAND_LINE_ERROR_STATUS_CODE,
15
+ ArgumentParser,
16
+ CommandLine,
17
+ build_annofabapi_resource_and_login,
18
+ get_list_from_args,
19
+ )
20
+ from annofabcli.common.facade import AnnofabApiFacade
21
+
22
+ logger = logging.getLogger(__name__)
23
+
24
+
25
+ class ListAttributeRestriction(CommandLine):
26
+ COMMON_MESSAGE = "annofabcli annotation_specs list_restriction: error:"
27
+
28
+ def get_history_id_from_before_index(self, project_id: str, before: int) -> Optional[str]:
29
+ histories, _ = self.service.api.get_annotation_specs_histories(project_id)
30
+ if before + 1 > len(histories):
31
+ logger.warning(f"アノテーション仕様の履歴は{len(histories)}個のため、最新より{before}個前のアノテーション仕様は見つかりませんでした。")
32
+ return None
33
+ history = histories[-(before + 1)]
34
+ return history["history_id"]
35
+
36
+ def main(self) -> None:
37
+ args = self.args
38
+
39
+ if args.project_id is not None:
40
+ history_id = None
41
+ if args.history_id is not None:
42
+ history_id = args.history_id
43
+
44
+ if args.before is not None:
45
+ history_id = self.get_history_id_from_before_index(args.project_id, args.before)
46
+ if history_id is None:
47
+ print( # noqa: T201
48
+ f"{self.COMMON_MESSAGE} argument --before: 最新より{args.before}個前のアノテーション仕様は見つかりませんでした。",
49
+ file=sys.stderr,
50
+ )
51
+ sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
52
+
53
+ query_params = {"v": "3"}
54
+ if history_id is not None:
55
+ query_params["history_id"] = history_id
56
+
57
+ annotation_specs, _ = self.service.api.get_annotation_specs(args.project_id, query_params=query_params)
58
+ elif args.annotation_json_path is not None:
59
+ with args.annotation_json_path.open() as f:
60
+ annotation_specs = json.load(f)
61
+
62
+ else:
63
+ raise RuntimeError("'--project_id'か'--annotation_specs_json'のどちらかを指定する必要があります。")
64
+
65
+ main_obj = AttributeRestrictionMessage(
66
+ labels=annotation_specs["labels"],
67
+ additionals=annotation_specs["additionals"],
68
+ output_format=OutputFormat(args.format),
69
+ )
70
+ target_attribute_names = get_list_from_args(args.attribute_name) if args.attribute_name is not None else None
71
+ target_label_names = get_list_from_args(args.label_name) if args.label_name is not None else None
72
+ restriction_text_list = main_obj.get_restriction_text_list(
73
+ annotation_specs["restrictions"],
74
+ target_attribute_names=target_attribute_names,
75
+ target_label_names=target_label_names,
76
+ )
77
+
78
+ annofabcli.common.utils.output_string("\n".join(restriction_text_list), args.output)
79
+
80
+
81
+ def parse_args(parser: argparse.ArgumentParser) -> None:
82
+ argument_parser = ArgumentParser(parser)
83
+
84
+ required_group = parser.add_mutually_exclusive_group(required=True)
85
+ required_group.add_argument(
86
+ "-p", "--project_id", help="対象のプロジェクトのproject_idを指定します。APIで取得したアノテーション仕様情報を元に出力します。"
87
+ )
88
+ required_group.add_argument(
89
+ "--annotation_specs_json",
90
+ type=Path,
91
+ help="指定したアノテーション仕様のJSONファイルを指定します。"
92
+ "JSONファイルに記載された情報を元に出力します。ただしアノテーション仕様の ``format_version`` は ``3`` である必要があります。",
93
+ )
94
+
95
+ # 過去のアノテーション仕様を参照するためのオプション
96
+ old_annotation_specs_group = parser.add_mutually_exclusive_group()
97
+ old_annotation_specs_group.add_argument(
98
+ "--history_id",
99
+ type=str,
100
+ help=(
101
+ "出力したいアノテーション仕様のhistory_idを指定してください。 "
102
+ "history_idは ``annotation_specs list_history`` コマンドで確認できます。 "
103
+ "指定しない場合は、最新のアノテーション仕様が出力されます。 "
104
+ ),
105
+ )
106
+
107
+ old_annotation_specs_group.add_argument(
108
+ "--before",
109
+ type=int,
110
+ help=(
111
+ "出力したい過去のアノテーション仕様が、最新よりいくつ前のアノテーション仕様であるかを指定してください。 "
112
+ "たとえば ``1`` を指定した場合、最新より1個前のアノテーション仕様を出力します。 "
113
+ "指定しない場合は、最新のアノテーション仕様が出力されます。 "
114
+ ),
115
+ )
116
+
117
+ parser.add_argument("--attribute_name", type=str, nargs="+", help="指定した属性名(英語)の属性の制約を出力します。")
118
+ parser.add_argument("--label_name", type=str, nargs="+", help="指定したラベル名(英語)のラベルに紐づく属性の制約を出力します。")
119
+ argument_parser.add_output()
120
+
121
+ parser.add_argument(
122
+ "-f",
123
+ "--format",
124
+ type=str,
125
+ choices=[e.value for e in OutputFormat],
126
+ default=OutputFormat.TEXT.value,
127
+ help=f"出力フォーマット\n"
128
+ "\n"
129
+ f"* {OutputFormat.TEXT.value}: 英語名のみ出力する形式\n"
130
+ f"* {OutputFormat.DETAILED_TEXT.value}: 属性IDや属性種類などの詳細情報を出力する形式\n",
131
+ )
132
+
133
+ parser.set_defaults(subcommand_func=main)
134
+
135
+
136
+ def main(args: argparse.Namespace) -> None:
137
+ service = build_annofabapi_resource_and_login(args)
138
+ facade = AnnofabApiFacade(service)
139
+ ListAttributeRestriction(service, facade, args).main()
140
+
141
+
142
+ def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
143
+ subcommand_name = "list_attribute_restriction"
144
+
145
+ subcommand_help = "アノテーション仕様の属性の制約情報を出力します。"
146
+
147
+ parser = annofabcli.common.cli.add_parser(subparsers, subcommand_name, subcommand_help)
148
+ parse_args(parser)
149
+ return parser
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import argparse
4
4
  import logging
5
+ import sys
5
6
  from dataclasses import dataclass
6
7
  from typing import Any, Optional
7
8
 
@@ -10,6 +11,7 @@ import annofabapi
10
11
  import annofabcli
11
12
  import annofabcli.common.cli
12
13
  from annofabcli.common.cli import (
14
+ COMMAND_LINE_ERROR_STATUS_CODE,
13
15
  ArgumentParser,
14
16
  CommandLine,
15
17
  CommandLineWithConfirm,
@@ -100,6 +102,9 @@ class PutLabelColor(CommandLine):
100
102
  args = self.args
101
103
  label_color = get_json_from_args(args.json)
102
104
 
105
+ if not isinstance(label_color, dict):
106
+ print("annofabcli annotation_specs put_label_color: error: JSON形式が不正です。オブジェクトを指定してください。", file=sys.stderr) # noqa: T201
107
+ sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
103
108
  main_obj = PuttingLabelColorMain(service=self.service, project_id=args.project_id, all_yes=args.yes)
104
109
  main_obj.main(label_color, comment=args.comment)
105
110
 
@@ -2,6 +2,7 @@ import argparse
2
2
  from typing import Optional
3
3
 
4
4
  import annofabcli
5
+ import annofabcli.annotation_specs.add_attribute_restriction
5
6
  import annofabcli.annotation_specs.export_annotation_specs
6
7
  import annofabcli.annotation_specs.get_annotation_specs_with_attribute_id_replaced
7
8
  import annofabcli.annotation_specs.get_annotation_specs_with_choice_id_replaced
@@ -20,6 +21,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
20
21
  subparsers = parser.add_subparsers(dest="subcommand_name")
21
22
 
22
23
  # サブコマンドの定義
24
+ annofabcli.annotation_specs.add_attribute_restriction.add_parser(subparsers)
23
25
  annofabcli.annotation_specs.export_annotation_specs.add_parser(subparsers)
24
26
  annofabcli.annotation_specs.get_annotation_specs_with_attribute_id_replaced.add_parser(subparsers)
25
27
  annofabcli.annotation_specs.get_annotation_specs_with_choice_id_replaced.add_parser(subparsers)
@@ -225,6 +225,9 @@ class DeleteComment(CommandLine):
225
225
  super().validate_project(args.project_id, [ProjectMemberRole.ACCEPTER, ProjectMemberRole.OWNER])
226
226
 
227
227
  dict_comments = annofabcli.common.cli.get_json_from_args(args.json)
228
+ if not isinstance(dict_comments, dict):
229
+ print(f"{self.COMMON_MESSAGE} argument --json: JSON形式が不正です。オブジェクトを指定してください。", file=sys.stderr) # noqa: T201
230
+ sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
228
231
  main_obj = DeleteCommentMain(self.service, project_id=args.project_id, all_yes=self.all_yes)
229
232
  main_obj.delete_comments_for_task_list(
230
233
  comment_ids_for_task_list=dict_comments,
@@ -44,6 +44,9 @@ class PutInspectionComment(CommandLine):
44
44
  super().validate_project(args.project_id, [ProjectMemberRole.ACCEPTER, ProjectMemberRole.OWNER])
45
45
 
46
46
  dict_comments = annofabcli.common.cli.get_json_from_args(args.json)
47
+ if not isinstance(dict_comments, dict):
48
+ print(f"{self.COMMON_MESSAGE} argument --json: JSON形式が不正です。オブジェクトを指定してください。", file=sys.stderr) # noqa: T201
49
+ sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
47
50
  comments_for_task_list = convert_cli_comments(dict_comments, comment_type=CommentType.INSPECTION)
48
51
  main_obj = PutCommentMain(self.service, project_id=args.project_id, comment_type=CommentType.INSPECTION, all_yes=self.all_yes)
49
52
  main_obj.add_comments_for_task_list(
@@ -42,6 +42,9 @@ class PutInspectionComment(CommandLine):
42
42
  super().validate_project(args.project_id)
43
43
 
44
44
  dict_comments = annofabcli.common.cli.get_json_from_args(args.json)
45
+ if not isinstance(dict_comments, dict):
46
+ print(f"{self.COMMON_MESSAGE} argument --json: JSON形式が不正です。オブジェクトを指定してください。", file=sys.stderr) # noqa: T201
47
+ sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
45
48
  comments_for_task_list = convert_cli_comments(
46
49
  dict_comments,
47
50
  comment_type=CommentType.ONHOLD,