mirror of
https://github.com/gsi-upm/senpy
synced 2025-08-24 02:22:20 +00:00
Draft merge 51-improve parameters
There are some unsolved issues, like representing the mix of analysis+parameters in a sensible way. I think we should somehow represent each of the analysis tasks with a unique ID, and it should contain the specific parameters used. Right now results.parameters is a mix of a dict with global parameters and a list with a dict of parameters per plugin.
This commit is contained in:
@@ -3,8 +3,9 @@ import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
from unittest import TestCase
|
||||
from senpy.api import parse_params, API_PARAMS, NIF_PARAMS, WEB_PARAMS
|
||||
from senpy.models import Error
|
||||
from senpy.api import (boolean, parse_params, get_extra_params, parse_extra_params,
|
||||
API_PARAMS, NIF_PARAMS, WEB_PARAMS)
|
||||
from senpy.models import Error, Plugin
|
||||
|
||||
|
||||
class APITest(TestCase):
|
||||
@@ -89,3 +90,157 @@ class APITest(TestCase):
|
||||
assert "Dummy" in p['algorithm']
|
||||
assert 'input' in p
|
||||
assert p['input'] == 'Aloha my friend'
|
||||
|
||||
def test_parse_extra_params(self):
|
||||
'''The API should parse user parameters and return them in a format that plugins can use'''
|
||||
plugins = [
|
||||
Plugin({
|
||||
'name': 'plugin1',
|
||||
'extra_params': {
|
||||
# Incompatible parameter
|
||||
'param0': {
|
||||
'aliases': ['p1', 'parameter1'],
|
||||
'options': ['option1', 'option2'],
|
||||
'default': 'option1',
|
||||
'required': True
|
||||
},
|
||||
'param1': {
|
||||
'aliases': ['p1', 'parameter1'],
|
||||
'options': ['en', 'es'],
|
||||
|
||||
'default': 'en',
|
||||
'required': False
|
||||
},
|
||||
'param2': {
|
||||
'aliases': ['p2', 'parameter2'],
|
||||
'required': False,
|
||||
'options': ['value2_1', 'value2_2', 'value3_3']
|
||||
}
|
||||
}
|
||||
}), Plugin({
|
||||
'name': 'plugin2',
|
||||
'extra_params': {
|
||||
'param0': {
|
||||
'aliases': ['parameter1'],
|
||||
'options': ['new option', 'new option2'],
|
||||
'default': 'new option',
|
||||
'required': False
|
||||
},
|
||||
'param1': {
|
||||
'aliases': ['myparam1', 'p1'],
|
||||
'options': ['en', 'de', 'auto'],
|
||||
'default': 'de',
|
||||
'required': True
|
||||
},
|
||||
'param3': {
|
||||
'aliases': ['p3', 'parameter3'],
|
||||
'options': boolean,
|
||||
'default': True
|
||||
}
|
||||
}
|
||||
})
|
||||
]
|
||||
call = {
|
||||
'param1': 'en',
|
||||
'0.param0': 'option1',
|
||||
'0.param1': 'en',
|
||||
'param2': 'value2_1',
|
||||
'param0': 'new option',
|
||||
'1.param1': 'de',
|
||||
'param3': False,
|
||||
}
|
||||
expected = [
|
||||
{
|
||||
'param0': 'option1',
|
||||
'param1': 'en',
|
||||
'param2': 'value2_1',
|
||||
}, {
|
||||
'param0': 'new option',
|
||||
'param1': 'de',
|
||||
'param3': False,
|
||||
}
|
||||
|
||||
]
|
||||
p = parse_extra_params(call, plugins)
|
||||
for i, arg in enumerate(expected):
|
||||
for k, v in arg.items():
|
||||
assert p[i][k] == v
|
||||
|
||||
def test_get_extra_params(self):
|
||||
'''The API should return the list of valid parameters for a set of plugins'''
|
||||
plugins = [
|
||||
Plugin({
|
||||
'name': 'plugin1',
|
||||
'extra_params': {
|
||||
# Incompatible parameter
|
||||
'param0': {
|
||||
'aliases': ['p1', 'parameter1'],
|
||||
'options': ['option1', 'option2'],
|
||||
'default': 'option1',
|
||||
'required': True
|
||||
},
|
||||
'param1': {
|
||||
'aliases': ['p1', 'parameter1'],
|
||||
'options': ['en', 'es'],
|
||||
'default': 'en',
|
||||
'required': False
|
||||
},
|
||||
'param2': {
|
||||
'aliases': ['p2', 'parameter2'],
|
||||
'required': False,
|
||||
'options': ['value2_1', 'value2_2', 'value3_3']
|
||||
}
|
||||
}
|
||||
}), Plugin({
|
||||
'name': 'plugin2',
|
||||
'extra_params': {
|
||||
'param0': {
|
||||
'aliases': ['parameter1'],
|
||||
'options': ['new option', 'new option2'],
|
||||
'default': 'new option',
|
||||
'required': False
|
||||
},
|
||||
'param1': {
|
||||
'aliases': ['myparam1', 'p1'],
|
||||
'options': ['en', 'de', 'auto'],
|
||||
'default': 'de',
|
||||
'required': True
|
||||
},
|
||||
'param3': {
|
||||
'aliases': ['p3', 'parameter3'],
|
||||
'options': boolean,
|
||||
'default': True
|
||||
}
|
||||
}
|
||||
})
|
||||
]
|
||||
|
||||
expected = {
|
||||
# Each plugin's parameters
|
||||
'0.param0': plugins[0]['extra_params']['param0'],
|
||||
'0.param1': plugins[0]['extra_params']['param1'],
|
||||
'0.param2': plugins[0]['extra_params']['param2'],
|
||||
'1.param0': plugins[1]['extra_params']['param0'],
|
||||
'1.param1': plugins[1]['extra_params']['param1'],
|
||||
'1.param3': plugins[1]['extra_params']['param3'],
|
||||
|
||||
# Non-overlapping parameters
|
||||
'param2': plugins[0]['extra_params']['param2'],
|
||||
'param3': plugins[1]['extra_params']['param3'],
|
||||
|
||||
# Intersection of overlapping parameters
|
||||
'param1': {
|
||||
'aliases': ['p1'],
|
||||
'options': ['en'],
|
||||
'default': None,
|
||||
'required': True
|
||||
}
|
||||
}
|
||||
|
||||
result = get_extra_params(plugins)
|
||||
|
||||
for ik, iv in expected.items():
|
||||
assert ik in result
|
||||
for jk, jv in iv.items():
|
||||
assert jk in result[ik]
|
||||
assert expected[ik][jk] == result[ik][jk]
|
||||
|
@@ -107,6 +107,7 @@ class BlueprintsTest(TestCase):
|
||||
assert isinstance(js, models.Error)
|
||||
resp = self.client.get("/api/?i=My aloha mohame&algo=DummyRequired&example=notvalid")
|
||||
self.assertCode(resp, 400)
|
||||
self.app.config['TESTING'] = True
|
||||
resp = self.client.get("/api/?i=My aloha mohame&algo=DummyRequired&example=a")
|
||||
self.assertCode(resp, 200)
|
||||
|
||||
@@ -148,6 +149,53 @@ class BlueprintsTest(TestCase):
|
||||
assert len(js['analysis']) == 1
|
||||
assert js['entries'][0]['nif:isString'] == 'My aloha mohame'
|
||||
|
||||
def test_requirements_chain_help(self):
|
||||
'''The extra parameters of each plugin should be merged if they are in a chain '''
|
||||
resp = self.client.get("/api/split/DummyRequired?help=true")
|
||||
self.assertCode(resp, 200)
|
||||
js = parse_resp(resp)
|
||||
assert 'valid_parameters' in js
|
||||
vp = js['valid_parameters']
|
||||
assert 'example' in vp
|
||||
|
||||
def test_requirements_chain_repeat_help(self):
|
||||
'''
|
||||
If a plugin appears several times in a chain, there should be a way to set different
|
||||
parameters for each.
|
||||
'''
|
||||
resp = self.client.get("/api/split/split?help=true")
|
||||
self.assertCode(resp, 200)
|
||||
js = parse_resp(resp)
|
||||
assert 'valid_parameters' in js
|
||||
vp = js['valid_parameters']
|
||||
assert '0.delimiter' in vp
|
||||
assert '1.delimiter' in vp
|
||||
assert 'delimiter' in vp
|
||||
|
||||
def test_requirements_chain(self):
|
||||
"""
|
||||
It should be possible to specify different parameters for each step in the chain.
|
||||
"""
|
||||
|
||||
# First, we split by sentence twice. Each call should generate 3 additional entries
|
||||
# (one per sentence in the original).
|
||||
resp = self.client.get('/api/split/split?i=The first sentence. The second sentence.'
|
||||
'\nA new paragraph&delimiter=sentence')
|
||||
js = parse_resp(resp)
|
||||
assert len(js['analysis']) == 2
|
||||
assert len(js['entries']) == 7
|
||||
|
||||
# Now, we split by sentence. This produces 3 additional entries.
|
||||
# Then, we split by paragraph. This should create 2 additional entries (One per paragraph
|
||||
# in the original text)
|
||||
resp = self.client.get('/api/split/split?i=The first sentence. The second sentence.'
|
||||
'\nA new paragraph&0.delimiter=sentence&1.delimiter=paragraph')
|
||||
# Calling dummy twice, should return the same string
|
||||
self.assertCode(resp, 200)
|
||||
js = parse_resp(resp)
|
||||
assert len(js['analysis']) == 2
|
||||
assert len(js['entries']) == 6
|
||||
|
||||
def test_error(self):
|
||||
"""
|
||||
The dummy plugin returns an empty response,\
|
||||
|
Reference in New Issue
Block a user