Browse Source

Pass type check

pull/1206/head
Hironsan 4 years ago
parent
commit
d98eca5800
10 changed files with 139 additions and 135 deletions
  1. 4
      app/api/views.py
  2. 136
      frontend/components/containers/settings/ConfigCreationForm.vue
  3. 30
      frontend/components/containers/settings/form/ConfigLabelMapping.vue
  4. 2
      frontend/components/containers/settings/form/LabelMapping.vue
  5. 48
      frontend/models/config/config-item-list.ts
  6. 13
      frontend/models/config/config-template.ts
  7. 8
      frontend/models/stepper.ts
  8. 17
      frontend/repositories/config/api.ts
  9. 6
      frontend/repositories/config/interface.ts
  10. 10
      frontend/services/application/config.service.ts

4
app/api/views.py

@ -596,6 +596,8 @@ class AutoLabelingConfigParameterTest(APIView):
return Response(response, status=status.HTTP_200_OK)
except requests.exceptions.ConnectionError:
raise URLConnectionError
except botocore.exceptions.ClientError:
raise AWSTokenError()
except Exception as e:
raise e
@ -613,6 +615,8 @@ class AutoLabelingTemplateTest(APIView):
template=template
)
labels = template.render(response)
if not labels.dict():
raise SampleDataException()
return Response(labels.dict(), status=status.HTTP_200_OK)

136
frontend/components/containers/settings/ConfigCreationForm.vue

