diff --git a/cvat-cli/README.md b/cvat-cli/README.md index 7caa57da4591..aec0afdb9590 100644 --- a/cvat-cli/README.md +++ b/cvat-cli/README.md @@ -2,10 +2,52 @@ ## Installation -`pip install cvat-cli/` +`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] [--https] [--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) + --https force https connection (default: try to detect automatically) + --debug show debug output +``` + +## Examples + +Create a task with local images: + +```bash +cvat-cli --auth user create + --labels '[{"name": "car"}, {"name": "person"}]' + "test_task" + "local" + "image1.jpg" "image2.jpg" +``` + +List tasks on a custom server with auth: + +```bash +cvat-cli --auth admin:password \ + --server-host cvat.my.server.com --server-port 30123 \ + ls ``` diff --git a/cvat-cli/requirements/base.txt b/cvat-cli/requirements/base.txt index 453c18215ea3..d79417306820 100644 --- a/cvat-cli/requirements/base.txt +++ b/cvat-cli/requirements/base.txt @@ -1,2 +1,2 @@ -cvat-sdk==2.0 +cvat-sdk==2.0a1.* Pillow>=6.2.0 diff --git a/cvat-cli/src/cvat_cli/parser.py b/cvat-cli/src/cvat_cli/parser.py index 89e2088d56b0..8aebf5fccd08 100644 --- a/cvat-cli/src/cvat_cli/parser.py +++ b/cvat-cli/src/cvat_cli/parser.py @@ -72,7 +72,7 @@ def make_cmdline_parser() -> argparse.ArgumentParser: "--https", default=False, action="store_true", - help="using https connection (default: %(default)s)", + help="force https connection (default: try to detect automatically)", ) parser.add_argument( "--debug", diff --git a/cvat-cli/src/cvat_cli/version.py b/cvat-cli/src/cvat_cli/version.py index bb283134c22f..9342504bb8ac 100644 --- a/cvat-cli/src/cvat_cli/version.py +++ b/cvat-cli/src/cvat_cli/version.py @@ -1 +1 @@ -VERSION = "0.2-alpha" +VERSION = "2.0a1" diff --git a/cvat-sdk/.gitignore b/cvat-sdk/.gitignore index 523f19970e11..ab79e72d17ee 100644 --- a/cvat-sdk/.gitignore +++ b/cvat-sdk/.gitignore @@ -71,6 +71,7 @@ schema/ # Generated code cvat_sdk/api_client/ +cvat_sdk/version.py requirements/ docs/ setup.py diff --git a/cvat-sdk/cvat_sdk/version.py b/cvat-sdk/cvat_sdk/version.py deleted file mode 100644 index fd4b2fc4581f..000000000000 --- a/cvat-sdk/cvat_sdk/version.py +++ /dev/null @@ -1 +0,0 @@ -VERSION = "2.0-alpha" diff --git a/cvat-sdk/gen/generate.sh b/cvat-sdk/gen/generate.sh index 1dc44d96e4b0..91ff46468b06 100755 --- a/cvat-sdk/gen/generate.sh +++ b/cvat-sdk/gen/generate.sh @@ -8,7 +8,7 @@ set -e GENERATOR_VERSION="v6.0.1" -VERSION="2.0-alpha" +VERSION="2.0a1" LIB_NAME="cvat_sdk" LAYER1_LIB_NAME="${LIB_NAME}/api_client" DST_DIR="." diff --git a/cvat-sdk/gen/templates/openapi-generator/README.mustache b/cvat-sdk/gen/templates/openapi-generator/README.mustache new file mode 100644 index 000000000000..6e37baf11df8 --- /dev/null +++ b/cvat-sdk/gen/templates/openapi-generator/README.mustache @@ -0,0 +1,51 @@ +# {{{projectName}}} +{{#appDescriptionWithNewLines}} +{{{.}}} +{{/appDescriptionWithNewLines}} + +This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: + +- API version: {{appVersion}} +- Package version: {{packageVersion}} +{{^hideGenerationTimestamp}} +- Build date: {{generatedDate}} +{{/hideGenerationTimestamp}} +- Build package: {{generatorClass}} +{{#infoUrl}} +For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}}) +{{/infoUrl}} + +## Installation & Usage +### pip install + +If the python package is hosted on a repository, you can install directly using: + +```sh +pip install git+https://{{gitHost}}/{{{gitUserId}}}/{{{gitRepoId}}}.git +``` +(you may need to run `pip` with root permission: `sudo pip install git+https://{{gitHost}}/{{{gitUserId}}}/{{{gitRepoId}}}.git`) + +Then import the package: +```python +import {{{packageName}}} +``` + +### Setuptools + +Install via [Setuptools](http://pypi.python.org/pypi/setuptools). + +```sh +python setup.py install --user +``` +(or `sudo python setup.py install` to install the package for all users) + +Then import the package: +```python +import {{{packageName}}} +``` + +## Getting Started + +Please follow the [installation procedure](#installation--usage) and then run the following: + +{{> README_common }} diff --git a/cvat-sdk/gen/templates/openapi-generator/README_common.mustache b/cvat-sdk/gen/templates/openapi-generator/README_common.mustache new file mode 100644 index 000000000000..6515c8b62660 --- /dev/null +++ b/cvat-sdk/gen/templates/openapi-generator/README_common.mustache @@ -0,0 +1,176 @@ +API includes 2 layers: +- REST API wrappers (`ApiClient`). Located in at `cvat_sdk.api_client` +- high-level tools (`core`). Located at `cvat_sdk.core` + +### `ApiClient` (low level) + +This layer is useful if you need to work directly with REST API, but want +to have data validation and syntax assistance from your code editor. The code +on this layer is autogenerated. + +#### Example + +Let's see how a task with local files can be created. We will use the basic auth +to make things simpler. + +```python +from time import sleep +from cvat_sdk.api_client import Configuration, ApiClient, models, apis, exceptions + +configuration = Configuration( + host="{{{basePath}}}", + username='YOUR_USERNAME', + password='YOUR_PASSWORD', +) + +# Enter a context with an instance of the API client +with ApiClient(configuration) as api_client: + # Parameters can be passed as a plain dict with JSON-serialized data + # or as model objects (from cvat_sdk.api_client.models), including + # mixed variants. + # + # In case of dicts, keys must be the same as members of models.I + # interfaces and values must be convertible to the corresponding member + # value types (e.g. a date or string enum value can be parsed from a string). + # + # In case of model objects, data must be of the corresponding + # models. types. + # + # Let's use a dict here. It should look like models.ITaskWriteRequest + task_spec = { + 'name': 'example task', + "labels": [{ + "name": "car", + "color": "#ff00ff", + "attributes": [ + { + "name": "a", + "mutable": True, + "input_type": "number", + "default_value": "5", + "values": ["4", "5", "6"] + } + ] + }], + } + + try: + # Apis can be accessed as ApiClient class members + # We use different models for input and output data. For input data, + # models are typically called like "*Request". Output data models have + # no suffix. + (task, response) = api_client.tasks_api.create(task_spec) + except exceptions.ApiException as e: + # We can catch the basic exception type, or a derived type + print("Exception when trying to create a task: %s\n" % e) + + # Here we will use models instead of a dict + task_data = models.DataRequest( + image_quality=75, + start_frame=2, + stop_frame=5, + client_files=[ + open('image1.jpg', 'rb'), + open('image2.jpg', 'rb'), + ], + ) + + # If we pass binary file objects, we need to specify content type. + # For this endpoint, we don't have response data + (_, response) = api_client.tasks_api.create_data(task.id, + data_request=task_data, + _content_type="multipart/form-data", + + # we can choose to check the response status manually + # and disable the response data parsing + _check_status=False, _parse_response=False + ) + assert response.status == 202, response.msg + + # Wait till task data is processed + for _ in range(100): + (status, _) = api_client.tasks_api.retrieve_status(task.id) + if status.state.value in ['Finished', 'Failed']: + break + sleep(0.1) + assert status.state.value == 'Finished', status.message + + # Update the task object and check the task size + (task, _) = api_client.tasks_api.retrieve(task.id) + assert task.size == 4 +``` + +### `Core` (high-level) + +This layer provides high-level APIs, allowing easier access to server operations. +API includes *Repositories* and *Entities*. Repositories provide management +operations for Entitites. Entitites represent separate objects on the server +(e.g. tasks, jobs etc). + +#### Example + +```python +from cvat_sdk import make_client, models +from cvat_sdk.core.proxies.tasks import ResourceType, Task + +with make_client(host="{{{basePath}}}") as client: + # Authorize using the basic auth + client.login(('YOUR_USERNAME', 'YOUR_PASSWORD')) + + # Models are used the same way as in the layer 1 + task_spec = { + "name": "example task 2", + "labels": [ + { + "name": "car", + "color": "#ff00ff", + "attributes": [ + { + "name": "a", + "mutable": True, + "input_type": "number", + "default_value": "5", + "values": ["4", "5", "6"], + } + ], + } + ], + } + + # Different repositories can be accessed as the Client class members. + # They may provide both simple and complex operations, + # such as entity creation, retrieval and removal. + task = client.tasks.create_from_data( + spec=task_spec, + resource_type=ResourceType.LOCAL, + resources=['image1.jpg', 'image2.png'], + ) + + # Task object is already up-to-date with its server counterpart + assert task.size == 2 + + # An entity needs to be fetch()-ed to reflect the latest changes. + # It can be update()-d and remove()-d depending on the entity type. + task.update({'name': 'mytask'}) + task.remove() +``` + +## Documentation for API Endpoints + +All URIs are relative to *{{basePath}}* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | **{{operationId}}** | **{{httpMethod}}** {{path}} | {{summary}} +{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} + +## Documentation For Models + +{{#models}}{{#model}} - {{{classname}}} +{{/model}}{{/models}} + + +## Author + +{{#apiInfo}}{{#apis}}{{#-last}}{{infoEmail}} +{{/-last}}{{/apis}}{{/apiInfo}} diff --git a/cvat-sdk/gen/templates/requirements/base.txt b/cvat-sdk/gen/templates/requirements/base.txt index 695db0608508..f22bae3b6fe0 100644 --- a/cvat-sdk/gen/templates/requirements/base.txt +++ b/cvat-sdk/gen/templates/requirements/base.txt @@ -1,6 +1,7 @@ -r api_client.txt attrs >= 21.4.0 +Pillow >= 9.0.1 tqdm >= 4.64.0 tuspy == 0.2.5 # have it pinned, because SDK has lots of patched TUS code typing_extensions >= 4.2.0 diff --git a/tests/python/requirements.txt b/tests/python/requirements.txt index e949f2f5f19e..1d2098a100bb 100644 --- a/tests/python/requirements.txt +++ b/tests/python/requirements.txt @@ -1,4 +1,4 @@ -cvat-sdk==2.0 +cvat-sdk==2.0a1.* pytest==6.2.5 requests==2.26.0 deepdiff==5.6.0