Пример #1
0
def emit_webhooks(organization, project, action, payload):
    """Run all active webhooks for the action."""
    webhooks = get_active_webhooks(organization, project, action)
    if project and payload and webhooks.filter(send_payload=True).exists():
        payload['project'] = load_func(settings.WEBHOOK_SERIALIZERS['project'])(instance=project).data
    for wh in webhooks:
        run_webhook(wh, action, payload)
Пример #2
0
 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)
Пример #3
0
def user_login(request):
    """ Login page
    """
    user = request.user
    next_page = request.GET.get('next')
    next_page = next_page if next_page else reverse('projects:project-index')
    login_form = load_func(settings.USER_LOGIN_FORM)
    form = login_form()

    if user.is_authenticated:
        return redirect(next_page)

    if request.method == 'POST':
        form = login_form(request.POST)
        if form.is_valid():
            user = form.cleaned_data['user']
            auth.login(request,
                       user,
                       backend='django.contrib.auth.backends.ModelBackend')

            # user is organization member
            org_pk = Organization.find_by_user(user).pk
            user.active_organization_id = org_pk
            user.save(update_fields=['active_organization'])
            return redirect(next_page)

    return render(request, 'users/user_login.html', {
        'form': form,
        'next': next_page
    })
Пример #4
0
def emit_webhooks_for_instance(organization, project, action, instance=None):
    """Run all active webhooks for the action using instances as payload.

    Be sure WebhookAction.ACTIONS contains all required fields.
    """
    webhooks = get_active_webhooks(organization, project, action)
    if not webhooks.exists():
        return
    payload = {}
    # if instances and there is a webhook that sends payload
    # get serialized payload
    action_meta = WebhookAction.ACTIONS[action]
    if instance and webhooks.filter(send_payload=True).exists():
        serializer_class = action_meta.get('serializer')
        if serializer_class:
            payload[action_meta['key']] = serializer_class(instance=instance, many=action_meta['many']).data
        if project and payload:
            payload['project'] = load_func(settings.WEBHOOK_SERIALIZERS['project'])(instance=project).data
        if payload and 'nested-fields' in action_meta:
            for key, value in action_meta['nested-fields'].items():
                payload[key] = value['serializer'](
                    instance=get_nested_field(instance, value['field']), many=value['many']
                ).data
    for wh in webhooks:
        run_webhook(wh, action, payload)
Пример #5
0
 def _get_serialized_data(self, annotation):
     if get_bool_env('FUTURE_SAVE_TASK_TO_STORAGE', default=False):
         # export task with annotations
         return ExportDataSerializer(annotation.task).data
     else:
         serializer_class = load_func(settings.STORAGE_ANNOTATION_SERIALIZER)
         # deprecated functionality - save only annotation
         return serializer_class(annotation).data
Пример #6
0
def proceed_registration(request, user_form, organization_form, next_page):
    """ Register a new user for POST user_signup
    """
    # save user to db
    save_user = load_func(settings.SAVE_USER)
    response = save_user(request, next_page, user_form)

    return response
Пример #7
0
def proceed_registration(request, user_form, organization_form, next_page):
    """ Register a new user for POST user_signup
    """
    # save user to db
    save_user = load_func(settings.SAVE_USER)
    user, redirect_url = save_user(request, next_page, user_form,
                                   organization_form)

    if Organization.objects.exists():
        org = Organization.objects.first()
        org.add_user(user)
    else:
        org = Organization.create_organization(created_by=user,
                                               title='Label Studio')
    user.active_organization = org
    user.save(update_fields=['active_organization'])

    return redirect(redirect_url)
Пример #8
0
 def train(self, project, use_ground_truth=False):
     # TODO Replace AnonymousUser with real user from request
     user = AnonymousUser()
     # Identify if feature flag is turned on
     if flag_set(
             'ff_back_dev_1417_start_training_mlbackend_webhooks_250122_long',
             user):
         request = {
             'action':
             'PROJECT_UPDATED',
             'project':
             load_func(settings.WEBHOOK_SERIALIZERS['project'])(
                 instance=project).data
         }
         return self._request('webhook',
                              request,
                              verbose=False,
                              timeout=TIMEOUT_PREDICT)
     else:
         # get only tasks with annotations
         tasks = project.tasks.annotate(
             num_annotations=Count('annotations')).filter(
                 num_annotations__gt=0)
         # create serialized tasks with annotations: {"data": {...}, "annotations": [{...}], "predictions": [{...}]}
         tasks_ser = ExportDataSerializer(tasks, many=True).data
         logger.debug(
             f'{len(tasks_ser)} tasks with annotations are sent to ML backend for training.'
         )
         request = {
             'annotations': tasks_ser,
             'project': self._create_project_uid(project),
             'label_config': project.label_config,
             'params': {
                 'login': project.task_data_login,
                 'password': project.task_data_password
             }
         }
         return self._request('train',
                              request,
                              verbose=False,
                              timeout=TIMEOUT_PREDICT)
