1
0
mirror of https://github.com/gsi-upm/senpy synced 2024-11-22 16:12:29 +00:00

Fix schema issues and parameter validation

This commit is contained in:
J. Fernando Sánchez 2018-05-14 11:38:02 +02:00
parent 73f7cbbe8a
commit d7acf3d67a
9 changed files with 49 additions and 21 deletions

View File

@ -6,8 +6,6 @@ RUN apt-get update && apt-get install -y \
libblas-dev liblapack-dev liblapacke-dev gfortran \ libblas-dev liblapack-dev liblapacke-dev gfortran \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir --upgrade numpy scipy scikit-learn
RUN mkdir /cache/ /senpy-plugins /data/ RUN mkdir /cache/ /senpy-plugins /data/
VOLUME /data/ VOLUME /data/

View File

@ -9,3 +9,6 @@ jsonref
PyYAML PyYAML
rdflib rdflib
rdflib-jsonld rdflib-jsonld
numpy
scipy
scikit-learn

View File

@ -147,7 +147,7 @@ def parse_params(indict, *specs):
for param, options in iteritems(spec): for param, options in iteritems(spec):
for alias in options.get("aliases", []): for alias in options.get("aliases", []):
# Replace each alias with the correct name of the parameter # Replace each alias with the correct name of the parameter
if alias in indict and alias is not param: if alias in indict and alias != param:
outdict[param] = indict[alias] outdict[param] = indict[alias]
del outdict[alias] del outdict[alias]
continue continue

View File

@ -19,7 +19,7 @@ Blueprints for Senpy
""" """
from flask import (Blueprint, request, current_app, render_template, url_for, from flask import (Blueprint, request, current_app, render_template, url_for,
jsonify) jsonify)
from .models import Error, Response, Help, Plugins, read_schema, Datasets from .models import Error, Response, Help, Plugins, read_schema, dump_schema, Datasets
from . import api from . import api
from .version import __version__ from .version import __version__
from functools import wraps from functools import wraps
@ -67,9 +67,9 @@ def index():
@api_blueprint.route('/schemas/<schema>') @api_blueprint.route('/schemas/<schema>')
def schema(schema="definitions"): def schema(schema="definitions"):
try: try:
return jsonify(read_schema(schema)) return dump_schema(read_schema(schema))
except Exception: # Should be FileNotFoundError, but it's missing from py2 except Exception as ex: # Should be FileNotFoundError, but it's missing from py2
return Error(message="Schema not found", status=404).flask() return Error(message="Schema not found: {}".format(ex), status=404).flask()
def basic_api(f): def basic_api(f):
@ -133,6 +133,7 @@ def api_root():
req = api.parse_call(request.parameters) req = api.parse_call(request.parameters)
return current_app.senpy.analyse(req) return current_app.senpy.analyse(req)
@api_blueprint.route('/evaluate/', methods=['POST', 'GET']) @api_blueprint.route('/evaluate/', methods=['POST', 'GET'])
@basic_api @basic_api
def evaluate(): def evaluate():
@ -145,6 +146,7 @@ def evaluate():
response = current_app.senpy.evaluate(params) response = current_app.senpy.evaluate(params)
return response return response
@api_blueprint.route('/plugins/', methods=['POST', 'GET']) @api_blueprint.route('/plugins/', methods=['POST', 'GET'])
@basic_api @basic_api
def plugins(): def plugins():
@ -163,10 +165,10 @@ def plugin(plugin=None):
return sp.get_plugin(plugin) return sp.get_plugin(plugin)
@api_blueprint.route('/datasets/', methods=['POST','GET']) @api_blueprint.route('/datasets/', methods=['POST', 'GET'])
@basic_api @basic_api
def datasets(): def datasets():
sp = current_app.senpy sp = current_app.senpy
datasets = sp.datasets datasets = sp.datasets
dic = Datasets(datasets = list(datasets.values())) dic = Datasets(datasets=list(datasets.values()))
return dic return dic

View File

