Source code for datumaro.cli.commands.require_project.modification.export

# Copyright (C) 2019-2021 Intel Corporation
#
# SPDX-License-Identifier: MIT

import argparse
import logging as log
import os
import os.path as osp

from datumaro.components.environment import DEFAULT_ENVIRONMENT
from datumaro.components.errors import ProjectNotFoundError
from datumaro.components.project import ProjectBuildTargets
from datumaro.util.os_util import make_file_name
from datumaro.util.scope import scope_add, scoped

from ....util import MultilineFormatter
from ....util.errors import CliException
from ....util.project import FilterModes, generate_next_file_name, load_project

__all__ = [
    "build_parser",
    "get_sensitive_args",
]


[docs] def build_parser(parser_ctor=argparse.ArgumentParser): builtins = sorted(DEFAULT_ENVIRONMENT.exporters) parser = parser_ctor( help="Export project", description=""" Exports a project in some format.|n |n Each dataset format has its own export options, which are passed after the '--' separator (see examples), pass '-- -h' for more info. If not stated otherwise, by default only annotations are exported, to include images pass '--save-media' parameter.|n |n A filter can be passed, check the 'filter' command description for more info.|n |n Formats:|n Datasets come in a wide variety of formats. Each dataset format defines its own data structure and rules on how to interpret the data. Check the user manual for the list of supported formats, examples and documentation. |n The list of supported formats can be extended by plugins. Check the "plugins" section of the developer guide for information about plugin implementation.|n |n List of builtin dataset formats: {}|n |n The command can only be applied to a project build target, a stage or the combined 'project' target, in which case all the targets will be affected. |n Examples:|n - Export project as a VOC-like dataset, include images:|n |s|s%(prog)s -f voc -- --save-media|n |n - Export project as a COCO-like dataset in other directory:|n |s|s%(prog)s -f coco -o path/I/like/ """.format( ", ".join(builtins) ), formatter_class=MultilineFormatter, ) parser.add_argument( "_positionals", nargs=argparse.REMAINDER, help=argparse.SUPPRESS ) # workaround for -- eaten by positionals parser.add_argument( "target", nargs="?", default="project", help="A project target to be exported (default: %(default)s)", ) parser.add_argument("-e", "--filter", help="XML XPath filter expression for dataset items") parser.add_argument( "--filter-mode", default=FilterModes.i.name, type=FilterModes.parse, help="Filter mode (options: %s; default: %s)" % (", ".join(FilterModes.list_options()), "%(default)s"), ) parser.add_argument( "-o", "--output-dir", dest="dst_dir", help="Directory to save output (default: a subdir in the current one)", ) parser.add_argument( "--overwrite", action="store_true", help="Overwrite existing files in the save directory" ) parser.add_argument( "-p", "--project", dest="project_dir", help="Directory of the project to operate on (default: current dir)", ) parser.add_argument("-f", "--format", required=True, help="Output format") parser.add_argument( "extra_args", nargs=argparse.REMAINDER, help="Additional arguments for exporter (pass '-- -h' for help). " "Must be specified after the main command arguments and after " "the '--' separator", ) parser.set_defaults(command=export_command) return parser
[docs] def get_sensitive_args(): return { export_command: ["dst_dir", "project_dir", "name", "extra_args", "target", "filter"], }
[docs] @scoped def export_command(args): has_sep = "--" in args._positionals if has_sep: pos = args._positionals.index("--") if 1 < pos: raise argparse.ArgumentError(None, message="Expected no more than 1 target argument") else: pos = 1 args.target = (args._positionals[:pos] or [ProjectBuildTargets.MAIN_TARGET])[0] args.extra_args = args._positionals[pos + has_sep :] show_plugin_help = "-h" in args.extra_args or "--help" in args.extra_args project = None try: project = scope_add(load_project(args.project_dir)) except ProjectNotFoundError: if not show_plugin_help: raise if project is not None: env = project.env else: env = DEFAULT_ENVIRONMENT try: exporter = env.exporters[args.format] except KeyError: raise CliException("Exporter for format '%s' is not found" % args.format) extra_args = exporter.parse_cmdline(args.extra_args) dst_dir = args.dst_dir if dst_dir: if not args.overwrite and osp.isdir(dst_dir) and os.listdir(dst_dir): raise CliException( "Directory '%s' already exists " "(pass --overwrite to overwrite)" % dst_dir ) else: dst_dir = generate_next_file_name("export-%s" % make_file_name(args.format)) dst_dir = osp.abspath(dst_dir) if args.filter: filter_args = FilterModes.make_filter_args(args.filter_mode) filter_expr = args.filter log.info("Loading the project...") dataset = project.working_tree.make_dataset(args.target) if args.filter: dataset.filter(filter_expr, **filter_args) log.info("Exporting...") dataset.export(save_dir=dst_dir, format=exporter, **extra_args) log.info("Results have been saved to '%s'" % dst_dir) return 0