@ -7,12 +7,12 @@
</v-overlay>
<config-header :step="step.count" />
<config-template-name
v-model="templateConfig"
v-model="fields"
@next="step.next()"
/>
<config-parameters
v-if="templateConfig.model_attrs !== undefined"
v-model="templateConfig.model_attrs"
v-if="fields.modelAttrs !== undefined"
v-model="fields.modelAttrs"
:is-passed="passTesting.parameter"
:error-messages="errors"
:response="response.parameter"
@ -22,7 +22,7 @@
/>
<config-template
v-model="templateConfig.template"
v-model="fields.template"
:is-passed="passTesting.template"
:error-messages="errors"
:response="response.parameter"
@ -33,9 +33,11 @@
/>
<config-label-mapping
v-model="labelMapping"
:error-messages="errors"
v-model="fields.labelMapping"
:is-passed="passTesting.mapping"
:error-messages="errors"
:response="response.template"
:result="response.mapping"
@prev="step.prev()"
@next="saveConfig"
@onTest="testMapping"
@ -47,7 +49,7 @@
import Vue from 'vue'
import { FromApiConfigItemListRepository } from '@/repositories/config/api'
import { ConfigApplicationService } from '@/services/application/config.service'
import { ConfigItem, Parameters } from '@/models/config/config-item-list'
import { ConfigItem, Fields } from '@/models/config/config-item-list'
import { StepCounter } from '@/models/stepper'
import ConfigHeader from './form/ConfigHeader.vue'
import ConfigTemplateName from './form/ConfigTemplateName.vue'
@ -58,24 +60,24 @@ import ConfigLabelMapping from './form/ConfigLabelMapping.vue'
export default Vue.extend({
components: {
ConfigHeader,
ConfigTemplate,
ConfigTemplateName,
ConfigLabelMapping,
ConfigParameters,
ConfigLabelMapping
ConfigTemplate,
ConfigTemplateName
},
data() {
return {
config: {} as ConfigItem,
errors: [] as string[],
fields: {} as Fields,
isLoading: false,
step: new StepCounter(),
passTesting: {
parameter: false,
template: false,
mapping: false
},
step: new StepCounter(1, 4),
templateConfig: {},
labelMapping: [],
response: {
parameter: [],
template: [],
@ -93,87 +95,63 @@ export default Vue.extend({
},
watch: {
templateConfig: {
handler() {
// this.passTesting = false
},
deep: true
}
'fields.modelName'() {
this.passTesting = {parameter: false, template: false, mapping: false}
},
'fields.modelAttrs': {
handler() {
this.passTesting = {parameter: false, template: false, mapping: false}
},
deep: true
},
'fields.template'() {
this.passTesting = {parameter: true, template: false, mapping: false}
},
'fields.labelMapping': {
handler() {
this.passTesting = {parameter: true, template: true, mapping: false}
},
deep: true
},
},
methods: {
createConfig() {
const payload = {
// @ts-ignore
modelName: this.templateConfig.model_name,
// @ts-ignore
modelAttrs: this.templateConfig.model_attrs,
// @ts-ignore
template: this.templateConfig.template,
// @ts-ignore
labelMapping: this.labelMapping
}
return ConfigItem.parseFromUI(payload)
},
testMapping() {
const projectId = this.$route.params.id
const item = this.createConfig()
testConfig(promise: Promise<any>, key: 'parameter'|'template'|'mapping') {
this.isLoading = true
this.configService.testMapping(projectId, item, this.response.template)
.then((value) => {
this.passTesting.mapping = true
// @ts-ignore
this.response.mapping = value
})
.catch((error) => {
this.errors = [error.message]
})
.finally(() => {
this.isLoading = false
})
promise.then((value) => {
this.response[key] = value
this.passTesting[key] = true
this.errors = []
}).catch((error) => {
this.errors = [error.message]
}).finally(() => {
this.isLoading = false
})
},
testParameters(text: string) {
// @ts-ignore
const item = Parameters.parse(this.templateConfig.model_attrs)
this.isLoading = true
// @ts-ignore
this.configService.testParameters(this.templateConfig.model_name, item, text)
.then((value) => {
// @ts-ignore
this.response.parameter = value
this.passTesting.parameter = true
})
.catch((error) => {
this.errors = [error.message]
})
.finally(() => {
this.isLoading = false
})
const item = ConfigItem.parseFromUI(this.fields)
const promise = this.configService.testParameters(item, text)
this.testConfig(promise, 'parameter')
},
testTemplate() {
const projectId = this.$route.params.id
this.isLoading = true
this.errors = []
// @ts-ignore
this.configService.testTemplate(projectId, this.response.parameter, this.templateConfig.template)
.then((value) => {
// @ts-ignore
this.response.template = value
this.passTesting.template = true
})
.catch((error) => {
this.errors = [error.message]
})
.finally(() => {
this.isLoading = false
})
const item = ConfigItem.parseFromUI(this.fields)
const promise = this.configService.testTemplate(projectId, this.response.parameter, item)
this.testConfig(promise, 'template')
},
testMapping() {
const projectId = this.$route.params.id
const item = ConfigItem.parseFromUI(this.fields)
const promise = this.configService.testMapping(projectId, item, this.response.template)
this.testConfig(promise, 'mapping')
},
saveConfig() {
const projectId = this.$route.params.id
const item = this.createConfig()
const item = ConfigItem.parseFromUI(this.fields)
this.isLoading = true
this.configService.save(projectId, item)
.then(() => {
this.step.first()
this.$emit('onCreate')
})
.finally(() => {

30
frontend/components/containers/settings/form/ConfigLabelMapping.vue

@ -4,8 +4,18 @@
<v-card-text class="pa-0">
<h4 class="text-h6">Configure label mappings</h4>
<p class="font-weight-regular body-1">
Once you fetch the API response, you can convert the label into the defined one.
Once you fetch the API response, you need to convert the label in the response into the one which you defined at the label page.
</p>
<h4 class="text-h6">
Response
</h4>
<v-sheet
:dark="!$vuetify.theme.dark"
:light="$vuetify.theme.dark"
class="mb-5 pa-5"
>
<pre>{{ JSON.stringify(response, null, 4) }}</pre>
</v-sheet>
<label-mapping v-model="mapping" />
<v-alert
v-for="(error, index) in errorMessages"
@ -19,6 +29,16 @@
</v-col>
</v-row>
</v-alert>
<h4 class="text-h6">
Result
</h4>
<v-sheet
:dark="!$vuetify.theme.dark"
:light="$vuetify.theme.dark"
class="mb-5 pa-5"
>
<pre>{{ JSON.stringify(result, null, 4) }}</pre>
</v-sheet>
</v-card-text>
<v-card-actions class="pa-0">
<v-spacer />
@ -39,7 +59,7 @@
</v-btn>
<v-btn
v-show="isPassed"
color="primary"
color="success"
class="text-capitalize"
@click="$emit('next')"
>
@ -74,15 +94,19 @@ export default Vue.extend({
type: Boolean,
default: false,
required: true
}
},
response: [String, Object, Array],
result: Array
},
computed: {
mapping: {
get() {
// @ts-ignore
return this.value
},
set(newVal) {
// @ts-ignore
this.$emit('input', newVal)
}
}

2
frontend/components/containers/settings/form/LabelMapping.vue

@ -179,6 +179,8 @@ export default Vue.extend({
this.editedItem = Object.assign({}, item)
const items = Object.assign([], this.value)
items.splice(this.editedIndex, 1)
this.editedItem = Object.assign({}, this.defaultItem)
this.editedIndex = -1
this.$emit('input', items)
},

48
frontend/models/config/config-item-list.ts

@ -10,6 +10,25 @@ export class ConfigItemList {
}
}
interface LabelMappingForUI {
from: string,
to: string
}
export interface ParametersForUI {
name: string,
value: string | object[],
type?: string,
items?: string[]
}
export interface Fields {
modelName: string,
modelAttrs: ParametersForUI[],
template: string,
labelMapping: LabelMappingForUI[]
}
export class ConfigItem {
constructor(
public id: number,
@ -27,14 +46,7 @@ export class ConfigItem {
}
static parseFromUI(
{ modelName, modelAttrs, template, labelMapping }:
{
modelName: string,
modelAttrs: {'name': string, 'value': string}[],
template: string,
labelMapping: {'from': string, 'to': string}[]
}
): ConfigItem {
{ modelName, modelAttrs, template, labelMapping }: Fields): ConfigItem {
const mapping = labelMapping.reduce((a, x) => ({...a, [x.from]: x.to}), {})
const attributes: {[key: string]: any} = modelAttrs.reduce((a, x) => ({...a, [x.name]: x.value}), {})
for (const [key, value] of Object.entries(attributes)) {
@ -65,23 +77,3 @@ export class ConfigItem {
}
}
}
export class Parameters {
constructor(
private readonly parameters: { [key: string]: any }
) {}
static parse(parameters: {'name': string, 'value': string}[]): Parameters {
const _parameters: {[key: string]: any} = parameters.reduce((a, x) => ({...a, [x.name]: x.value}), {})
for (const [key, value] of Object.entries(_parameters)) {
if (Array.isArray(value)) {
_parameters[key] = value.reduce((a, x) => ({...a, [x.key]: x.value}), {})
}
}
return new Parameters(_parameters)
}
toObject(): object {
return this.parameters
}
}

13
frontend/models/config/config-template.ts

@ -1,3 +1,5 @@
import { Fields, ParametersForUI } from '@/models/config/config-item-list'
export interface Schema {
title: string,
type: string,
@ -27,8 +29,8 @@ export class ConfigTemplateItem {
return this.schema.title
}
get fields() {
const response = []
get fields(): ParametersForUI[] {
const response: ParametersForUI[] = []
for (const [key, value] of Object.entries(this.schema.properties)) {
if ('type' in value && value.type === 'string') {
response.push({name: key, type: 'textField', value: ''})
@ -56,11 +58,12 @@ export class ConfigTemplateItem {
return response
}
toObject(): Object {
toObject(): Fields {
return {
model_name: this.modelName,
modelName: this.modelName,
template: this.template,
model_attrs: this.fields
modelAttrs: this.fields,
labelMapping: []
}
}
}

8
frontend/models/stepper.ts

@ -30,6 +30,14 @@ export class StepCounter {
this.step = Math.max(this.step - 1, this.minStep)
}
first(): void {
this.step = this.minStep
}
last(): void {
this.step = this.maxStep
}
hasNext(): boolean {
return this.step !== this.maxStep
}

17
frontend/repositories/config/api.ts

@ -1,6 +1,6 @@
import ApiService from '@/services/api.service'
import { ConfigItemListRepository, ConfigTestResponse } from '@/repositories/config/interface'
import { ConfigItemList, ConfigItem, Parameters } from '@/models/config/config-item-list'
import { ConfigItemList, ConfigItem } from '@/models/config/config-item-list'
export interface ConfigItemResponse {
id: number,
@ -61,24 +61,17 @@ export class FromApiConfigItemListRepository implements ConfigItemListRepository
return responseItem
}
async testParameters(modelName: string, parameters: Parameters, text: string) {
async testParameters(item: ConfigItem, text: string) {
const url = 'auto-labeling-parameter-testing'
const response = await this.request.post(
url,
{
text,
model_name: modelName,
model_attrs: parameters.toObject()
}
)
const response = await this.request.post(url, {...item.toAPI(), text})
const responseItem: ConfigTestResponse = response.data
return responseItem
}
async testTemplate(projectId: string, response: any, template: string): Promise<ConfigTestResponse> {
async testTemplate(projectId: string, response: any, item: ConfigItem): Promise<ConfigTestResponse> {
console.log(projectId)
const url = `/projects/${projectId}/auto-labeling-template-testing`
const _response = await this.request.post(url, { response, template })
const _response = await this.request.post(url, { response, ...item.toAPI() })
const responseItem: ConfigTestResponse = _response.data
return responseItem
}

6
frontend/repositories/config/interface.ts

@ -1,4 +1,4 @@
import { ConfigItem, ConfigItemList, Parameters } from '@/models/config/config-item-list'
import { ConfigItem, ConfigItemList } from '@/models/config/config-item-list'
export interface ConfigTestResponse {
valid: boolean,
@ -16,9 +16,9 @@ export interface ConfigItemListRepository {
testConfig(projectId: string, item: ConfigItem, text: string): Promise<ConfigTestResponse>
testParameters(modelName: string, parameters: Parameters, text: string): Promise<ConfigTestResponse>
testParameters(item: ConfigItem, text: string): Promise<ConfigTestResponse>
testTemplate(projectId: string, response: any, template: string): Promise<ConfigTestResponse>
testTemplate(projectId: string, response: any, item: ConfigItem): Promise<ConfigTestResponse>
testMapping(projectId: string, item: ConfigItem, response: any): Promise<ConfigTestResponse>
}

10
frontend/services/application/config.service.ts

@ -1,4 +1,4 @@
import { ConfigItemList, ConfigItem, Parameters } from '@/models/config/config-item-list'
import { ConfigItemList, ConfigItem } from '@/models/config/config-item-list'
import { ConfigItemListRepository, ConfigTestResponse } from '@/repositories/config/interface'
export class ConfigApplicationService {
@ -37,8 +37,8 @@ export class ConfigApplicationService {
})
}
public testParameters(modelName: string, parameters: Parameters, text: string) {
return this.configRepository.testParameters(modelName, parameters, text)
public testParameters(item: ConfigItem, text: string) {
return this.configRepository.testParameters(item, text)
.then((value) => {
return value
})
@ -48,8 +48,8 @@ export class ConfigApplicationService {
})
}
public testTemplate(projectId: string, response: any, template: string) {
return this.configRepository.testTemplate(projectId, response, template)
public testTemplate(projectId: string, response: any, item: ConfigItem) {
return this.configRepository.testTemplate(projectId, response, item)
.then((value) => {
return value
})

Loading…
Cancel
Save