mirror of
https://github.com/gsi-upm/senpy
synced 2024-11-22 08:12:27 +00:00
Fix schema issues and parameter validation
This commit is contained in:
parent
73f7cbbe8a
commit
d7acf3d67a
@ -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/
|
||||||
|
@ -9,3 +9,6 @@ jsonref
|
|||||||
PyYAML
|
PyYAML
|
||||||
rdflib
|
rdflib
|
||||||
rdflib-jsonld
|
rdflib-jsonld
|
||||||
|
numpy
|
||||||
|
scipy
|
||||||
|
scikit-learn
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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)
|
||||||
|
@ -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"
|
||||||
|
@ -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': {
|
||||||
|
@ -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):
|
||||||
|
Loading…
Reference in New Issue
Block a user