Пример #9
0
import ujson as json
from core import version
from core.utils.common import load_func
from core.utils.io import get_all_files_from_dir, get_temp_dir, read_bytes_stream
from django.conf import settings
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _
from label_studio_converter import Converter
from tasks.models import Annotation

logger = logging.getLogger(__name__)

ExportMixin = load_func(settings.EXPORT_MIXIN)


class Export(ExportMixin, models.Model):
    class Status(models.TextChoices):
        CREATED = 'created', _('Created')
        IN_PROGRESS = 'in_progress', _('In progress')
        FAILED = 'failed', _('Failed')
        COMPLETED = 'completed', _('Completed')

    title = models.CharField(
        _('title'),
        blank=True,
        default='',
        max_length=2048,
    )
Пример #10
0
                self.project.model_version = last_model_version
                self.project.save()

        self.post_process_annotations(self.db_annotations)
        return db_tasks

    @staticmethod
    def post_process_annotations(db_annotations):
        pass

    class Meta:
        model = Task
        fields = "__all__"
    

TaskSerializer = load_func(settings.TASK_SERIALIZER)
        

class TaskWithAnnotationsSerializer(TaskSerializer):
    """
    """
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['annotations'] = AnnotationSerializer(many=True, default=[], context=self.context)

    class Meta:
        model = Task
        list_serializer_class = load_func(settings.TASK_SERIALIZER_BULK)
        
        exclude = ()
Пример #11
0
class WebhookAction(models.Model):
    PROJECT_CREATED = 'PROJECT_CREATED'
    PROJECT_UPDATED = 'PROJECT_UPDATED'
    PROJECT_DELETED = 'PROJECT_DELETED'

    TASKS_CREATED = 'TASKS_CREATED'
    TASKS_DELETED = 'TASKS_DELETED'

    ANNOTATION_CREATED = 'ANNOTATION_CREATED'
    ANNOTATIONS_CREATED = 'ANNOTATIONS_CREATED'
    ANNOTATION_UPDATED = 'ANNOTATION_UPDATED'
    ANNOTATIONS_DELETED = 'ANNOTATIONS_DELETED'

    LABEL_LINK_CREATED = 'LABEL_LINK_CREATED'
    LABEL_LINK_UPDATED = 'LABEL_LINK_UPDATED'
    LABEL_LINK_DELETED = 'LABEL_LINK_DELETED'

    ACTIONS = {
        PROJECT_CREATED: {
            'name': _('Project created'),
            'description': _(''),
            'key': 'project',
            'many': False,
            'model': Project,
            'serializer': load_func(settings.WEBHOOK_SERIALIZERS['project']),
            'organization-only': True,
        },
        PROJECT_UPDATED: {
            'name': _('Project updated'),
            'description': _(''),
            'key': 'project',
            'many': False,
            'model': Project,
            'serializer': load_func(settings.WEBHOOK_SERIALIZERS['project']),
            'project-field': '__self__',
        },
        PROJECT_DELETED: {
            'name': _('Project deleted'),
            'description': _(''),
            'key': 'project',
            'many': False,
            'model': Project,
            'serializer': OnlyIDWebhookSerializer,
            'organization-only': True,
        },
        TASKS_CREATED: {
            'name': _('Task created'),
            'description': _(''),
            'key': 'tasks',
            'many': True,
            'model': Task,
            'serializer': load_func(settings.WEBHOOK_SERIALIZERS['task']),
            'project-field': 'project',
        },
        TASKS_DELETED: {
            'name': _('Task deleted'),
            'description': _(''),
            'key': 'tasks',
            'many': True,
            'model': Task,
            'serializer': OnlyIDWebhookSerializer,
            'project-field': 'project',
        },
        ANNOTATION_CREATED: {
            'name': _('Annotation created'),
            'description': _(''),
            'key': 'annotation',
            'many': False,
            'model': Annotation,
            'serializer':
            load_func(settings.WEBHOOK_SERIALIZERS['annotation']),
            'project-field': 'task__project',
            'nested-fields': {
                'task': {
                    'serializer':
                    load_func(settings.WEBHOOK_SERIALIZERS['task']),
                    'many': False,
                    'field': 'task',
                },
            },
        },
        ANNOTATIONS_CREATED: {
            'name': _('Annotations created'),
            'description': _(''),
            'key': 'annotation',
            'many': True,
            'model': Annotation,
            'serializer':
            load_func(settings.WEBHOOK_SERIALIZERS['annotation']),
            'project-field': 'task__project',
            'nested-fields': {
                'task': {
                    'serializer':
                    load_func(settings.WEBHOOK_SERIALIZERS['task']),
                    'many': True,
                    'field': 'task',
                },
            },
        },
        ANNOTATION_UPDATED: {
            'name': _('Annotation updated'),
            'description': _(''),
            'key': 'annotation',
            'many': False,
            'model': Annotation,
            'serializer':
            load_func(settings.WEBHOOK_SERIALIZERS['annotation']),
            'project-field': 'task__project',
            'nested-fields': {
                'task': {
                    'serializer':
                    load_func(settings.WEBHOOK_SERIALIZERS['task']),
                    'many': False,
                    'field': 'task',
                },
            },
        },
        ANNOTATIONS_DELETED: {
            'name': _('Annotation deleted'),
            'description': _(''),
            'key': 'annotations',
            'many': True,
            'model': Annotation,
            'serializer': OnlyIDWebhookSerializer,
            'project-field': 'task__project',
        },
        LABEL_LINK_CREATED: {
            'name': _('Label link created'),
            'description': _(''),
            'key': 'label_link',
            'many': True,
            'model': LabelLink,
            'serializer':
            load_func(settings.WEBHOOK_SERIALIZERS['label_link']),
            'project-field': 'project',
        },
        LABEL_LINK_UPDATED: {
            'name': _('Label link updated'),
            'description': _(''),
            'key': 'label_link',
            'many': False,
            'model': LabelLink,
            'serializer':
            load_func(settings.WEBHOOK_SERIALIZERS['label_link']),
            'project-field': 'project',
            'nested-fields': {
                'label': {
                    'many': False,
                    'field': 'label',
                    'serializer':
                    load_func(settings.WEBHOOK_SERIALIZERS['label']),
                },
            }
        },
        LABEL_LINK_DELETED: {
            'name': _('Label link deleted'),
            'description': _(''),
            'key': 'label_link',
            'many': False,
            'model': LabelLink,
            'serializer': OnlyIDWebhookSerializer,
            'project-field': 'project',
        },
    }

    webhook = models.ForeignKey(Webhook,
                                on_delete=models.CASCADE,
                                related_name='actions')

    action = models.CharField(
        _('action of webhook'),
        choices=[[key, value['name']] for key, value in ACTIONS.items()],
        max_length=128,
        db_index=True,
        help_text=_('Action value'),
    )

    class Meta:
        db_table = 'webhook_action'
        unique_together = [['webhook', 'action']]
