Esempio n. 1
0
 def _save(self, tasks):
     serializer = self.get_serializer(data=tasks, many=True)
     serializer.is_valid(raise_exception=True)
     task_instances = serializer.save(project_id=self.kwargs['pk'])
     project = generics.get_object_or_404(Project.objects.for_user(self.request.user), pk=self.kwargs['pk'])
     emit_webhooks_for_instance(self.request.user.active_organization, project, WebhookAction.TASKS_CREATED, task_instances)
     return task_instances, serializer
Esempio n. 2
0
def delete_tasks_annotations(project, queryset, **kwargs):
    """ Delete all annotations by tasks ids

    :param project: project instance
    :param queryset: filtered tasks db queryset
    """
    task_ids = queryset.values_list('id', flat=True)
    annotations = Annotation.objects.filter(task__id__in=task_ids)
    count = annotations.count()

    # take only tasks where annotations were deleted
    real_task_ids = set(list(annotations.values_list('task__id', flat=True)))
    annotations_ids = list(annotations.values('id'))
    annotations.delete()
    emit_webhooks_for_instance(project.organization, project,
                               WebhookAction.ANNOTATIONS_DELETED,
                               annotations_ids)
    start_job_async_or_sync(bulk_update_stats_project_tasks,
                            queryset.filter(is_labeled=True))

    request = kwargs['request']
    Task.objects.filter(id__in=real_task_ids).update(updated_at=datetime.now(),
                                                     updated_by=request.user)
    return {
        'processed_items': count,
        'detail': 'Deleted ' + str(count) + ' annotations'
    }
Esempio n. 3
0
 def perform_create(self, serializer):
     project = get_object_with_check_and_log(self.request,
                                             Project,
                                             pk=self.kwargs['pk'])
     instance = serializer.save(project=project)
     emit_webhooks_for_instance(self.request.user.active_organization,
                                project, WebhookAction.TASKS_CREATED,
                                [instance])
Esempio n. 4
0
 def perform_create(self, serializer):
     project_id = self.request.data.get('project')
     generics.get_object_or_404(Project, pk=project_id)
     project = generics.get_object_or_404(Project, pk=project_id)
     instance = serializer.save(project=project)
     emit_webhooks_for_instance(self.request.user.active_organization,
                                project, WebhookAction.TASKS_CREATED,
                                [instance])
Esempio n. 5
0
 def delete(self, request, *args, **kwargs):
     project = generics.get_object_or_404(Project.objects.for_user(
         self.request.user),
                                          pk=self.kwargs['pk'])
     task_ids = list(Task.objects.filter(project=project).values('id'))
     Task.objects.filter(project=project).delete()
     emit_webhooks_for_instance(request.user.active_organization, None,
                                WebhookAction.TASKS_DELETED, task_ids)
     return Response(data={'tasks': task_ids}, status=204)
Esempio n. 6
0
def delete_tasks(project, queryset, **kwargs):
    """ Delete tasks by ids

    :param project: project instance
    :param queryset: filtered tasks db queryset
    """
    tasks_ids = list(queryset.values('id'))
    count = len(tasks_ids)
    tasks_ids_list = [task['id'] for task in tasks_ids]
    # signals to switch off
    signals = [(post_delete, update_is_labeled_after_removing_annotation,
                Annotation),
               (post_delete, update_all_task_states_after_deleting_task, Task),
               (pre_delete, remove_data_columns, Task),
               (pre_delete, remove_project_summary_annotations, Annotation)]

    # delete all project tasks
    if count == project.tasks.count():
        with temporary_disconnect_list_signal(signals):
            queryset.delete()
        project.summary.reset()

    # delete only specific tasks
    else:
        # update project summary
        start_job_async_or_sync(async_project_summary_recalculation,
                                tasks_ids_list, project.id)

        with temporary_disconnect_list_signal(signals):
            queryset.delete()

    project.update_tasks_states(maximum_annotations_changed=False,
                                overlap_cohort_percentage_changed=False,
                                tasks_number_changed=True)

    # emit webhooks for project
    emit_webhooks_for_instance(project.organization, project,
                               WebhookAction.TASKS_DELETED, tasks_ids)

    # remove all tabs if there are no tasks in project
    reload = False
    if not project.tasks.exists():
        project.views.all().delete()
        reload = True

    return {
        'processed_items': count,
        'reload': reload,
        'detail': 'Deleted ' + str(count) + ' tasks'
    }
Esempio n. 7
0
def test_emit_webhooks_for_instance(setup_project_dialog, organization_webhook):
    webhook = organization_webhook
    project_title = f'Projects 1'
    project = Project.objects.create(title=project_title)
    with requests_mock.Mocker(real_http=True) as m:
        m.register_uri('POST', webhook.url)
        emit_webhooks_for_instance(
            webhook.organization, webhook.project, WebhookAction.PROJECT_CREATED, instance=project
        )
    assert len(m.request_history) == 1
    assert m.request_history[0].method == 'POST'
    data = m.request_history[0].json()
    assert 'action' in data
    assert 'project' in data
    assert project_title == data['project']['title']
