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

Prefix handling and bug fixes

This commit is contained in:
J. Fernando Sánchez 2016-02-21 02:53:39 +01:00
parent 48d7d1d02e
commit 14a3e4103b
9 changed files with 88 additions and 59 deletions

View File

@ -12,7 +12,7 @@ RUN apt-get -y install libopenblas-dev
RUN apt-get -y install gfortran RUN apt-get -y install gfortran
RUN apt-get -y install libxml2-dev libxslt1-dev python-dev RUN apt-get -y install libxml2-dev libxslt1-dev python-dev
RUN pip install --upgrade pip #RUN pip install --upgrade pip
ADD id_rsa /root/.ssh/id_rsa ADD id_rsa /root/.ssh/id_rsa
RUN chmod 700 /root/.ssh/id_rsa RUN chmod 700 /root/.ssh/id_rsa

View File

@ -3,3 +3,7 @@ include test-requirements.txt
include README.md include README.md
include senpy/context.jsonld include senpy/context.jsonld
graft senpy/plugins graft senpy/plugins
graft senpy/schemas
graft senpy/templates
graft senpy/static
graft img

View File

@ -38,7 +38,13 @@ API_PARAMS = {
"aliases": ["inHeaders", "headers"], "aliases": ["inHeaders", "headers"],
"required": True, "required": True,
"default": "0" "default": "0"
} },
"prefix": {
"@id": "prefix",
"aliases": ["prefix", "p"],
"required": True,
"default": "",
},
} }
BASIC_PARAMS = { BASIC_PARAMS = {
@ -171,7 +177,8 @@ def api():
params.update(get_params(request, specific_params)) params.update(get_params(request, specific_params))
response = current_app.senpy.analyse(**params) response = current_app.senpy.analyse(**params)
in_headers = params["inHeaders"] != "0" in_headers = params["inHeaders"] != "0"
return response.flask(in_headers=in_headers) prefix = params["prefix"]
return response.flask(in_headers=in_headers, prefix=prefix)
except Error as ex: except Error as ex:
return ex.message.flask() return ex.message.flask()
@ -186,6 +193,7 @@ def plugins():
@nif_blueprint.route('/plugins/<plugin>/', methods=['POST', 'GET']) @nif_blueprint.route('/plugins/<plugin>/', methods=['POST', 'GET'])
@nif_blueprint.route('/plugins/<plugin>/<action>', methods=['POST', 'GET']) @nif_blueprint.route('/plugins/<plugin>/<action>', methods=['POST', 'GET'])
def plugin(plugin=None, action="list"): def plugin(plugin=None, action="list"):
params = get_params(request, API_PARAMS)
filt = {} filt = {}
sp = current_app.senpy sp = current_app.senpy
plugs = sp.filter_plugins(name=plugin) plugs = sp.filter_plugins(name=plugin)
@ -197,8 +205,9 @@ def plugin(plugin=None, action="list"):
else: else:
return Error(message="Plugin not found", status=404).flask() return Error(message="Plugin not found", status=404).flask()
if action == "list": if action == "list":
in_headers = get_params(request, API_PARAMS)["inHeaders"] != "0" in_headers = params["inHeaders"] != "0"
return response.flask(in_headers=in_headers) prefix = params['prefix']
return response.flask(in_headers=in_headers, prefix=prefix)
method = "{}_plugin".format(action) method = "{}_plugin".format(action)
if(hasattr(sp, method)): if(hasattr(sp, method)):
getattr(sp, method)(plugin) getattr(sp, method)(plugin)

View File

@ -69,9 +69,12 @@ class SenpyMixin(object):
def flask(self, def flask(self,
in_headers=False, in_headers=False,
url="http://demos.gsi.dit.upm.es/senpy/senpy.jsonld"): url="http://demos.gsi.dit.upm.es/senpy/senpy.jsonld",
prefix=None):
""" """
Return the values and error to be used in flask Return the values and error to be used in flask.
So far, it returns a fixed context. We should store/generate different
contexts if the plugin adds more aliases.
""" """
headers = None headers = None
if in_headers: if in_headers:
@ -80,7 +83,8 @@ class SenpyMixin(object):
'rel="http://www.w3.org/ns/json-ld#context";' 'rel="http://www.w3.org/ns/json-ld#context";'
' type="application/ld+json"' % url) ' type="application/ld+json"' % url)
} }
return FlaskResponse(self.to_JSON(with_context=not in_headers), return FlaskResponse(self.to_JSON(with_context=not in_headers,
prefix=prefix),
status=getattr(self, "status", 200), status=getattr(self, "status", 200),
headers=headers, headers=headers,
mimetype="application/json") mimetype="application/json")
@ -103,11 +107,14 @@ class SenpyMixin(object):
return ser_or_down(self._plain_dict()) return ser_or_down(self._plain_dict())
def jsonld(self, context=None, with_context=False): def jsonld(self, context=None, prefix=None, with_context=False):
ser = self.serializable() ser = self.serializable()
if with_context: if with_context:
ser["@context"] = self.context ser["@context"] = self.context.copy()
if prefix:
ser["@context"]["@base"] = prefix
return ser return ser
@ -129,8 +136,17 @@ class SenpyModel(SenpyMixin, dict):
schema = base_schema schema = base_schema
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.id = kwargs.pop('id', '{}_{}'.format(type(self).__name__,
time.time()))
temp = dict(*args, **kwargs) temp = dict(*args, **kwargs)
for i in temp:
nk = self._get_key(i)
if nk != i:
temp[nk] = temp[i]
del temp[i]
reqs = self.schema.get('required', []) reqs = self.schema.get('required', [])
for i in reqs: for i in reqs:
if i not in temp: if i not in temp:
@ -175,30 +191,15 @@ class SenpyModel(SenpyMixin, dict):
def _plain_dict(self): def _plain_dict(self):
d = { k: v for (k,v) in self.items() if k[0] != "_"} d = { k: v for (k,v) in self.items() if k[0] != "_"}
if hasattr(self, "id"): d["@id"] = d.pop('id')
d["@id"] = self.id
return d return d
@property
def id(self):
if not hasattr(self, '_id'):
self.__dict__["_id"] = '_:{}_{}'.format(type(self).__name__, time.time())
return self._id
@id.setter
def id(self, value):
self._id = value
class Response(SenpyModel): class Response(SenpyModel):
schema = read_schema('response.json') schema = read_schema('response.json')
class Results(SenpyModel): class Results(SenpyModel):
schema = read_schema('results.json') schema = read_schema('results.json')
def jsonld(self, context=None, with_context=True):
return super(Results, self).jsonld(context, with_context)
class Entry(SenpyModel): class Entry(SenpyModel):
schema = read_schema('entry.json') schema = read_schema('entry.json')
@ -211,6 +212,9 @@ class Analysis(SenpyModel):
class EmotionSet(SenpyModel): class EmotionSet(SenpyModel):
schema = read_schema('emotionSet.json') schema = read_schema('emotionSet.json')
class Emotion(SenpyModel):
schema = read_schema('emotion.json')
class Suggestion(SenpyModel): class Suggestion(SenpyModel):
schema = read_schema('suggestion.json') schema = read_schema('suggestion.json')