Пример #12
0
 def create_organization(cls, created_by=None, title='Your Organization'):
     _create_organization = load_func(settings.CREATE_ORGANIZATION)
     return _create_organization(title=title, created_by=created_by)
Пример #13
0
        from users.models import User

        user_pk = user_or_user_pk.pk if isinstance(user_or_user_pk,
                                                   User) else user_or_user_pk
        return OrganizationMember.objects.get(user=user_pk,
                                              organization=organization_pk)

    @property
    def is_owner(self):
        return self.user.id == self.organization.created_by.id

    class Meta:
        ordering = ['pk']


OrganizationMixin = load_func(settings.ORGANIZATION_MIXIN)


class Organization(OrganizationMixin, models.Model):
    """
    """
    title = models.CharField(_('organization title'),
                             max_length=1000,
                             null=False)

    token = models.CharField(_('token'),
                             max_length=256,
                             default=create_hash,
                             unique=True,
                             null=True,
                             blank=True)
Пример #14
0
                'tasks__annotations__id',
                filter=Q(tasks__annotations__was_cancelled=False) &
                    Q(tasks__annotations__ground_truth=False) &
                    Q(tasks__annotations__result__isnull=False)
            ),
            ground_truth_number=Count(
                'tasks__annotations__id',
                filter=Q(tasks__annotations__ground_truth=True)
            ),
            skipped_annotations_number=Count(
                'tasks__annotations__id',
                filter=Q(tasks__annotations__was_cancelled=True)
            ),
        )

ProjectMixin = load_func(settings.PROJECT_MIXIN)