@ -51,6 +51,10 @@ def read_schema(schema_file, absolute=False):
return jsonref.load(f, base_uri=schema_uri) return jsonref.load(f, base_uri=schema_uri)
def dump_schema(schema):
return jsonref.dumps(schema)
def load_context(context): def load_context(context):
logging.debug('Loading context: {}'.format(context)) logging.debug('Loading context: {}'.format(context))
if not context: if not context:

View File

@ -19,8 +19,6 @@ import importlib
import yaml import yaml
import threading import threading
import numpy as np
from .. import models, utils from .. import models, utils
from .. import api from .. import api
@ -49,11 +47,11 @@ class PluginMeta(models.BaseMeta):
attrs['name'] = alias attrs['name'] = alias
if 'description' not in attrs: if 'description' not in attrs:
doc = attrs.get('__doc__', None) doc = attrs.get('__doc__', None)
if not doc: if doc:
raise Exception(('Please, add a description or ' attrs['description'] = doc
'documentation to class {}').format(name)) else:
attrs['description'] = doc logger.warn(('Plugin {} does not have a description. '
attrs['name'] = alias 'Please, add a short summary to help other developers').format(name))
cls = super(PluginMeta, mcs).__new__(mcs, name, bases, attrs) cls = super(PluginMeta, mcs).__new__(mcs, name, bases, attrs)
if alias in mcs._classes: if alias in mcs._classes:
@ -291,7 +289,7 @@ class Box(AnalysisPlugin):
return self return self
def transform(self, X): def transform(self, X):
return np.array([self.predict_one(x) for x in X]) return [self.predict_one(x) for x in X]
def predict(self, X): def predict(self, X):
return self.transform(X) return self.transform(X)

View File

@ -1,6 +1,6 @@
{ {
"$schema": "http://json-schema.org/draft-04/schema#", "$schema": "http://json-schema.org/draft-04/schema#",
"name": "Evalation", "name": "Evaluation",
"properties": { "properties": {
"@id": { "@id": {
"type": "string" "type": "string"

View File

@ -32,7 +32,7 @@ class APITest(TestCase):
query = {} query = {}
plug_params = { plug_params = {
'hello': { 'hello': {
'aliases': ['hello', 'hiya'], 'aliases': ['hiya', 'hello'],
'required': True 'required': True
} }
} }
@ -48,6 +48,26 @@ class APITest(TestCase):
assert 'hello' in p assert 'hello' in p
assert p['hello'] == 'dlrow' assert p['hello'] == 'dlrow'
def test_parameters2(self):
in1 = {
'meaningcloud-key': 5
}
in2 = {
'apikey': 25
}
extra_params = {
"apikey": {
"aliases": [
"apikey",
"meaningcloud-key"
],
"required": True
}
}
p1 = parse_params(in1, extra_params)
p2 = parse_params(in2, extra_params)
assert (p2['apikey'] / p1['apikey']) == 5
def test_default(self): def test_default(self):
spec = { spec = {
'hello': { 'hello': {

View File

@ -8,6 +8,8 @@ from fnmatch import fnmatch
from jsonschema import RefResolver, Draft4Validator, ValidationError from jsonschema import RefResolver, Draft4Validator, ValidationError
from senpy.models import read_schema
root_path = path.join(path.dirname(path.realpath(__file__)), '..') root_path = path.join(path.dirname(path.realpath(__file__)), '..')
schema_folder = path.join(root_path, 'senpy', 'schemas') schema_folder = path.join(root_path, 'senpy', 'schemas')
examples_path = path.join(root_path, 'docs', 'examples') examples_path = path.join(root_path, 'docs', 'examples')
@ -15,7 +17,8 @@ bad_examples_path = path.join(root_path, 'docs', 'bad-examples')
class JSONSchemaTests(unittest.TestCase): class JSONSchemaTests(unittest.TestCase):
pass def test_definitions(self):
read_schema('definitions.json')
def do_create_(jsfile, success): def do_create_(jsfile, success):