Tensorflow annotation update (rq queues instead of CVAT statuses) (#155)

* Use rq instead of cvat statuses
* Removed permissions for meta info
main
Boris Sekachev 8 years ago committed by Nikita Manovich
parent 920247dc31
commit dd6bdeaa2a

@ -1,4 +1,3 @@
# Copyright (C) 2018 Intel Corporation # Copyright (C) 2018 Intel Corporation
# #
# SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT

@ -192,7 +192,7 @@ def save_job_status(jid, status, user):
db_task = db_job.segment.task db_task = db_job.segment.task
status = StatusChoice(status) status = StatusChoice(status)
slogger.job[jid].info('changing job status from {} to {} by an user {}'.format(db_job.status, status, user)) slogger.job[jid].info('changing job status from {} to {} by an user {}'.format(db_job.status, str(status), user))
db_job.status = status.value db_job.status = status.value
db_job.save() db_job.save()

@ -9,7 +9,7 @@ function CheckTFAnnotationRequest(taskId, tfAnnotationButton) {
let errorCount = 0; let errorCount = 0;
let interval = setInterval(function() { let interval = setInterval(function() {
$.ajax ({ $.ajax ({
url: '/tf_annotation/check/task/' + taskId, url: '/tensorflow/annotation/check/task/' + taskId,
success: function(jsonData) { success: function(jsonData) {
let status = jsonData["status"]; let status = jsonData["status"];
if (status == "started" || status == "queued") { if (status == "started" || status == "queued") {
@ -40,7 +40,7 @@ function RunTFAnnotationRequest() {
let tfAnnotationButton = this; let tfAnnotationButton = this;
let taskID = window.cvat.dashboard.taskID; let taskID = window.cvat.dashboard.taskID;
$.ajax ({ $.ajax ({
url: '/tf_annotation/create/task/' + taskID, url: '/tensorflow/annotation/create/task/' + taskID,
success: function() { success: function() {
showMessage('Process started.'); showMessage('Process started.');
tfAnnotationButton.text(`Cancel TF Annotation (0%)`); tfAnnotationButton.text(`Cancel TF Annotation (0%)`);
@ -57,7 +57,7 @@ function RunTFAnnotationRequest() {
function CancelTFAnnotationRequest() { function CancelTFAnnotationRequest() {
let tfAnnotationButton = this; let tfAnnotationButton = this;
$.ajax ({ $.ajax ({
url: '/tf_annotation/cancel/task/' + window.cvat.dashboard.taskID, url: '/tensorflow/annotation/cancel/task/' + window.cvat.dashboard.taskID,
success: function() { success: function() {
tfAnnotationButton.prop("disabled", true); tfAnnotationButton.prop("disabled", true);
}, },
@ -90,20 +90,38 @@ window.cvat.dashboard = window.cvat.dashboard || {};
window.cvat.dashboard.uiCallbacks = window.cvat.dashboard.uiCallbacks || []; window.cvat.dashboard.uiCallbacks = window.cvat.dashboard.uiCallbacks || [];
window.cvat.dashboard.uiCallbacks.push(function(newElements) { window.cvat.dashboard.uiCallbacks.push(function(newElements) {
tids = [];
for (let el of newElements) {
tids.push(el.id.split('_')[1])
}
$.ajax({
type: 'POST',
url: '/tensorflow/annotation/meta/get',
data: JSON.stringify(tids),
contentType: "application/json; charset=utf-8",
success: (data) => {
newElements.each(function(idx) { newElements.each(function(idx) {
let elem = $(newElements[idx]); let elem = $(newElements[idx]);
let taskId = +elem.attr('id').split('_')[1]; let tid = +elem.attr('id').split('_')[1];
let status = $.trim($(elem.find('label.dashboardStatusLabel')[0]).text());
let buttonsUI = elem.find('div.dashboardButtonsUI')[0]; let buttonsUI = elem.find('div.dashboardButtonsUI')[0];
let tfAnnotationButton = $('<button> Run TF Annotation </button>'); let tfAnnotationButton = $('<button> Run TF Annotation </button>');
tfAnnotationButton.on('click', onTFAnnotationClick.bind(tfAnnotationButton)); tfAnnotationButton.on('click', onTFAnnotationClick.bind(tfAnnotationButton));
tfAnnotationButton.addClass('dashboardTFAnnotationButton semiBold dashboardButtonUI'); tfAnnotationButton.addClass('dashboardTFAnnotationButton semiBold dashboardButtonUI');
tfAnnotationButton.appendTo(buttonsUI); tfAnnotationButton.appendTo(buttonsUI);
if (status == "TF Annotation") { if ((tid in data) && (data[tid].active)) {
tfAnnotationButton.text("Cancel TF Annotation"); tfAnnotationButton.text("Cancel TF Annotation");
tfAnnotationButton.addClass("tfAnnotationProcess"); tfAnnotationButton.addClass("tfAnnotationProcess");
CheckTFAnnotationRequest(taskId, tfAnnotationButton); CheckTFAnnotationRequest(tid, tfAnnotationButton);
}
});
},
error: (data) => {
let message = `Can not get tf annotation meta info. Code: ${data.status}. Message: ${data.responseText || data.statusText}`;
showMessage(message);
throw Error(message);
} }
}); });
}); });

@ -10,4 +10,5 @@ urlpatterns = [
path('create/task/<int:tid>', views.create), path('create/task/<int:tid>', views.create),
path('check/task/<int:tid>', views.check), path('check/task/<int:tid>', views.check),
path('cancel/task/<int:tid>', views.cancel), path('cancel/task/<int:tid>', views.cancel),
path('meta/get', views.get_meta_info),
] ]

@ -258,13 +258,32 @@ def create_thread(tid, labels_mapping):
# Modify data format and save # Modify data format and save
result = convert_to_cvat_format(result) result = convert_to_cvat_format(result)
annotation.save_task(tid, result) annotation.save_task(tid, result)
db_task.status = "Annotation"
db_task.save()
slogger.glob.info('tf annotation for task {} done'.format(tid)) slogger.glob.info('tf annotation for task {} done'.format(tid))
except:
try:
slogger.task[tid].exception('exception was occured during tf annotation of the task', exc_info=True)
except:
slogger.glob.exception('exception was occured during tf annotation of the task {}'.format(tid), exc_into=True)
@login_required
def get_meta_info(request):
try:
queue = django_rq.get_queue('low')
tids = json.loads(request.body.decode('utf-8'))
result = {}
for tid in tids:
job = queue.fetch_job('tf_annotation.create/{}'.format(tid))
if job is not None:
result[tid] = {
"active": job.is_queued or job.is_started,
"success": not job.is_failed
}
return JsonResponse(result)
except Exception as ex: except Exception as ex:
slogger.glob.exception('exception was occured during tf annotation of the task {}: {}'.format(tid, ex)) slogger.glob.exception('exception was occured during tf meta request', exc_into=True)
db_task.status = "TF Annotation Fault" return HttpResponseBadRequest(str(ex))
db_task.save()
@login_required @login_required
@permission_required(perm=['engine.view_task', 'engine.change_annotation'], raise_exception=True) @permission_required(perm=['engine.view_task', 'engine.change_annotation'], raise_exception=True)
@ -272,19 +291,14 @@ def create(request, tid):
slogger.glob.info('tf annotation create request for task {}'.format(tid)) slogger.glob.info('tf annotation create request for task {}'.format(tid))
try: try:
db_task = TaskModel.objects.get(pk=tid) db_task = TaskModel.objects.get(pk=tid)
except ObjectDoesNotExist:
slogger.glob.exception('task with id {} not found'.format(tid))
return HttpResponseBadRequest("A task with this ID was not found")
if not task.is_task_owner(request.user, tid): if not task.is_task_owner(request.user, tid):
slogger.glob.error('not enought of permissions for tf annotation of the task {}'.format(tid)) raise Exception('Not enought of permissions for tf annotation')
return HttpResponseBadRequest("You don't have permissions to tf annotation of the task.")
queue = django_rq.get_queue('low') queue = django_rq.get_queue('low')
job = queue.fetch_job('tf_annotation.create/{}'.format(tid)) job = queue.fetch_job('tf_annotation.create/{}'.format(tid))
if job is not None and (job.is_started or job.is_queued): if job is not None and (job.is_started or job.is_queued):
slogger.glob.error('tf annotation for task {} already running'.format(tid)) raise Exception("The process is already running")
return HttpResponseBadRequest("The process is already running")
db_labels = db_task.label_set.prefetch_related('attributespec_set').all() db_labels = db_task.label_set.prefetch_related('attributespec_set').all()
db_labels = {db_label.id:db_label.name for db_label in db_labels} db_labels = {db_label.id:db_label.name for db_label in db_labels}
@ -313,30 +327,34 @@ def create(request, tid):
labels_mapping[tf_annotation_labels[labels]] = key labels_mapping[tf_annotation_labels[labels]] = key
if not len(labels_mapping.values()): if not len(labels_mapping.values()):
slogger.glob.error('no labels found for task {} tf annotation'.format(tid)) raise Exception('No labels found for tf annotation')
return HttpResponseBadRequest("No labels found for tf annotation")
db_task.status = "TF Annotation"
db_task.save()
# Run tf annotation job # Run tf annotation job
queue.enqueue_call(func=create_thread, queue.enqueue_call(func=create_thread,
args=(tid, labels_mapping), args=(tid, labels_mapping),
job_id='tf_annotation.create/{}'.format(tid), job_id='tf_annotation.create/{}'.format(tid),
timeout=604800) # 7 days timeout=604800) # 7 days
slogger.glob.info('tf annotation job enqueued for task {} with labels {}'.format(tid, labels_mapping))
slogger.task[tid].info('tensorflow annotation job enqueued with labels {}'.format(labels_mapping))
except Exception as ex:
try:
slogger.task[tid].exception("exception was occured during tensorflow annotation request", exc_info=True)
except:
pass
return HttpResponseBadRequest(str(ex))
return HttpResponse() return HttpResponse()
@login_required @login_required
@permission_required(perm='engine.view_task', raise_exception=True) @permission_required(perm='engine.view_task', raise_exception=True)
def check(request, tid): def check(request, tid):
try:
queue = django_rq.get_queue('low') queue = django_rq.get_queue('low')
job = queue.fetch_job('tf_annotation.create/{}'.format(tid)) job = queue.fetch_job('tf_annotation.create/{}'.format(tid))
if job is not None and 'cancel' in job.meta: if job is not None and 'cancel' in job.meta:
return JsonResponse({'status': 'finished'}) return JsonResponse({'status': 'finished'})
data = {} data = {}
try:
if job is None: if job is None:
data['status'] = 'unknown' data['status'] = 'unknown'
elif job.is_queued: elif job.is_queued:
@ -350,6 +368,7 @@ def check(request, tid):
else: else:
data['status'] = 'failed' data['status'] = 'failed'
job.delete() job.delete()
except Exception: except Exception:
data['status'] = 'unknown' data['status'] = 'unknown'
@ -363,14 +382,16 @@ def cancel(request, tid):
queue = django_rq.get_queue('low') queue = django_rq.get_queue('low')
job = queue.fetch_job('tf_annotation.create/{}'.format(tid)) job = queue.fetch_job('tf_annotation.create/{}'.format(tid))
if job is None or job.is_finished or job.is_failed: if job is None or job.is_finished or job.is_failed:
raise Exception('Task is not in tf annotation process') raise Exception('Task is not being annotated currently')
elif 'cancel' not in job.meta: elif 'cancel' not in job.meta:
job.meta['cancel'] = True job.meta['cancel'] = True
job.save() job.save()
db_task = TaskModel.objects.get(pk=tid)
db_task.status = "Annotation"
db_task.save()
except Exception as ex: except Exception as ex:
return HttpResponseBadRequest("TF annotation cancel error: {}".format(str(ex))) try:
slogger.task[tid].exception("cannot cancel tensorflow annotation for task #{}".format(tid), exc_info=True)
except:
pass
return HttpResponseBadRequest(str(ex))
return HttpResponse() return HttpResponse()

@ -35,7 +35,7 @@ urlpatterns = [
] ]
if apps.is_installed('cvat.apps.tf_annotation'): if apps.is_installed('cvat.apps.tf_annotation'):
urlpatterns.append(path('tf_annotation/', include('cvat.apps.tf_annotation.urls'))) urlpatterns.append(path('tensorflow/annotation/', include('cvat.apps.tf_annotation.urls')))
if apps.is_installed('cvat.apps.log_viewer'): if apps.is_installed('cvat.apps.log_viewer'):
urlpatterns.append(path('analytics/', include('cvat.apps.log_viewer.urls'))) urlpatterns.append(path('analytics/', include('cvat.apps.log_viewer.urls')))

Loading…
Cancel
Save