Skip to content
This repository has been archived by the owner on Feb 23, 2022. It is now read-only.

Commit

Permalink
Merge pull request #94 from multinet-app/csv_validation
Browse files Browse the repository at this point in the history
[WIP] Add CSV validation at rest endpoint, and catch response on front-end
  • Loading branch information
jjnesbitt committed Jul 23, 2019
2 parents d5cb8bd + dc51abc commit ec34b29
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 20 deletions.
24 changes: 15 additions & 9 deletions client/src/views/WorkspaceDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
<v-card-text>
<v-layout row wrap>
<v-flex>
<v-text-field v-model="newTable" placeholder="name your table" solo />
<v-text-field v-model="newTable" placeholder="name your table" solo :error-messages="tableCreationErrors"/>
</v-flex>
</v-layout>
<v-layout row wrap>
Expand Down Expand Up @@ -205,6 +205,7 @@ export default {
selectedType: null,
graphNodeTables: [],
graphEdgeTable: null,
tableCreationErrors: [],
}
},
computed: {
Expand Down Expand Up @@ -258,15 +259,20 @@ export default {
async createTable(){
let queryType = this.fileTypes[this.selectedType].queryCall;
await api().post(`multinet/${queryType}/${this.workspace}/${this.newTable}`,
this.fileList[0],
{
headers: {
'Content-Type': 'text/plain'
},
try {
await api().post(`multinet/${queryType}/${this.workspace}/${this.newTable}`,
this.fileList[0],
{
headers: {
'Content-Type': 'text/plain'
},
}
);
this.tableCreationErrors = [];
this.update()
} catch(err) {
this.tableCreationErrors.push(err.response.data.message);
}
)
this.update()
},
async createGraph () {
Expand Down
9 changes: 9 additions & 0 deletions multinet/multinet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from girder.api import access
from girder.api.rest import Resource, getBodyJson
from girder.api.describe import Description, autoDescribeRoute
from girder.exceptions import RestException

import csv
from io import StringIO
Expand Down Expand Up @@ -80,6 +81,7 @@ def graphql(self, params):
.param('workspace', 'Target workspace', required=True)
.param('table', 'Target table', required=True)
.param('data', 'CSV data', paramType='body', required=True)
.errorResponse()
)
def bulk(self, params, workspace=None, table=None):
"""
Expand All @@ -93,6 +95,13 @@ def bulk(self, params, workspace=None, table=None):
rows = csv.DictReader(StringIO(cherrypy.request.body.read().decode('utf8')))
workspace = db.db(workspace)

# Check for key uniqueness
if ('_key' in rows.fieldnames):
keys = [row['_key'] for row in rows]
uniqueKeys = set(keys)
if len(keys) != len(uniqueKeys):
raise RestException('CSV Validation Failed: Non-unique key detected.')

# Set the collection, paying attention to whether the data contains
# _from/_to fields.
coll = None
Expand Down
2 changes: 1 addition & 1 deletion multinet/multinet/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def workspace_graph(workspace, name, arango=None):
def table_fields(query, arango=None):
"""Return a list of column names for table `query.table` in workspace `query.workspace`."""
workspace = db(query.workspace, arango=arango)
if workspace.has_collection(query.table):
if workspace.has_collection(query.table) and workspace.collection(query.table).count() > 0:
sample = workspace.collection(query.table).random()
return sample.keys()
else:
Expand Down
22 changes: 12 additions & 10 deletions multinet/multinet/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@
from graphql import build_ast_schema
from graphql.language.parser import parse

from .resolvers import attribute
from .resolvers import properties
from .resolvers import entity_type
from .resolvers import entity
from .resolvers import pagedlist
from .resolvers import table
from .resolvers import graph
from .resolvers import workspace
from .resolvers import query
from .resolvers import mutation
from .resolvers import (
attribute,
properties,
entity_type,
entity,
pagedlist,
table,
graph,
workspace,
query,
mutation
)

schema_text = None
with open(os.path.join(os.path.dirname(__file__), 'multinet.gql')) as f:
Expand Down
8 changes: 8 additions & 0 deletions test/data/clubs_invalid.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
_key,name
5,St Andrews Lodge
1,Loyal Nine
2,North Caucus
3,Long Room Club
4,Tea Party
5,Boston Committee
2,London Enemies

0 comments on commit ec34b29

Please sign in to comment.