Skip to content

Commit

Permalink
Merge pull request #1632 from doccano/enhancement/refactorProjectModel
Browse files Browse the repository at this point in the history
[Enhancement] refactor project model and serializer
  • Loading branch information
Hironsan committed Jan 14, 2022
2 parents fb459c2 + 9cb7abd commit 69511c3
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 68 deletions.
94 changes: 79 additions & 15 deletions backend/api/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import abc
import random
import string
import uuid
from typing import Literal

from auto_labeling_pipeline.models import RequestModelFactory
from django.contrib.auth.models import User
Expand Down Expand Up @@ -39,49 +39,113 @@ class Project(PolymorphicModel):
collaborative_annotation = models.BooleanField(default=False)
single_class_classification = models.BooleanField(default=False)

def is_task_of(self, task: Literal['text', 'image', 'speech']):
raise NotImplementedError()
@property
@abc.abstractmethod
def is_text_project(self) -> bool:
return False

@property
def can_define_label(self) -> bool:
"""Whether or not the project can define label(ignoring the type of label)"""
return False

@property
def can_define_relation(self) -> bool:
"""Whether or not the project can define relation."""
return False

@property
def can_define_category(self) -> bool:
"""Whether or not the project can define category."""
return False

@property
def can_define_span(self) -> bool:
"""Whether or not the project can define span."""
return False

def __str__(self):
return self.name


class TextClassificationProject(Project):

def is_task_of(self, task: Literal['text', 'image', 'speech']):
return task == 'text'
@property
def is_text_project(self) -> bool:
return True

@property
def can_define_label(self) -> bool:
return True

@property
def can_define_category(self) -> bool:
return True


class SequenceLabelingProject(Project):
allow_overlapping = models.BooleanField(default=False)
grapheme_mode = models.BooleanField(default=False)

def is_task_of(self, task: Literal['text', 'image', 'speech']):
return task == 'text'
@property
def is_text_project(self) -> bool:
return True

@property
def can_define_label(self) -> bool:
return True

@property
def can_define_span(self) -> bool:
return True


class Seq2seqProject(Project):

def is_task_of(self, task: Literal['text', 'image', 'speech']):
return task == 'text'
@property
def is_text_project(self) -> bool:
return True


class IntentDetectionAndSlotFillingProject(Project):

def is_task_of(self, task: Literal['text', 'image', 'speech']):
return task == 'text'
@property
def is_text_project(self) -> bool:
return True

@property
def can_define_label(self) -> bool:
return True

@property
def can_define_category(self) -> bool:
return True

@property
def can_define_span(self) -> bool:
return True


class Speech2textProject(Project):

def is_task_of(self, task: Literal['text', 'image', 'speech']):
return task == 'speech'
@property
def is_text_project(self) -> bool:
return False


class ImageClassificationProject(Project):

def is_task_of(self, task: Literal['text', 'image', 'speech']):
return task == 'image'
@property
def is_text_project(self) -> bool:
return False

@property
def can_define_label(self) -> bool:
return True

@property
def can_define_category(self) -> bool:
return True


def generate_random_hex_color():
Expand Down
10 changes: 10 additions & 0 deletions backend/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,21 @@ class Meta:
'random_order',
'collaborative_annotation',
'single_class_classification',
'is_text_project',
'can_define_label',
'can_define_relation',
'can_define_category',
'can_define_span',
'tags'
)
read_only_fields = (
'updated_at',
'users',
'is_text_project',
'can_define_label',
'can_define_relation',
'can_define_category',
'can_define_span',
'tags'
)

Expand Down
4 changes: 2 additions & 2 deletions backend/api/views/auto_labeling.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def send_request(self, model, example):

def prepare_example(self):
text = self.request.data['text']
if self.project.is_task_of('text'):
if self.project.is_text_project:
return text
else:
tu = TemporaryUpload.objects.get(upload_id=text)
Expand Down Expand Up @@ -221,7 +221,7 @@ def perform_create(self, serializer):

def get_example(self, project):
example = get_object_or_404(Example, pk=self.kwargs['example_id'])
if project.is_task_of('text'):
if project.is_text_project:
return example.text
else:
return str(example.filename)
Expand Down
79 changes: 28 additions & 51 deletions frontend/domain/models/project/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ export class ProjectReadItem {
public allow_overlapping: boolean,
public grapheme_mode: boolean,
public tags: Object[],
public is_text_project: boolean,
public can_define_label: boolean,
public can_define_relation: boolean,
public can_define_span: boolean,
public can_define_category: boolean,
) {}

static valueOf(
Expand All @@ -34,7 +39,12 @@ export class ProjectReadItem {
resourcetype,
allow_overlapping,
grapheme_mode,
tags
tags,
is_text_project,
can_define_label,
can_define_relation,
can_define_span,
can_define_category,
}:
{
id: number,
Expand All @@ -50,7 +60,12 @@ export class ProjectReadItem {
resourcetype: string,
allow_overlapping: boolean,
grapheme_mode: boolean,
tags: Object[]
tags: Object[],
is_text_project: boolean,
can_define_label: boolean,
can_define_relation: boolean,
can_define_span: boolean,
can_define_category: boolean
}
): ProjectReadItem {
return new ProjectReadItem(
Expand All @@ -67,7 +82,12 @@ export class ProjectReadItem {
resourcetype,
allow_overlapping,
grapheme_mode,
tags
tags,
is_text_project,
can_define_label,
can_define_relation,
can_define_span,
can_define_category
)
}

Expand All @@ -85,66 +105,23 @@ export class ProjectReadItem {
}

get canDefineLabel() {
const allowedProjectTypes = [
'DocumentClassification',
'SequenceLabeling',
'IntentDetectionAndSlotFilling',
'ImageClassification'
]
return allowedProjectTypes.includes(this.project_type)
return this.can_define_label
}

get canDefineRelation() {
const allowedProjectTypes = [
'SequenceLabeling'
]
return allowedProjectTypes.includes(this.project_type)
return this.can_define_relation
}

get isTextProject() {
const allowedProjectTypes = [
'DocumentClassification',
'SequenceLabeling',
'Seq2seq',
'IntentDetectionAndSlotFilling'
]
return allowedProjectTypes.includes(this.project_type)
return this.is_text_project
}

get hasCategory(): boolean {
const allowedProjectTypes = [
'DocumentClassification',
'IntentDetectionAndSlotFilling',
'ImageClassification'
]
return allowedProjectTypes.includes(this.project_type)
return this.can_define_category
}

get hasSpan(): boolean {
const allowedProjectTypes = [
'IntentDetectionAndSlotFilling',
'SequenceLabeling'
]
return allowedProjectTypes.includes(this.project_type)
}

toObject(): Object {
return {
id: this.id,
name: this.name,
description: this.description,
guideline: this.guideline,
users: this.users,
project_type: this.project_type,
updated_at: this.updated_at,
random_order: this.random_order,
collaborative_annotation: this.collaborative_annotation,
single_class_classification: this.single_class_classification,
resourcetype: this.resourcetype,
allow_overlapping: this.allow_overlapping,
grapheme_mode: this.grapheme_mode,
tags: this.tags
}
return this.can_define_span
}
}

Expand Down

0 comments on commit 69511c3

Please sign in to comment.