Skip to content

Commit 1f8e1e7

Browse files
authored
Add a new CLI command: datum format (#1570)
### Summary - This PR resolves https://jira.devtools.intel.com/browse/CVS-144954 and #1545 - Add a new CLI command: `datum format`. It displays a list of data format names supported by Datumaro. It can be useful for quick reference of data format name used for other CLI command such as `datum convert -if <data-format> -f <data-format>`. ### How to test Added unit tests as well. ### Checklist <!-- Put an 'x' in all the boxes that apply --> - [x] I have added unit tests to cover my changes.​ - [ ] I have added integration tests to cover my changes.​ - [x] I have added the description of my changes into [CHANGELOG](https://github.com/openvinotoolkit/datumaro/blob/develop/CHANGELOG.md).​ - [x] I have updated the [documentation](https://github.com/openvinotoolkit/datumaro/tree/develop/docs) accordingly ### License - [x] I submit _my code changes_ under the same [MIT License](https://github.com/openvinotoolkit/datumaro/blob/develop/LICENSE) that covers the project. Feel free to contact the maintainers if that's a concern. - [x] I have updated the license header for each file (see an example below). ```python # Copyright (C) 2024 Intel Corporation # # SPDX-License-Identifier: MIT ``` --------- Signed-off-by: Kim, Vinnam <[email protected]>
1 parent 6ee3b2f commit 1f8e1e7

File tree

10 files changed

+194
-6
lines changed

10 files changed

+194
-6
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## \[unreleased\]
99
### New features
10+
- Add a new CLI command: datum format
11+
(<https://github.com/openvinotoolkit/datumaro/pull/1570>)
1012

1113
### Enhancements
1214

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Format
2+
3+
## List Supported Data Formats
4+
5+
This command shows a list of supported import/export data formats in Datumaro.
6+
It is useful on a quick reference of data format name used for other CLI command such as [convert](../context_free/convert.md), [import](../context/sources.md#import-dataset), or [export](../context/export.md#export-datasets). For more detailed guides on each data format, please visit [our Data Formats section](../../data-formats/formats/index.rst).
7+
8+
Usage:
9+
10+
```console
11+
usage: datum format [-h] [-li | -le] [-d DELIMITER]
12+
```
13+
14+
Parameters:
15+
- `-h, --help` - Print the help message and exit.
16+
- `-d DELIMITER, --delimiter DELIMITER` - Seperator used to list data format names (default: `\n`). For example, `datum format -d ','` command displays
17+
```console
18+
Supported import formats:
19+
ade20k2017,ade20k2020,align_celeba,...
20+
```
21+
- `-li, --list-import` - List all supported import data format names
22+
- `-le, --list-export` - List all supported export data format names
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
===============
2+
Helper Commands
3+
===============
4+
5+
.. toctree::
6+
:maxdepth: 1
7+
:glob:
8+
9+
*

docs/source/docs/command-reference/overview.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
Overview
33
========
44

5-
The command line is split into the separate ``commands`` (:ref:`Context Commands`)
6-
and command ``contexts`` (:ref:`Context-free Commands`).
5+
The command line is split into three groups:
6+
``commands`` (:ref:`Context Commands`), command ``contexts`` (:ref:`Context-free Commands`), and ``helpers`` (:ref:`Helper Commands`).
77
Contexts group multiple commands related to a specific topic, e.g.
88
project operations, data source operations etc. Almost all the commands
99
operate on projects, so the ``project`` context and commands without a context

docs/source/docs/explanation/command_line.dot

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ digraph command_line {
3232
"util";
3333
}
3434

35+
subgraph helper {
36+
label = "Helper";
37+
"format";
38+
}
39+
3540
subgraph cluster_model {
3641
label = "Model";
3742
"madd" [label = "add";];
@@ -70,7 +75,7 @@ digraph command_line {
7075
"split_video";
7176
}
7277

73-
"datum" -> {"convert" "detect" "compare" "dinfo" "download" "explain" "filter" "generate" "merge" "patch" "search" "stats" "transform" "validate"};
78+
"datum" -> {"convert" "detect" "compare" "dinfo" "download" "explain" "filter" "generate" "merge" "patch" "search" "stats" "transform" "validate" "format"};
7479
"datum" -> {"model" "project" "source" "util"};
7580
"model" -> {"madd" "mremove" "run" "minfo"};
7681
"project" -> {"add" "create" "export" "import" "remove"};

docs/source/docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Docs
4848
command-reference/overview
4949
command-reference/context_free/index
5050
command-reference/context/index
51+
command-reference/helper/index
5152

5253
.. toctree::
5354
:maxdepth: 1

src/datumaro/cli/__main__.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
send_command_success_info,
1717
)
1818
from ..version import __version__
19-
from . import contexts
19+
from . import contexts, helpers
2020
from .commands import get_non_project_commands, get_project_commands
2121
from .util import add_subparser, make_subcommands_help
2222
from .util.errors import CliException
@@ -80,9 +80,19 @@ def _get_known_contexts():
8080
]
8181

8282

83+
def _get_helper_commands():
84+
return [
85+
(
86+
"format",
87+
helpers.format,
88+
"List and show information about supported import/export data formats",
89+
),
90+
]
91+
92+
8393
def _get_sensitive_args():
8494
known_contexts = _get_known_contexts()
85-
known_commands = get_project_commands() + get_non_project_commands()
95+
known_commands = get_project_commands() + get_non_project_commands() + _get_helper_commands()
8696

8797
res = {}
8898
for _, command, _ in known_contexts + known_commands:
@@ -104,6 +114,7 @@ def make_parser():
104114

105115
known_contexts = _get_known_contexts()
106116
known_commands = get_non_project_commands()
117+
known_helpers = _get_helper_commands()
107118

108119
# Argparse doesn't support subparser groups:
109120
# https://stackoverflow.com/questions/32017020/grouping-argparse-subparser-arguments
@@ -118,6 +129,11 @@ def make_parser():
118129
subcommands_desc += "\n"
119130
subcommands_desc += "Context-free Commands:\n"
120131
subcommands_desc += make_subcommands_help(known_commands, help_line_start)
132+
if known_helpers:
133+
if subcommands_desc:
134+
subcommands_desc += "\n"
135+
subcommands_desc += "Helper Commands:\n"
136+
subcommands_desc += make_subcommands_help(known_helpers, help_line_start)
121137
if subcommands_desc:
122138
subcommands_desc += (
123139
"\nRun '%s COMMAND --help' for more information on a command." % parser.prog
@@ -126,7 +142,7 @@ def make_parser():
126142
subcommands = parser.add_subparsers(
127143
title=subcommands_desc, description="", help=argparse.SUPPRESS
128144
)
129-
for command_name, command, _ in known_contexts + known_commands:
145+
for command_name, command, _ in known_contexts + known_commands + known_helpers:
130146
if command is not None:
131147
add_subparser(subcommands, command_name, command.build_parser)
132148

src/datumaro/cli/helpers/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Copyright (C) 2024 Intel Corporation
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
from . import format

src/datumaro/cli/helpers/format.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Copyright (C) 2024 Intel Corporation
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
import argparse
6+
import os
7+
8+
from datumaro.cli.util import MultilineFormatter
9+
10+
11+
def build_parser(parser_ctor=argparse.ArgumentParser):
12+
parser = parser_ctor(
13+
help="List supported import/export data formats",
14+
description="""
15+
List supported import/export data format names.
16+
For more detailed guides on each data format,
17+
please visit our documentation website:
18+
https://openvinotoolkit.github.io/datumaro/stable/docs/data-formats/formats
19+
|n
20+
|n
21+
Examples:|n
22+
- List supported import/export data format names:|n
23+
|s|s%(prog)s|n
24+
|n
25+
- List only supported import data format names:|n
26+
|s|s%(prog)s --list-import|n
27+
|n
28+
- List only supported export data format names:|n
29+
|s|s%(prog)s --list-export|n
30+
|n
31+
- List with comma delimiter:|n
32+
|s|s%(prog)s --delimiter ','
33+
""",
34+
formatter_class=MultilineFormatter,
35+
)
36+
37+
group = parser.add_argument_group()
38+
exclusive_group = group.add_mutually_exclusive_group(required=False)
39+
40+
exclusive_group.add_argument(
41+
"-li",
42+
"--list-import",
43+
action="store_true",
44+
help="List all supported import data format names",
45+
)
46+
exclusive_group.add_argument(
47+
"-le",
48+
"--list-export",
49+
action="store_true",
50+
help="List all supported export data format names",
51+
)
52+
parser.add_argument(
53+
"-d",
54+
"--delimiter",
55+
type=str,
56+
default=os.linesep,
57+
help="Seperator used to list data format names (default: \\n)",
58+
)
59+
60+
parser.set_defaults(command=format_command)
61+
return parser
62+
63+
64+
def get_sensitive_args():
65+
return {
66+
format_command: ["list", "show"],
67+
}
68+
69+
70+
def format_command(args: argparse.Namespace) -> None:
71+
from datumaro.components.environment import DEFAULT_ENVIRONMENT
72+
73+
delimiter = args.delimiter
74+
75+
if args.list_import:
76+
builtin_readers = sorted(
77+
set(DEFAULT_ENVIRONMENT.importers) | set(DEFAULT_ENVIRONMENT.extractors)
78+
)
79+
print(delimiter.join(builtin_readers))
80+
return
81+
82+
if args.list_export:
83+
builtin_writers = sorted(DEFAULT_ENVIRONMENT.exporters)
84+
print(delimiter.join(builtin_writers))
85+
return
86+
87+
builtin_readers = sorted(
88+
set(DEFAULT_ENVIRONMENT.importers) | set(DEFAULT_ENVIRONMENT.extractors)
89+
)
90+
builtin_writers = sorted(DEFAULT_ENVIRONMENT.exporters)
91+
print(f"Supported import formats:\n{delimiter.join(builtin_readers)}")
92+
print(f"Supported export formats:\n{delimiter.join(builtin_writers)}")

tests/unit/cli/test_helper.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Copyright (C) 2024 Intel Corporation
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
from argparse import ArgumentParser, Namespace
6+
7+
import pytest
8+
9+
from datumaro.cli.helpers.format import build_parser, format_command
10+
11+
# from datumaro.cli.__main__ import make_parser
12+
13+
14+
class FormatTest:
15+
def test_build_parser(self):
16+
parser = build_parser(lambda help, **kwargs: ArgumentParser(**kwargs))
17+
assert isinstance(parser, ArgumentParser)
18+
19+
args = parser.parse_args(["--list-import"])
20+
assert args.list_import
21+
22+
args = parser.parse_args(["--list-export"])
23+
assert args.list_export
24+
25+
args = parser.parse_args(["--delimiter", ","])
26+
assert args.delimiter == ","
27+
28+
@pytest.mark.parametrize(
29+
"list_import,list_export", [(True, False), (False, True), (False, False)]
30+
)
31+
def test_format_command(
32+
self, list_import: bool, list_export: bool, capsys: pytest.CaptureFixture
33+
):
34+
format_command(Namespace(delimiter="\n", list_import=list_import, list_export=list_export))
35+
out, _ = capsys.readouterr()
36+
assert "coco" in out

0 commit comments

Comments
 (0)