class Project(ProjectMixin, models.Model):
    """
    """
    objects = ProjectManager()
    __original_label_config = None
    
    title = models.CharField(_('title'), null=True, blank=True, default='', max_length=settings.PROJECT_TITLE_MAX_LEN,
                             help_text=f'Project name. Must be between {settings.PROJECT_TITLE_MIN_LEN} and {settings.PROJECT_TITLE_MAX_LEN} characters long.',
                             validators=[MinLengthValidator(settings.PROJECT_TITLE_MIN_LEN), MaxLengthValidator(settings.PROJECT_TITLE_MAX_LEN)])
    description = models.TextField(_('description'), blank=True, null=True, default='', help_text='Project description')

    organization = models.ForeignKey('organizations.Organization', on_delete=models.CASCADE, related_name='projects', null=True)
    label_config = models.TextField(_('label config'), blank=True, null=True, default='<View></View>',
Пример #15
0
    def get_avatar(self, user):
        return user.avatar_url

    def get_initials(self, user):
        return user.get_initials()

    class Meta:
        model = User
        fields = (
            'id',
            'first_name',
            'last_name',
            'username',
            'email',
            'last_activity',
            'avatar',
            'initials',
            'phone',
            'active_organization',
        )


class UserSimpleSerializer(BaseUserSerializer):
    class Meta:
        model = User
        fields = ('id', 'first_name', 'last_name', 'email', 'avatar')


UserSerializer = load_func(settings.USER_SERIALIZER)
Пример #16
0

class UserLastActivityMixin(models.Model):
    last_activity = models.DateTimeField(_('last activity'),
                                         default=timezone.now,
                                         editable=False)

    def update_last_activity(self):
        self.last_activity = timezone.now()
        self.save(update_fields=["last_activity"])

    class Meta:
        abstract = True


UserMixin = load_func(settings.USER_MIXIN)


class User(UserMixin, AbstractBaseUser, PermissionsMixin,
           UserLastActivityMixin):
    """
    An abstract base class implementing a fully featured User model with
    admin-compliant permissions.

    Username and password are required. Other fields are optional.
    """
    username = models.CharField(_('username'), max_length=256)
    email = models.EmailField(_('email address'), unique=True, blank=True)

    first_name = models.CharField(_('first name'), max_length=256, blank=True)
    last_name = models.CharField(_('last name'), max_length=256, blank=True)
Пример #17
0
 class Meta:
     model = Task
     list_serializer_class = load_func(settings.TASK_SERIALIZER_BULK)
     
     exclude = ()
Пример #18
0
from django.db.models import JSONField
from django.urls import reverse
from django.utils.timesince import timesince
from django.utils.timezone import now
from django.dispatch import receiver, Signal

from model_utils import FieldTracker

from core.utils.common import find_first_one_to_one_related_field_by_prefix, string_is_url, load_func
from core.utils.params import get_env
from data_manager.managers import PreparedTaskManager, TaskManager
from core.bulk_update_utils import bulk_update

logger = logging.getLogger(__name__)

TaskMixin = load_func(settings.TASK_MIXIN)


class Task(TaskMixin, models.Model):
    """ Business tasks from project
    """
    id = models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID', db_index=True)
    data = JSONField('data', null=False, help_text='User imported or uploaded data for a task. Data is formatted according to '
                                                   'the project label config. You can find examples of data for your project '
                                                   'on the Import page in the Label Studio Data Manager UI.')
    meta = JSONField('meta', null=True, default=dict,
                     help_text='Meta is user imported (uploaded) data and can be useful as input for an ML '
                               'Backend for embeddings, advanced vectors, and other info. It is passed to '
                               'ML during training/predicting steps.')
    project = models.ForeignKey('projects.Project', related_name='tasks', on_delete=models.CASCADE, null=True,
                                help_text='Project ID for this task')
Пример #19
0
        fields = ExportSerializer.Meta.fields + [
            'task_filter_options',
            'annotation_filter_options',
            'serialization_options',
        ]

    task_filter_options = TaskFilterOptionsSerializer(required=False, default=None)
    annotation_filter_options = AnnotationFilterOptionsSerializer(required=False, default=None)
    serialization_options = SerializationOptionsSerializer(required=False, default=None)


class ExportParamSerializer(serializers.Serializer):
    interpolate_key_frames = serializers.BooleanField(default=settings.INTERPOLATE_KEY_FRAMES,
                                                      help_text='Interpolate video key frames.',
                                                      required=False)
    download_resources = serializers.BooleanField(default=settings.CONVERTER_DOWNLOAD_RESOURCES,
                                                  help_text='Download resources in converter.',
                                                  required=False)
    # deprecated param to delete
    export_type = serializers.CharField(default='JSON',
                                        help_text='Export file format.',
                                        required=False)
    exportType = serializers.CharField(help_text='Export file format.',
                                        required=False)
    download_all_tasks = serializers.BooleanField(default=False,
                                                  help_text='Download all tasks or only finished.',
                                                  required=False)


ExportDataSerializer = load_func(settings.EXPORT_DATA_SERIALIZER)