Browse Source

Implement auto labeling setting

pull/1206/head
Hironsan 4 years ago
parent
commit
c7fded9aa4
6 changed files with 121 additions and 5 deletions
  1. 5
      app/api/exceptions.py
  2. 6
      app/api/views.py
  3. 70
      frontend/components/containers/annotation/Settings.vue
  4. 20
      frontend/layouts/annotation.vue
  5. 4
      frontend/services/annotation.service.js
  6. 21
      frontend/store/documents.js

5
app/api/exceptions.py

@ -10,3 +10,8 @@ class FileParseException(APIException):
def __init__(self, line_num, line, code=None):
detail = self.default_detail.format(line_num, line)
super().__init__(detail, code)
class AutoLabelingException(APIException):
status_code = status.HTTP_400_BAD_REQUEST
default_detail = 'Auto labeling not allowed for the document with labels.'

6
app/api/views.py

@ -25,6 +25,7 @@ from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser
from rest_framework_csv.renderers import CSVRenderer
from .exceptions import AutoLabelingException
from .filters import DocumentFilter
from .models import Project, Label, Document, RoleMapping, Role, Comment, AutoLabelingConfig
from .permissions import IsProjectAdmin, IsAnnotatorAndReadOnly, IsAnnotator, IsAnnotationApproverAndReadOnly, IsOwnAnnotation, IsAnnotationApprover, IsOwnComment
@ -595,6 +596,9 @@ class AutoLabelingAnnotation(generics.CreateAPIView):
return queryset
def create(self, request, *args, **kwargs):
queryset = self.get_queryset()
if queryset.exists():
raise AutoLabelingException()
labels = self.extract()
labels = self.transform(labels)
serializer = self.get_serializer(data=labels, many=True)
@ -609,7 +613,7 @@ class AutoLabelingAnnotation(generics.CreateAPIView):
def extract(self):
project = get_object_or_404(Project, pk=self.kwargs['project_id'])
doc = get_object_or_404(Document, pk=self.kwargs['doc_id'])
config = project.auto_labeling_config.get(default=True)
config = project.auto_labeling_config.first()
task = TaskFactory.create(project.project_type)
model = RequestModelFactory.create(
model_name=config.model_name,

70
frontend/components/containers/annotation/Settings.vue

@ -0,0 +1,70 @@
<template>
<div style="display:inline;">
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn
class="text-capitalize ps-1 pe-1"
min-width="36"
icon
v-on="on"
@click="dialog=true"
>
<v-icon>
mdi-cog-outline
</v-icon>
</v-btn>
</template>
<span>Settings</span>
</v-tooltip>
<v-dialog
v-model="dialog"
width="800"
>
<base-card
title="Settings"
:cancel-text="$t('generic.close')"
@cancel="dialog=false"
>
<template #content>
<v-switch
v-model="value.onAutoLabeling"
label="Auto Labeling"
/>
</template>
</base-card>
</v-dialog>
</div>
</template>
<script>
import BaseCard from '@/components/molecules/BaseCard'
export default {
components: {
BaseCard
},
data() {
return {
dialog: false
}
},
props: {
value: {
type: Object,
default: () => {},
required: true
}
},
watch: {
value: {
handler(val) {
this.$emit('input', val)
},
deep: true
}
}
}
</script>

20
frontend/layouts/annotation.vue

@ -41,6 +41,7 @@
<guideline-button />
<comment-button />
<clear-annotations-button />
<settings v-model="options" />
</v-col>
<v-spacer />
<v-col>
@ -84,6 +85,7 @@ import CommentButton from '@/components/containers/annotation/CommentButton'
import Pagination from '~/components/containers/annotation/Pagination'
import TheHeader from '~/components/organisms/layout/TheHeader'
import TheSideBar from '~/components/organisms/layout/TheSideBar'
import Settings from '~/components/containers/annotation/Settings.vue'
export default {
middleware: ['check-auth', 'auth', 'set-project'],
@ -98,7 +100,8 @@ export default {
ApproveButton,
MetadataBox,
ClearAnnotationsButton,
CommentButton
CommentButton,
Settings
},
fetch() {
@ -115,7 +118,10 @@ export default {
data() {
return {
drawerLeft: null,
limit: 10
limit: 10,
options: {
onAutoLabeling: false
}
}
},
@ -187,16 +193,24 @@ export default {
current: {
handler() {
this.setCurrent(this.current)
if (this.options.onAutoLabeling) {
this.autoLabeling({ projectId: this.$route.params.id })
}
},
immediate: true
},
searchOptions() {
this.saveSearchOptions(JSON.parse(this.searchOptions))
},
"options.onAutoLabeling": function(val) {
if (val) {
this.autoLabeling({ projectId: this.$route.params.id })
}
}
},
methods: {
...mapActions('documents', ['getDocumentList']),
...mapActions('documents', ['getDocumentList', 'autoLabeling']),
...mapMutations('documents', ['setCurrent']),
...mapMutations('projects', ['saveSearchOptions'])
}

4
frontend/services/annotation.service.js

@ -24,6 +24,10 @@ class AnnotationService {
updateAnnotation(projectId, docId, annotationId, payload) {
return this.request.patch(`/projects/${projectId}/docs/${docId}/annotations/${annotationId}`, payload)
}
autoLabel(projectId, docId) {
return this.request.post(`/projects/${projectId}/docs/${docId}/auto-labeling`)
}
}
export default new AnnotationService()

21
frontend/store/documents.js

@ -64,6 +64,9 @@ export const mutations = {
addAnnotation(state, payload) {
state.items[state.current].annotations.push(payload)
},
setAnnotations(state, payload) {
state.items[state.current].annotations = payload
},
deleteAnnotation(state, annotationId) {
state.items[state.current].annotations = state.items[state.current].annotations.filter(item => item.id !== annotationId)
},
@ -263,5 +266,21 @@ export const actions = {
.catch((error) => {
alert(error)
})
}
},
autoLabeling({ commit, state }, payload) {
const document = state.items[state.current]
if (document) {
commit('setLoading', true)
AnnotationService.autoLabel(payload.projectId, document.id)
.then((response) => {
commit('setAnnotations', response.data)
})
.catch((error) => {
console.log(error)
})
.finally(() => {
commit('setLoading', false)
})
}
},
}
Loading…
Cancel
Save