-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Currently, the CLI has one level of subcommands, and all subcommands work on tasks. This leaves no room for subcommands that work on other CVAT resources. This change redesigns the CLI interface by adding another level of subcommand hierarchy. Instead of running `cvat-cli <action>`, the user will now run `cvat-cli <resource> <action>`. Previously available commands are left available as deprecated aliases. As a proof of concept, this PR adds some basic project actions. I have also used this opportunity to correct some of the task action names, specifically `export`, `import`, `dump` and `upload`. These names don't correspond to either SDK function names, API endpoints, or UI labels corresponding to these actions. In the new subcommand hierarchy, I renamed those commands to `backup`, `create-from-backup`, `export-dataset` and `import-dataset`, which are more consistent with how other CVAT components call these actions. I rewrote the introduction and usage sections of the cli README and reference in order to reduce clutter and remove the need to resynchronize the help output after every interface change.
- Loading branch information
Showing
16 changed files
with
667 additions
and
304 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
### Added | ||
|
||
- \[CLI\] Added new commands: `project create`, `project delete`, `project ls` | ||
(<https://github.com/cvat-ai/cvat/pull/8787>) | ||
|
||
- \[SDK\] You can now use `client.projects.remove_by_ids` to remove multiple | ||
projects | ||
(<https://github.com/cvat-ai/cvat/pull/8787>) | ||
|
||
### Changed | ||
|
||
- \[CLI\] Switched to a new subcommand hierarchy; now CLI subcommands | ||
have the form `cvat-cli <resource> <action>` | ||
(<https://github.com/cvat-ai/cvat/pull/8787>) | ||
|
||
### Deprecated | ||
|
||
- \[CLI\] All existing CLI commands of the form `cvat-cli <action>` | ||
are now deprecated. Use `cvat-cli task <action>` instead | ||
(<https://github.com/cvat-ai/cvat/pull/8787>) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Copyright (C) 2024 CVAT.ai Corporation | ||
# | ||
# SPDX-License-Identifier: MIT | ||
|
||
from .command_base import CommandGroup, DeprecatedAlias | ||
from .commands_projects import COMMANDS as COMMANDS_PROJECTS | ||
from .commands_tasks import COMMANDS as COMMANDS_TASKS | ||
|
||
COMMANDS = CommandGroup(description="Perform operations on CVAT resources.") | ||
|
||
COMMANDS.add_command("project", COMMANDS_PROJECTS) | ||
COMMANDS.add_command("task", COMMANDS_TASKS) | ||
|
||
_legacy_mapping = { | ||
"create": "create", | ||
"ls": "ls", | ||
"delete": "delete", | ||
"frames": "frames", | ||
"dump": "export-dataset", | ||
"upload": "import-dataset", | ||
"export": "backup", | ||
"import": "create-from-backup", | ||
"auto-annotate": "auto-annotate", | ||
} | ||
|
||
for _legacy, _new in _legacy_mapping.items(): | ||
COMMANDS.add_command(_legacy, DeprecatedAlias(COMMANDS_TASKS.commands[_new], f"task {_new}")) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
# Copyright (C) 2024 CVAT.ai Corporation | ||
# | ||
# SPDX-License-Identifier: MIT | ||
|
||
import argparse | ||
import textwrap | ||
|
||
from cvat_sdk import Client, models | ||
|
||
from .command_base import CommandGroup, GenericCommand, GenericDeleteCommand, GenericListCommand | ||
from .parsers import parse_label_arg | ||
|
||
COMMANDS = CommandGroup(description="Perform operations on CVAT projects.") | ||
|
||
|
||
class GenericProjectCommand(GenericCommand): | ||
resource_type_str = "project" | ||
|
||
def repo(self, client: Client): | ||
return client.projects | ||
|
||
|
||
@COMMANDS.command_class("ls") | ||
class ProjectList(GenericListCommand, GenericProjectCommand): | ||
pass | ||
|
||
|
||
@COMMANDS.command_class("create") | ||
class ProjectCreate: | ||
description = textwrap.dedent( | ||
"""\ | ||
Create a new CVAT project, optionally importing a dataset. | ||
""" | ||
) | ||
|
||
def configure_parser(self, parser: argparse.ArgumentParser) -> None: | ||
parser.add_argument("name", type=str, help="name of the project") | ||
parser.add_argument( | ||
"--bug_tracker", "--bug", default=argparse.SUPPRESS, type=str, help="bug tracker URL" | ||
) | ||
parser.add_argument( | ||
"--labels", | ||
default=[], | ||
type=parse_label_arg, | ||
help="string or file containing JSON labels specification (default: %(default)s)", | ||
) | ||
parser.add_argument( | ||
"--dataset_path", | ||
default="", | ||
type=str, | ||
help="path to the dataset file to import", | ||
) | ||
parser.add_argument( | ||
"--dataset_format", | ||
default="CVAT 1.1", | ||
type=str, | ||
help="format of the dataset file being uploaded" | ||
" (only applies when --dataset_path is specified; default: %(default)s)", | ||
) | ||
parser.add_argument( | ||
"--completion_verification_period", | ||
dest="status_check_period", | ||
default=2, | ||
type=float, | ||
help="period between status checks" | ||
" (only applies when --dataset_path is specified; default: %(default)s)", | ||
) | ||
|
||
def execute( | ||
self, | ||
client: Client, | ||
*, | ||
name: str, | ||
labels: dict, | ||
dataset_path: str, | ||
dataset_format: str, | ||
status_check_period: int, | ||
**kwargs, | ||
) -> None: | ||
project = client.projects.create_from_dataset( | ||
spec=models.ProjectWriteRequest(name=name, labels=labels, **kwargs), | ||
dataset_path=dataset_path, | ||
dataset_format=dataset_format, | ||
status_check_period=status_check_period, | ||
) | ||
print(f"Created project ID {project.id}") | ||
|
||
|
||
@COMMANDS.command_class("delete") | ||
class ProjectDelete(GenericDeleteCommand, GenericProjectCommand): | ||
pass |
Oops, something went wrong.