View File

@ -17,6 +17,7 @@ class SenpyPlugin(PluginModel):
"information for the plugin.")) "information for the plugin."))
logger.debug("Initialising {}".format(info)) logger.debug("Initialising {}".format(info))
super(SenpyPlugin, self).__init__(info) super(SenpyPlugin, self).__init__(info)
self.id = '{}_{}'.format(self.name, self.version)
self.params = info.get("extra_params", {}) self.params = info.get("extra_params", {})
self._info = info self._info = info
if "@id" not in self.params: if "@id" not in self.params:
@ -36,10 +37,6 @@ class SenpyPlugin(PluginModel):
def deactivate(self): def deactivate(self):
pass pass
@property
def id(self):
return "{}_{}".format(self.name, self.version)
def __del__(self): def __del__(self):
''' Destructor, to make sure all the resources are freed ''' ''' Destructor, to make sure all the resources are freed '''
self.deactivate() self.deactivate()

View File

@ -115,7 +115,11 @@
"type": "string" "type": "string"
}, },
"onyx:hasEmotion": { "onyx:hasEmotion": {
"$ref": "#/Emotion" "type": "array",
"items": {
"$ref": "#/Emotion"
},
"default": []
}, },
"prov:wasGeneratedBy": { "prov:wasGeneratedBy": {
"type": "string", "type": "string",

View File

@ -17,37 +17,38 @@ function encodeHTML(text) {
$(document).ready(function() { $(document).ready(function() {
var response = JSON.parse($.ajax({type: "GET", url: "/api/plugins/" , async: false}).responseText); var response = JSON.parse($.ajax({type: "GET", url: "/api/plugins/" , async: false}).responseText);
var defaultPlugin= JSON.parse($.ajax({type: "GET", url: "/api/default" , async: false}).responseText); var defaultPlugin= JSON.parse($.ajax({type: "GET", url: "/api/plugins/default" , async: false}).responseText);
html=""; html="";
for (r in response){ plugins = response.plugins;
if (response[r]["name"]){ for (r in plugins){
if (response[r]["name"] == defaultPlugin["name"]){ if (plugins[r]["name"]){
if (response[r]["is_activated"]){ if (plugins[r]["name"] == defaultPlugin["name"]){
html+= "<option value=\""+response[r]["name"]+"\" selected=\"selected\">"+response[r]["name"]+"</option>" if (plugins[r]["is_activated"]){
html+= "<option value=\""+plugins[r]["name"]+"\" selected=\"selected\">"+plugins[r]["name"]+"</option>"
}else{ }else{
html+= "<option value=\""+response[r]["name"]+"\" selected=\"selected\" disabled=\"disabled\">"+response[r]["name"]+"</option>" html+= "<option value=\""+plugins[r]["name"]+"\" selected=\"selected\" disabled=\"disabled\">"+plugins[r]["name"]+"</option>"
} }
} }
else{ else{
if (response[r]["is_activated"]){ if (plugins[r]["is_activated"]){
html+= "<option value=\""+response[r]["name"]+"\">"+response[r]["name"]+"</option>" html+= "<option value=\""+plugins[r]["name"]+"\">"+plugins[r]["name"]+"</option>"
} }
else{ else{
html+= "<option value=\""+response[r]["name"]+"\" disabled=\"disabled\">"+response[r]["name"]+"</option>" html+= "<option value=\""+plugins[r]["name"]+"\" disabled=\"disabled\">"+plugins[r]["name"]+"</option>"
} }
} }
} }
if (response[r]["extra_params"]){ if (plugins[r]["extra_params"]){
plugins_params[response[r]["name"]]={}; plugins_params[plugins[r]["name"]]={};
for (param in response[r]["extra_params"]){ for (param in plugins[r]["extra_params"]){
if (typeof response[r]["extra_params"][param] !="string"){ if (typeof plugins[r]["extra_params"][param] !="string"){
var params = new Array(); var params = new Array();
var alias = response[r]["extra_params"][param]["aliases"][0]; var alias = plugins[r]["extra_params"][param]["aliases"][0];
params[alias]=new Array(); params[alias]=new Array();
for (option in response[r]["extra_params"][param]["options"]){ for (option in plugins[r]["extra_params"][param]["options"]){
params[alias].push(response[r]["extra_params"][param]["options"][option]) params[alias].push(plugins[r]["extra_params"][param]["options"][option])
} }
plugins_params[response[r]["name"]][alias] = (params[alias]) plugins_params[plugins[r]["name"]][alias] = (params[alias])
} }
} }
} }

View File

@ -15,7 +15,7 @@ except AttributeError:
install_reqs = [str(ir.req) for ir in install_reqs] install_reqs = [str(ir.req) for ir in install_reqs]
test_reqs = [str(ir.req) for ir in test_reqs] test_reqs = [str(ir.req) for ir in test_reqs]
VERSION = "0.5.1" VERSION = "0.5.4"
setup( setup(
name='senpy', name='senpy',

View File

@ -6,7 +6,7 @@ import jsonschema
import json import json
import os import os
from unittest import TestCase from unittest import TestCase
from senpy.models import Response, Entry, Results, Sentiment, EmotionSet, Error from senpy.models import Response, Entry, Results, Sentiment, EmotionSet, Emotion, Error
from senpy.plugins import SenpyPlugin from senpy.plugins import SenpyPlugin
from pprint import pprint from pprint import pprint
@ -15,20 +15,23 @@ class ModelsTest(TestCase):
def test_jsonld(self): def test_jsonld(self):
ctx = os.path.normpath(os.path.join(__file__, "..", "..", "..", "senpy", "schemas", "context.jsonld")) ctx = os.path.normpath(os.path.join(__file__, "..", "..", "..", "senpy", "schemas", "context.jsonld"))
prueba = {"@id": "test", prueba = {"id": "test",
"analysis": [], "analysis": [],
"entries": []} "entries": []}
r = Results(**prueba) r = Results(**prueba)
print("Response's context: ") print("Response's context: ")
pprint(r.context) pprint(r.context)
assert r.id == "test"
j = r.jsonld(with_context=True) j = r.jsonld(with_context=True)
print("As JSON:") print("As JSON:")
pprint(j) pprint(j)
assert("@context" in j) assert("@context" in j)
assert("marl" in j["@context"]) assert("marl" in j["@context"])
assert("entries" in j["@context"]) assert("entries" in j["@context"])
assert(j["@id"] == "test")
assert "id" not in j
r6 = Results(**prueba) r6 = Results(**prueba)
r6.entries.append(Entry({"@id":"ohno", "nif:isString":"Just testing"})) r6.entries.append(Entry({"@id":"ohno", "nif:isString":"Just testing"}))
@ -47,6 +50,18 @@ class ModelsTest(TestCase):
assert(received["entries"][0]["nif:isString"] == "Just testing") assert(received["entries"][0]["nif:isString"] == "Just testing")
assert(received["entries"][0]["nif:isString"] != "Not testing") assert(received["entries"][0]["nif:isString"] != "Not testing")
def test_id(self):
''' Adding the id after creation should overwrite the automatic ID
'''
r = Entry()
j = r.jsonld()
assert '@id' in j
r.id = "test"
j2 = r.jsonld()
assert j2['@id'] == 'test'
assert 'id' not in j2
def test_entries(self): def test_entries(self):
e = Entry() e = Entry()
self.assertRaises(jsonschema.ValidationError, e.validate) self.assertRaises(jsonschema.ValidationError, e.validate)
@ -67,8 +82,6 @@ class ModelsTest(TestCase):
self.assertRaises(jsonschema.ValidationError, e.validate) self.assertRaises(jsonschema.ValidationError, e.validate)
e.nif__anchorOf = "so much testing" e.nif__anchorOf = "so much testing"
e.prov__wasGeneratedBy = "" e.prov__wasGeneratedBy = ""
self.assertRaises(jsonschema.ValidationError, e.validate)
e.onyx__hasEmotion = {}
e.validate() e.validate()
def test_results(self): def test_results(self):
@ -79,9 +92,6 @@ class ModelsTest(TestCase):
r.id = ":test_results" r.id = ":test_results"
r.validate() r.validate()
def test_sentiments(self):
pass
def test_plugins(self): def test_plugins(self):
self.assertRaises(Error, SenpyPlugin) self.assertRaises(Error, SenpyPlugin)
p = SenpyPlugin({"name": "dummy", "version": 0}) p = SenpyPlugin({"name": "dummy", "version": 0})