From 3fee4cfcab389268b6ad6c2b54bb60f06fb38ba8 Mon Sep 17 00:00:00 2001 From: Eric Grinstein Date: Mon, 22 Jun 2020 10:49:59 -0300 Subject: [PATCH] Functionality to upload annotations on task creation (#1735) * Upload annotations on task creation * Bulk upload v1 * Not working * Annotation upon task creation finished * Functionality to upload annotations on task creation * Functionality to upload annotations on task creation * Functionality to upload annotations on task creation * Functionality to upload annotations on task creation * Fix trailing whitespace * Use status request for checking task completion * fixed default format name Co-authored-by: Eric Grinstein Co-authored-by: Andrey Zhavoronkov Co-authored-by: Nikita Manovich <40690625+nmanovic@users.noreply.github.com> --- CHANGELOG.md | 1 + utils/cli/core/core.py | 33 +++++++++++++++++++++++++++++---- utils/cli/core/definition.py | 21 ++++++++++++++++++++- 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 488c67b1..eb38df34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Built-in search for labels when create an object or change a label () - Better validation of labels and attributes in raw viewer () - ClamAV antivirus integration () +- Add option to upload annotations upon task creation on CLI - Polygon and polylines interpolation () - Ability to redraw shape from scratch (Shift + N) for an activated shape () - Highlights for the first point of a polygon/polyline and direction () diff --git a/utils/cli/core/core.py b/utils/cli/core/core.py index f684608e..a5136428 100644 --- a/utils/cli/core/core.py +++ b/utils/cli/core/core.py @@ -8,6 +8,7 @@ import os import requests from io import BytesIO import mimetypes +from time import sleep from PIL import Image @@ -57,7 +58,9 @@ class CLI(): response = self.session.get(url) response.raise_for_status() - def tasks_create(self, name, labels, bug, resource_type, resources, **kwargs): + def tasks_create(self, name, labels, bug, resource_type, resources, + annotation_path='', annotation_format='CVAT XML 1.1', + completion_verification_period=20, **kwargs): """ Create a new task with the given name and labels JSON and add the files to it. """ url = self.api.tasks @@ -69,7 +72,26 @@ class CLI(): response.raise_for_status() response_json = response.json() log.info('Created task ID: {id} NAME: {name}'.format(**response_json)) - self.tasks_data(response_json['id'], resource_type, resources) + task_id = response_json['id'] + self.tasks_data(task_id, resource_type, resources) + + if annotation_path != '': + url = self.api.tasks_id_status(task_id) + response = self.session.get(url) + response_json = response.json() + + log.info('Awaiting data compression before uploading annotations...') + while response_json['state'] != 'Finished': + sleep(completion_verification_period) + response = self.session.get(url) + response_json = response.json() + logger_string= '''Awaiting compression for task {}. + Status={}, Message={}'''.format(task_id, + response_json['state'], + response_json['message']) + log.info(logger_string) + + self.tasks_upload(task_id, annotation_format, annotation_path, **kwargs) def tasks_delete(self, task_ids, **kwargs): """ Delete a list of tasks, ignoring those which don't exist. """ @@ -135,8 +157,8 @@ class CLI(): while True: response = self.session.put( url, - files={'annotation_file':open(filename, 'rb')} - ) + files={'annotation_file': open(filename, 'rb')} + ) response.raise_for_status() if response.status_code == 201: break @@ -176,6 +198,9 @@ class CVAT_API_V1(): def tasks_id_frame_id(self, task_id, frame_id, quality): return self.tasks_id(task_id) + '/data?type=frame&number={}&quality={}'.format(frame_id, quality) + def tasks_id_status(self, task_id): + return self.tasks_id(task_id) + '/status' + def tasks_id_annotations_format(self, task_id, fileformat): return self.tasks_id(task_id) + '/annotations?format={}' \ .format(fileformat) diff --git a/utils/cli/core/definition.py b/utils/cli/core/definition.py index 7f9eb2db..d8892d19 100644 --- a/utils/cli/core/definition.py +++ b/utils/cli/core/definition.py @@ -125,6 +125,25 @@ task_create_parser.add_argument( help='list of paths or URLs', nargs='+' ) +task_create_parser.add_argument( + '--annotation_path', + default='', + type=str, + help='path to annotation file' +) +task_create_parser.add_argument( + '--annotation_format', + default='CVAT 1.1', + type=str, + help='format of the annotation file being uploaded, e.g. CVAT 1.1' +) +task_create_parser.add_argument( + '--completion_verification_period', + default=20, + type=int, + help='''number of seconds to wait until checking + if data compression finished (necessary before uploading annotations)''' +) ####################################################################### # Delete @@ -240,4 +259,4 @@ upload_parser.add_argument( type=str, default='CVAT 1.1', help='annotation format (default: %(default)s)' -) +) \ No newline at end of file