Skip to content

Commit

Permalink
Merge pull request #8849 from cvat-ai/release-2.24.0
Browse files Browse the repository at this point in the history
Release v2.24.0
  • Loading branch information
cvat-bot[bot] authored Dec 20, 2024
2 parents e50cf53 + f3835c5 commit 9fafd98
Show file tree
Hide file tree
Showing 106 changed files with 2,628 additions and 1,305 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
- 'master'
- 'develop'
pull_request:
types: [ready_for_review, opened, synchronize, reopened]
types: [opened, synchronize, reopened]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ yarn-error.log*

# Ignore all the installed packages
node_modules
venv/
.venv/

# Ignore all js dists
cvat-data/dist
Expand Down
2 changes: 2 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,8 @@
"python": "${command:python.interpreterPath}",
"module": "pytest",
"args": [
"--verbose",
"--no-cov", // vscode debugger might not work otherwise
"tests/python/rest_api/"
],
"cwd": "${workspaceFolder}",
Expand Down
67 changes: 67 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,73 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

<!-- scriv-insert-here -->

<a id='changelog-2.24.0'></a>
## \[2.24.0\] - 2024-12-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>)

- Support for boolean parameters in annotations actions
(<https://github.com/cvat-ai/cvat/pull/8798>)

### Changed

- Improved uniformity of validation frames distribution in honeypot tasks and
random honeypot rerolls
(<https://github.com/cvat-ai/cvat/pull/8776>)

- \[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>)

- \[CLI\] The output of the `task create`, `task create-from-backup` and
`project create` commands is now just the created resource ID,
making it machine-readable
(<https://github.com/cvat-ai/cvat/pull/8833>)

- /api/events can now be used to receive events from several sources
(<https://github.com/cvat-ai/cvat/pull/8799>)

### 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>)

### Removed

- Automatic calculation of quality reports in tasks
(<https://github.com/cvat-ai/cvat/pull/8790>)

### Fixed

- Uploading a skeleton template in configurator does not work
(<https://github.com/cvat-ai/cvat/pull/8822>)

- Installation of YOLOv7 on GPU
(<https://github.com/cvat-ai/cvat/pull/8824>)

- \[Server API\] Significantly improved preformance of honeypot changes in tasks
(<https://github.com/cvat-ai/cvat/pull/8789>)
- \[Server API\] `PATCH tasks/id/validation_layout` responses now include correct
`disabled_frames` and handle simultaneous updates of
`disabled_frames` and honeypot frames correctly
(<https://github.com/cvat-ai/cvat/pull/8789>)

- Fixed handling of tracks keyframes from deleted frames on export
(<https://github.com/cvat-ai/cvat/pull/8834>)

- Exporting datasets could start significantly later than expected, both for 1
and several users in the same project/task/job (<https://github.com/cvat-ai/cvat/pull/8721>)
- Scheduled RQ jobs could not be restarted due to incorrect RQ job status
updating and handling (<https://github.com/cvat-ai/cvat/pull/8721>)

<a id='changelog-2.23.1'></a>
## \[2.23.1\] - 2024-12-09

Expand Down
73 changes: 38 additions & 35 deletions cvat-cli/README.md
Original file line number Diff line number Diff line change
@@ -1,57 +1,60 @@
# Command-line client for CVAT

A simple command line interface for working with CVAT tasks. At the moment it
A simple command line interface for working with CVAT. At the moment it
implements a basic feature set but may serve as the starting point for a more
comprehensive CVAT administration tool in the future.

Overview of functionality:
The following subcommands are supported:

- Create a new task (supports name, bug tracker, project, labels JSON, local/share/remote files)
- Delete tasks (supports deleting a list of task IDs)
- List all tasks (supports basic CSV or JSON output)
- Download JPEG frames (supports a list of frame IDs)
- Dump annotations (supports all formats via format string)
- Upload annotations for a task in the specified format (e.g. 'YOLO ZIP 1.0')
- Export and download a whole task
- Import a task
- Projects:
- `create` - create a new project
- `delete` - delete projects
- `ls` - list all projects

- Tasks:
- `create` - create a new task
- `create-from-backup` - create a task from a backup file
- `delete` - delete tasks
- `ls` - list all tasks
- `frames` - download frames from a task
- `export-dataset` - export a task as a dataset
- `import-dataset` - import annotations into a task from a dataset
- `backup` - back up a task
- `auto-annotate` - automatically annotate a task using a local function

## Installation

`pip install cvat-cli`

## Usage

```bash
$ cvat-cli --help

usage: cvat-cli [-h] [--version] [--auth USER:[PASS]]
[--server-host SERVER_HOST] [--server-port SERVER_PORT] [--debug]
{create,delete,ls,frames,dump,upload,export,import} ...

Perform common operations related to CVAT tasks.

positional arguments:
{create,delete,ls,frames,dump,upload,export,import}

optional arguments:
-h, --help show this help message and exit
--version show program's version number and exit
--auth USER:[PASS] defaults to the current user and supports the PASS
environment variable or password prompt
(default: current user)
--server-host SERVER_HOST
host (default: localhost)
--server-port SERVER_PORT
port (default: 8080)
--debug show debug output
The general form of a CLI command is:

```console
$ cvat-cli <common options> <resource> <action> <options>
```

where:

- `<common options>` are options shared between all subcommands;
- `<resource>` is a CVAT resource, such as `task`;
- `<action>` is the action to do with the resource, such as `create`;
- `<options>` is any options specific to a particular resource and action.

You can list available subcommands and options using the `--help` option:

```
$ cvat-cli --help # get help on available common options and resources
$ cvat-cli <resource> --help # get help on actions for the given resource
$ cvat-cli <resource> <action> --help # get help on action-specific options
```

## Examples

Create a task with local images:

```bash
cvat-cli --auth user create
cvat-cli --auth user task create
--labels '[{"name": "car"}, {"name": "person"}]'
"test_task"
"local"
Expand All @@ -63,5 +66,5 @@ List tasks on a custom server with auth:
```bash
cvat-cli --auth admin:password \
--server-host cvat.my.server.com --server-port 30123 \
ls
task ls
```
2 changes: 1 addition & 1 deletion cvat-cli/requirements/base.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
cvat-sdk~=2.23.1
cvat-sdk~=2.24.0
Pillow>=10.3.0
setuptools>=70.0.0 # not directly required, pinned by Snyk to avoid a vulnerability
2 changes: 1 addition & 1 deletion cvat-cli/src/cvat_cli/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import urllib3.exceptions
from cvat_sdk import exceptions

from ._internal.commands import COMMANDS
from ._internal.commands_all import COMMANDS
from ._internal.common import build_client, configure_common_arguments, configure_logger
from ._internal.utils import popattr

Expand Down
75 changes: 74 additions & 1 deletion cvat-cli/src/cvat_cli/_internal/command_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@
# SPDX-License-Identifier: MIT

import argparse
import json
import textwrap
import types
from collections.abc import Mapping
from abc import ABCMeta, abstractmethod
from collections.abc import Mapping, Sequence
from typing import Callable, Protocol

from cvat_sdk import Client


class Command(Protocol):
@property
Expand Down Expand Up @@ -51,3 +56,71 @@ def execute(self) -> None:
# It should be impossible for a command group to be executed,
# because configure_parser requires that a subcommand is specified.
assert False, "unreachable code"


class DeprecatedAlias:
def __init__(self, command: Command, replacement: str) -> None:
self._command = command
self._replacement = replacement

@property
def description(self) -> str:
return textwrap.dedent(
f"""\
{self._command.description}
(Deprecated; use "{self._replacement}" instead.)
"""
)

def configure_parser(self, parser: argparse.ArgumentParser) -> None:
self._command.configure_parser(parser)

def execute(self, client: Client, **kwargs) -> None:
client.logger.warning('This command is deprecated. Use "%s" instead.', self._replacement)
self._command.execute(client, **kwargs)


class GenericCommand(metaclass=ABCMeta):
@abstractmethod
def repo(self, client: Client): ...

@property
@abstractmethod
def resource_type_str(self) -> str: ...


class GenericListCommand(GenericCommand):
@property
def description(self) -> str:
return f"List all CVAT {self.resource_type_str}s in either basic or JSON format."

def configure_parser(self, parser: argparse.ArgumentParser) -> None:
parser.add_argument(
"--json",
dest="use_json_output",
default=False,
action="store_true",
help="output JSON data",
)

def execute(self, client: Client, *, use_json_output: bool = False):
results = self.repo(client).list(return_json=use_json_output)
if use_json_output:
print(json.dumps(json.loads(results), indent=2))
else:
for r in results:
print(r.id)


class GenericDeleteCommand(GenericCommand):
@property
def description(self):
return f"Delete a list of {self.resource_type_str}s, ignoring those which don't exist."

def configure_parser(self, parser: argparse.ArgumentParser) -> None:
parser.add_argument(
"ids", type=int, help=f"list of {self.resource_type_str} IDs", nargs="+"
)

def execute(self, client: Client, *, ids: Sequence[int]) -> None:
self.repo(client).remove_by_ids(ids)
27 changes: 27 additions & 0 deletions cvat-cli/src/cvat_cli/_internal/commands_all.py
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}"))
Loading

0 comments on commit 9fafd98

Please sign in to comment.