def perform_create(self, ser): task = get_object_with_check_and_log(self.request, Task, pk=self.kwargs['pk']) # annotator has write access only to annotations and it can't be checked it after serializer.save() user = self.request.user # updates history result = ser.validated_data.get('result') extra_args = {'task_id': self.kwargs['pk']} # save stats about how well annotator annotations coincide with current prediction # only for finished task annotations if result is not None: prediction = Prediction.objects.filter( task=task, model_version=task.project.model_version) if prediction.exists(): prediction = prediction.first() prediction_ser = PredictionSerializer(prediction).data else: logger.debug( f'User={self.request.user}: there are no predictions for task={task}' ) prediction_ser = {} # serialize annotation extra_args.update({ 'prediction': prediction_ser, }) if 'was_cancelled' in self.request.GET: extra_args['was_cancelled'] = bool_from_request( self.request.GET, 'was_cancelled', False) if 'completed_by' not in ser.validated_data: extra_args['completed_by'] = self.request.user # create annotation logger.debug(f'User={self.request.user}: save annotation') annotation = ser.save(**extra_args) logger.debug(f'Save activity for user={self.request.user}') self.request.user.activity_at = timezone.now() self.request.user.save() # Release task if it has been taken at work (it should be taken by the same user, or it makes sentry error logger.debug(f'User={user} releases task={task}') task.release_lock(user) # if annotation created from draft - remove this draft draft_id = self.request.data.get('draft_id') if draft_id is not None: logger.debug( f'Remove draft {draft_id} after creating annotation {annotation.id}' ) AnnotationDraft.objects.filter(id=draft_id).delete() if self.request.data.get('ground_truth'): annotation.task.ensure_unique_groundtruth( annotation_id=annotation.id) return annotation
def get(self, request): """ get: Project state Retrieve the project state for data manager. """ pk = int_from_request(request.GET, "project", 1) # replace 1 to None, it's for debug only project = get_object_with_check_and_log(request, Project.objects.with_counts(), pk=pk) self.check_object_permissions(request, project) data = ProjectSerializer(project).data data.update({ "can_delete_tasks": True, "can_manage_annotations": True, "can_manage_tasks": True, "source_syncing": False, "target_syncing": False, "task_count": project.tasks.count(), "annotation_count": Annotation.objects.filter(task__project=project).count(), 'config_has_control_tags': len(project.get_control_tags_from_config()) > 0 }) return Response(data)
def post(self, request, *args, **kwargs): ml_backend = get_object_with_check_and_log(request, MLBackend, pk=self.kwargs['pk']) self.check_object_permissions(self.request, ml_backend) serializer = MLInteractiveAnnotatingRequest(data=request.data) serializer.is_valid(raise_exception=True) validated_data = serializer.validated_data task = get_object_with_check_and_log(request, Task, pk=validated_data['task'], project=ml_backend.project) context = validated_data.get('context') result = ml_backend.interactive_annotating(task, context) return Response( result, status=status.HTTP_200_OK, )
def post(self, request): """ post: Post actions Perform an action with the selected items from a specific view. """ pk = int_from_request(request.GET, "project", None) project = get_object_with_check_and_log(request, Project, pk=pk) self.check_object_permissions(request, project) queryset = get_prepared_queryset(request, project) # no selected items on tab if not queryset.exists(): response = {'detail': 'No selected items for specified view'} return Response(response, status=404) # wrong action id action_id = request.GET.get('id', None) if action_id is None: response = { 'detail': 'No action id "' + str(action_id) + '", use ?id=<action-id>' } return Response(response, status=422) # perform action and return the result dict kwargs = {'request': request} # pass advanced params to actions result = perform_action(action_id, project, queryset, **kwargs) code = result.pop('response_code', 200) return Response(result, status=code)
def get_queryset(self): org_pk = get_organization_from_request(self.request) org = get_object_with_check_and_log(self.request, Organization, pk=org_pk) self.check_object_permissions(self.request, org) return Project.objects.all()
def get(self, request): pk = int_from_request(request.GET, "project", 1) project = get_object_with_check_and_log(request, Project, pk=pk) self.check_object_permissions(request, project) GET_ALL_COLUMNS = load_func(settings.DATA_MANAGER_GET_ALL_COLUMNS) data = GET_ALL_COLUMNS(project, request.user) return Response(data)
def post(self, request, *args, **kwargs): ml_backend = get_object_with_check_and_log(request, MLBackend, pk=self.kwargs['pk']) self.check_object_permissions(self.request, ml_backend) ml_backend.train() return Response(status=status.HTTP_200_OK)
def get_queryset(self): project_pk = self.request.query_params.get('project') project = get_object_with_check_and_log(self.request, Project, pk=project_pk) self.check_object_permissions(self.request, project) ImportStorageClass = self.serializer_class.Meta.model return ImportStorageClass.objects.filter(project_id=project.id)
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])
def from_request(cls, request): if 'organization_pk' not in request.session: logger.debug( '"organization_pk" is missed in request.session: can\'t get Organization' ) return pk = get_organization_from_request(request) return get_object_with_check_and_log(request, Organization, pk=pk)
def get_queryset(self): project_pk = self.request.query_params.get('project') project = get_object_with_check_and_log(self.request, Project, pk=project_pk) self.check_object_permissions(self.request, project) ml_backends = MLBackend.objects.filter(project_id=project.id) for mlb in ml_backends: mlb.update_state() return ml_backends
def task_page(request, pk): org_pk = get_organization_from_request(request) org = get_object_with_permissions(request, Organization, org_pk, 'organizations.view_organization') project = get_object_with_check_and_log(request, Project, pk=pk) response = {'project': project, 'version': get_short_version()} response.update(find_editor_files()) return render(request, 'data_manager/data.html', response)
def update(self, request, *args, **kwargs): # save user history with annotator_id, time & annotation result annotation_id = self.kwargs['pk'] annotation = get_object_with_check_and_log(request, Annotation, pk=annotation_id) annotation.task.save() # refresh task metrics return super(AnnotationAPI, self).update(request, *args, **kwargs)
def update(self, request, *args, **kwargs): # save user history with annotator_id, time & annotation result annotation_id = self.kwargs['pk'] annotation = get_object_with_check_and_log(request, Annotation, pk=annotation_id) annotation.task.save() # refresh task metrics if self.request.data.get('ground_truth'): annotation.task.ensure_unique_groundtruth(annotation_id=annotation.id) return super(AnnotationAPI, self).update(request, *args, **kwargs)
def project(self): """ Take the project from context """ if 'project' in self.context: project = self.context['project'] elif 'view' in self.context and 'project_id' in self.context['view'].kwargs: kwargs = self.context['view'].kwargs project = get_object_with_check_and_log(Project, kwargs['project_id']) else: project = None return project
def get(self, request, *args, **kwargs): org = get_object_with_check_and_log( self.request, Organization, pk=request.user.active_organization_id) self.check_object_permissions(self.request, org) invite_url = '{}?token={}'.format(reverse('user-signup'), org.token) serializer = OrganizationInviteSerializer(data={ 'invite_url': invite_url, 'token': org.token }) serializer.is_valid() return Response(serializer.data, status=200)
def get(self, request): """ get: Get actions Retrieve all the registered actions with descriptions that data manager can use. """ pk = int_from_request(request.GET, "project", 1) # replace 1 to None, it's for debug only project = get_object_with_check_and_log(request, Project, pk=pk) self.check_object_permissions(request, project) return Response(get_all_actions(request.user))
def get(self, request): """ get: Get data manager columns Retrieve the data manager columns available for the tasks in a specific project. """ pk = int_from_request(request.GET, "project", 1) project = get_object_with_check_and_log(request, Project, pk=pk) self.check_object_permissions(request, project) data = get_all_columns(project) return Response(data)
def perform_create(self, ser): # get organization org_pk = self.request.session.get('organization_pk') org = get_object_with_check_and_log(self.request, Organization, pk=org_pk) self.check_object_permissions(self.request, org) try: project = ser.save(organization=org) except IntegrityError as e: if str(e) == 'UNIQUE constraint failed: project.title, project.created_by_id': raise ProjectExistException('Project with the same name already exists: {}'. format(ser.validated_data.get('title', ''))) raise LabelStudioDatabaseException('Database error during project creation. Try again.')
def get(self, request, *args, **kwargs): project = self.get_object() project = get_object_with_check_and_log(request, Project, pk=self.kwargs['pk']) self.check_object_permissions(self.request, project) paths = [] for name in os.listdir(settings.EXPORT_DIR): if name.endswith('.json') and not name.endswith('-info.json'): project_id = name.split('-')[0] if str(kwargs['pk']) == project_id: paths.append(settings.EXPORT_URL_ROOT + name) items = [{'name': p.split('/')[2].split('.')[0], 'url': p} for p in sorted(paths)[::-1]] return Response({'export_files': items}, status=status.HTTP_200_OK)
def get(self, request, *args, **kwargs): """ Get export files list """ original_url = request.META['HTTP_X_ORIGINAL_URI'] filename = original_url.replace('/export/', '') project_id = filename.split('-')[0] try: pk = int(project_id) except ValueError: return Response("Incorrect filename in export", status=status.HTTP_422_UNPROCESSABLE_ENTITY) project = get_object_with_check_and_log(request, Project, pk=pk) self.check_object_permissions(self.request, project) return Response("auth ok", status=status.HTTP_200_OK)
def post(self, request, *args, **kwargs): org_pk = request.data.get('org_pk') org = get_object_with_check_and_log(self.request, Organization, pk=org_pk) self.check_object_permissions(self.request, org) org.reset_token() logger.debug(f'New token for organization {org.pk} is {org.token}') return Response( { 'token': org.token, 'invite_url': reverse('organizations:organization-invite', kwargs={'token': org.token}) }, status=201)
def get(self, request): """ get: Get actions Retrieve all the registered actions with descriptions that data manager can use. """ pk = int_from_request(request.GET, "project", 1) # replace 1 to None, it's for debug only project = get_object_with_check_and_log(request, Project, pk=pk) self.check_object_permissions(request, project) params = { 'can_delete_tasks': True, 'can_manage_annotations': True, 'experimental_feature': False } return Response(get_all_actions(params))
def post(self, request): pk = int_from_request(request.GET, "project", None) project = get_object_with_check_and_log(request, Project, pk=pk) self.check_object_permissions(request, project) queryset = get_prepared_queryset(request, project) # wrong action id action_id = request.GET.get('id', None) if action_id is None: response = {'detail': 'No action id "' + str(action_id) + '", use ?id=<action-id>'} return Response(response, status=422) # perform action and return the result dict kwargs = {'request': request} # pass advanced params to actions result = perform_action(action_id, project, queryset, request.user, **kwargs) code = result.pop('response_code', 200) return Response(result, status=code)
def upload_example_using_config(request): """ Generate upload data example by config only """ config = request.GET.get('label_config', '') if not config: config = request.POST.get('label_config', '') org_pk = request.session.get('organization_pk', None) secure_mode = False if org_pk is not None: org = get_object_with_check_and_log(request, Organization, pk=org_pk) secure_mode = org.secure_mode try: Project.validate_label_config(config) task_data, _, _ = get_sample_task(config, secure_mode) task_data = playground_replacements(request, task_data) except (ValueError, ValidationError, lxml.etree.Error): response = HttpResponse('error while example generating', status=status.HTTP_400_BAD_REQUEST) else: response = HttpResponse(json.dumps(task_data)) return response
def get_object(self): org = get_object_with_check_and_log(self.request, Organization, pk=self.kwargs[self.lookup_field]) self.check_object_permissions(self.request, org) return org
def perform_create(self, serializer): project = get_object_with_check_and_log(self.request, Project, pk=self.kwargs['pk']) serializer.save(project=project)
def get_serializer_context(self): context = super(TasksListAPI, self).get_serializer_context() context['project'] = get_object_with_check_and_log( self.request, Project, pk=self.kwargs['pk']) return context
def get(self, request, *args, **kwargs): project = get_object_with_check_and_log(request, Project, pk=self.kwargs['pk']) # TODO: LSE option # if not project.is_published: # raise PermissionDenied('Project is not published.') self.check_object_permissions(request, project) user = request.user # support actions api call from actions/next_task.py if hasattr(self, 'prepared_tasks'): project.prepared_tasks = self.prepared_tasks external_prepared_tasks_used = True # get prepared tasks from request params (filters, selected items) else: project.prepared_tasks = get_prepared_queryset( self.request, project) external_prepared_tasks_used = False # detect solved and not solved tasks user_solved_tasks_array = user.annotations.filter( ground_truth=False).filter(Q(task__isnull=False)).values_list( 'task__pk', flat=True) with conditional_atomic(): not_solved_tasks = project.prepared_tasks.\ exclude(pk__in=user_solved_tasks_array).filter(is_labeled=False) not_solved_tasks_count = not_solved_tasks.count() # return nothing if there are no tasks remain if not_solved_tasks_count == 0: raise NotFound( f'There are no tasks remaining to be annotated by the user={user}' ) logger.debug( f'{not_solved_tasks_count} tasks that still need to be annotated for user={user}' ) # ordered by data manager if external_prepared_tasks_used: next_task = not_solved_tasks.first() if not next_task: raise NotFound('No more tasks found') return self._make_response(next_task, request) # If current user has already lock one task - return it (without setting the lock again) next_task = Task.get_locked_by(user, project) if next_task: return self._make_response(next_task, request, use_task_lock=False) if project.show_ground_truth_first: logger.debug( f'User={request.user} tries ground truth from {not_solved_tasks_count} tasks' ) next_task = self._try_ground_truth(not_solved_tasks, project) if next_task: return self._make_response(next_task, request) if project.show_overlap_first: # don't output anything - just filter tasks with overlap logger.debug( f'User={request.user} tries overlap first from {not_solved_tasks_count} tasks' ) _, not_solved_tasks = self._try_tasks_with_overlap( not_solved_tasks) # if there any tasks in progress (with maximum number of annotations), randomly sampling from them logger.debug( f'User={request.user} tries depth first from {not_solved_tasks_count} tasks' ) next_task = self._try_breadth_first(not_solved_tasks) if next_task: return self._make_response(next_task, request) if project.sampling == project.UNCERTAINTY: logger.debug( f'User={request.user} tries uncertainty sampling from {not_solved_tasks_count} tasks' ) next_task = self._try_uncertainty_sampling( not_solved_tasks, project, user_solved_tasks_array) elif project.sampling == project.UNIFORM: logger.debug( f'User={request.user} tries random sampling from {not_solved_tasks_count} tasks' ) next_task = self._get_random_unlocked(not_solved_tasks) elif project.sampling == project.SEQUENCE: logger.debug( f'User={request.user} tries sequence sampling from {not_solved_tasks_count} tasks' ) next_task = self._get_first_unlocked( not_solved_tasks.all().order_by('id')) if next_task: return self._make_response(next_task, request) else: raise NotFound( f'There exist some unsolved tasks for the user={user}, but they seem to be locked by another users' )
def get_object(self): obj = get_object_with_check_and_log(self.request, Project, pk=self.kwargs['pk']) self.check_object_permissions(self.request, obj) return obj