def predictions_to_annotations(project, queryset, **kwargs):
    request = kwargs['request']
    user = request.user
    model_version = request.data.get('model_version')
    queryset = queryset.filter(predictions__isnull=False)
    predictions = Prediction.objects.filter(task__in=queryset,
                                            child_annotations__isnull=True)

    # model version filter
    if model_version is not None:
        if isinstance(model_version, list):
            predictions = predictions.filter(
                model_version__in=model_version).distinct()
        else:
            predictions = predictions.filter(model_version=model_version)

    predictions_values = list(
        predictions.values_list('result', 'model_version', 'task_id', 'id'))

    # prepare annotations
    annotations = []
    tasks_ids = []
    for result, model_version, task_id, prediction_id in predictions_values:
        tasks_ids.append(task_id)
        annotations.append({
            'result': result,
            'completed_by_id': user.pk,
            'task_id': task_id,
            'parent_prediction_id': prediction_id
        })

    count = len(annotations)
    logger.debug(f'{count} predictions will be converter to annotations')
    db_annotations = [Annotation(**annotation) for annotation in annotations]
    db_annotations = Annotation.objects.bulk_create(db_annotations)
    Task.objects.filter(id__in=tasks_ids).update(updated_at=now(),
                                                 updated_by=request.user)

    if db_annotations:
        TaskSerializerBulk.post_process_annotations(db_annotations)
        # Execute webhook for created annotations
        emit_webhooks_for_instance(user.active_organization, project,
                                   WebhookAction.ANNOTATIONS_CREATED,
                                   db_annotations)

    return {'response_code': 200, 'detail': f'Created {count} annotations'}
Esempio n. 9
0
def delete_tasks_annotations(project, queryset, **kwargs):
    """ Delete all annotations by tasks ids

    :param project: project instance
    :param queryset: filtered tasks db queryset
    """
    task_ids = queryset.values_list('id', flat=True)
    annotations = Annotation.objects.filter(task__id__in=task_ids)
    count = annotations.count()
    annotations_ids = list(annotations.values('id'))
    annotations.delete()
    emit_webhooks_for_instance(project.organization, project,
                               WebhookAction.ANNOTATIONS_DELETED,
                               annotations_ids)
    return {
        'processed_items': count,
        'detail': 'Deleted ' + str(count) + ' annotations'
    }
Esempio n. 10
0
def delete_tasks(project, queryset, **kwargs):
    """ Delete tasks by ids

    :param project: project instance
    :param queryset: filtered tasks db queryset
    """
    tasks_ids = list(queryset.values('id'))
    count = len(tasks_ids)

    # delete all project tasks
    if count == project.tasks.count():
        with temporary_disconnect_all_signals():
            queryset.delete()

        project.summary.reset()
        project.update_tasks_states(maximum_annotations_changed=False,
                                    overlap_cohort_percentage_changed=False,
                                    tasks_number_changed=True)

    # delete only specific tasks
    else:
        # this signal re-save the task back
        with temporary_disconnect_signal(
                signals.post_delete,
                update_is_labeled_after_removing_annotation, Annotation):
            queryset.delete()

    emit_webhooks_for_instance(project.organization, project,
                               WebhookAction.TASKS_DELETED, tasks_ids)

    # remove all tabs if there are no tasks in project
    reload = False
    if not project.tasks.exists():
        project.views.all().delete()
        reload = True

    return {
        'processed_items': count,
        'reload': reload,
        'detail': 'Deleted ' + str(count) + ' tasks'
    }
Esempio n. 11
0
    def create(self, validated_data):
        ''' Bulk creation objects of Label model with related LabelLink
        reusing already existing labels
        '''
        from webhooks.utils import emit_webhooks_for_instance

        with transaction.atomic():
            # loading already existing labels
            titles = [item['title'] for item in validated_data]
            existing_labels = Label.objects.filter(
                organization=self.context['request'].user.active_organization,
                title__in=titles).all()
            existing_labels_map = {
                label.title: label
                for label in existing_labels
            }

            # create objects for labels, that we need to create
            labels_data = []
            labels = []
            labels_create = []
            for item in validated_data:
                project = item.pop('project')
                from_name = item.pop('from_name')
                if item['title'] in existing_labels_map:
                    label = existing_labels_map[item['title']]
                else:
                    label = Label(**item)
                    labels_create.append(label)
                labels.append(label)
                labels_data.append(dict(project=project, from_name=from_name))

            if labels_create:
                if settings.DJANGO_DB == settings.DJANGO_DB_SQLITE:
                    created_labels = {}
                    for label in labels_create:
                        label.save()
                        created_labels[label.title] = label
                else:
                    created_labels = {
                        label.title: label
                        for label in Label.objects.bulk_create(labels_create)
                    }

            # connect existing and created labels to project with LabelLink
            links = []
            result = []
            for index, label in enumerate(labels):
                if label.id is None:
                    label = created_labels[label.title]
                label.project = labels_data[index]['project']
                label.from_name = labels_data[index]['from_name']
                result.append(label)
                links.append(
                    LabelLink(
                        **{
                            'label': label,
                            'project': labels_data[index]['project'],
                            'from_name': labels_data[index]['from_name'],
                        }))

            links = LabelLink.objects.bulk_create(links, ignore_conflicts=True)
            # webhooks processing
            # bulk_create with ignore_conflicts doesn't return ids, reloading links
            project = labels[0].project
            label_ids = [label.id for label in result]
            links = LabelLink.objects.filter(label_id__in=label_ids,
                                             project=project).all()
            if links:
                emit_webhooks_for_instance(
                    self.context['request'].user.active_organization,
                    links[0].project, 'LABEL_LINK_CREATED', links)

        return result