mirror of
https://github.com/gsi-upm/senpy
synced 2025-10-19 17:58:28 +00:00
Compare commits
3 Commits
0.11.0
...
54-get-sin
Author | SHA1 | Date | |
---|---|---|---|
|
530982be62 | ||
|
38b478890b | ||
|
6dd4a44924 |
@@ -184,14 +184,19 @@ def basic_api(f):
|
|||||||
return decorated_function
|
return decorated_function
|
||||||
|
|
||||||
|
|
||||||
@api_blueprint.route('/', methods=['POST', 'GET'])
|
@api_blueprint.route('/', defaults={'plugin': None}, methods=['POST', 'GET'])
|
||||||
|
@api_blueprint.route('/<path:plugin>', methods=['POST', 'GET'])
|
||||||
@basic_api
|
@basic_api
|
||||||
def api_root():
|
def api_root(plugin):
|
||||||
if request.parameters['help']:
|
if request.parameters['help']:
|
||||||
dic = dict(api.API_PARAMS, **api.NIF_PARAMS)
|
dic = dict(api.API_PARAMS, **api.NIF_PARAMS)
|
||||||
response = Help(valid_parameters=dic)
|
response = Help(valid_parameters=dic)
|
||||||
return response
|
return response
|
||||||
req = api.parse_call(request.parameters)
|
req = api.parse_call(request.parameters)
|
||||||
|
if plugin:
|
||||||
|
plugin = plugin.replace('+', '/')
|
||||||
|
plugin = plugin.split('/')
|
||||||
|
req.parameters['algorithm'] = plugin
|
||||||
return current_app.senpy.analyse(req)
|
return current_app.senpy.analyse(req)
|
||||||
|
|
||||||
|
|
||||||
@@ -221,7 +226,7 @@ def plugins():
|
|||||||
|
|
||||||
@api_blueprint.route('/plugins/<plugin>/', methods=['POST', 'GET'])
|
@api_blueprint.route('/plugins/<plugin>/', methods=['POST', 'GET'])
|
||||||
@basic_api
|
@basic_api
|
||||||
def plugin(plugin=None):
|
def plugin(plugin):
|
||||||
sp = current_app.senpy
|
sp = current_app.senpy
|
||||||
return sp.get_plugin(plugin)
|
return sp.get_plugin(plugin)
|
||||||
|
|
||||||
|
@@ -153,7 +153,6 @@ class Senpy(object):
|
|||||||
yield i
|
yield i
|
||||||
return
|
return
|
||||||
plugin = plugins[0]
|
plugin = plugins[0]
|
||||||
self._activate(plugin) # Make sure the plugin is activated
|
|
||||||
specific_params = api.parse_extra_params(req, plugin)
|
specific_params = api.parse_extra_params(req, plugin)
|
||||||
req.analysis.append({'plugin': plugin,
|
req.analysis.append({'plugin': plugin,
|
||||||
'parameters': specific_params})
|
'parameters': specific_params})
|
||||||
@@ -352,7 +351,7 @@ class Senpy(object):
|
|||||||
|
|
||||||
logger.info("Activating plugin: {}".format(plugin.name))
|
logger.info("Activating plugin: {}".format(plugin.name))
|
||||||
|
|
||||||
if sync or 'async' in plugin and not plugin.async:
|
if sync or not getattr(plugin, 'async', True):
|
||||||
return self._activate(plugin)
|
return self._activate(plugin)
|
||||||
else:
|
else:
|
||||||
th = Thread(target=partial(self._activate, plugin))
|
th = Thread(target=partial(self._activate, plugin))
|
||||||
@@ -375,7 +374,7 @@ class Senpy(object):
|
|||||||
|
|
||||||
self._set_active(plugin, False)
|
self._set_active(plugin, False)
|
||||||
|
|
||||||
if sync or 'async' in plugin and not plugin.async:
|
if sync or not getattr(plugin, 'async', True):
|
||||||
self._deactivate(plugin)
|
self._deactivate(plugin)
|
||||||
else:
|
else:
|
||||||
th = Thread(target=partial(self._deactivate, plugin))
|
th = Thread(target=partial(self._deactivate, plugin))
|
||||||
|
187
senpy/plugins/emotion/maxSentiment_plugin.py
Normal file
187
senpy/plugins/emotion/maxSentiment_plugin.py
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
from senpy import AnalysisPlugin, easy
|
||||||
|
|
||||||
|
|
||||||
|
class maxSentiment(AnalysisPlugin):
|
||||||
|
'''Plugin to extract max emotion from a multi-empotion set'''
|
||||||
|
author = '@dsuarezsouto'
|
||||||
|
version = '0.1'
|
||||||
|
|
||||||
|
extra_params = {
|
||||||
|
'max': {
|
||||||
|
"aliases": ["maximum", "max"],
|
||||||
|
'required': True,
|
||||||
|
'options': [True, False],
|
||||||
|
"@id": 'maxSentiment',
|
||||||
|
'default': False
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def analyse_entry(self, entry, params):
|
||||||
|
if not params["max"]:
|
||||||
|
yield entry
|
||||||
|
return
|
||||||
|
|
||||||
|
set_emotions= entry.emotions[0]['onyx:hasEmotion']
|
||||||
|
max_emotion =set_emotions[0]
|
||||||
|
|
||||||
|
# Extract max emotion from the set emotions (emotion with highest intensity)
|
||||||
|
for tmp_emotion in set_emotions:
|
||||||
|
if tmp_emotion['onyx:hasEmotionIntensity']>max_emotion['onyx:hasEmotionIntensity']:
|
||||||
|
max_emotion=tmp_emotion
|
||||||
|
|
||||||
|
if max_emotion['onyx:hasEmotionIntensity'] == 0:
|
||||||
|
max_emotion['onyx:hasEmotionCategory'] = "neutral"
|
||||||
|
max_emotion['onyx:hasEmotionIntensity'] = 1.0
|
||||||
|
|
||||||
|
entry.emotions[0]['onyx:hasEmotion'] = [max_emotion]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
entry.emotions[0]['prov:wasGeneratedBy'] = "maxSentiment"
|
||||||
|
#print(entry)
|
||||||
|
yield entry
|
||||||
|
|
||||||
|
# Test Cases:
|
||||||
|
# 1 Normal Situation.
|
||||||
|
# 2 Case to return a Neutral Emotion.
|
||||||
|
test_cases = [{
|
||||||
|
"entry": {
|
||||||
|
"@type": "entry",
|
||||||
|
"emotions": [
|
||||||
|
{
|
||||||
|
"@id": "Emotions0",
|
||||||
|
"@type": "emotionSet",
|
||||||
|
"onyx:hasEmotion": [
|
||||||
|
{
|
||||||
|
"@id": "_:Emotion_1538121033.74",
|
||||||
|
"@type": "emotion",
|
||||||
|
"onyx:hasEmotionCategory": "anger",
|
||||||
|
"onyx:hasEmotionIntensity": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@id": "_:Emotion_1538121033.74",
|
||||||
|
"@type": "emotion",
|
||||||
|
"onyx:hasEmotionCategory": "joy",
|
||||||
|
"onyx:hasEmotionIntensity": 0.3333333333333333
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@id": "_:Emotion_1538121033.74",
|
||||||
|
"@type": "emotion",
|
||||||
|
"onyx:hasEmotionCategory": "negative-fear",
|
||||||
|
"onyx:hasEmotionIntensity": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@id": "_:Emotion_1538121033.74",
|
||||||
|
"@type": "emotion",
|
||||||
|
"onyx:hasEmotionCategory": "sadness",
|
||||||
|
"onyx:hasEmotionIntensity": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@id": "_:Emotion_1538121033.74",
|
||||||
|
"@type": "emotion",
|
||||||
|
"onyx:hasEmotionCategory": "disgust",
|
||||||
|
"onyx:hasEmotionIntensity": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"nif:isString": "This text makes me sad.\nwhilst this text makes me happy and surprised at the same time.\nI cannot believe it!"
|
||||||
|
},
|
||||||
|
'params': {
|
||||||
|
'max': True
|
||||||
|
},
|
||||||
|
'expected' : {
|
||||||
|
"@type": "entry",
|
||||||
|
"emotions": [
|
||||||
|
{
|
||||||
|
"@id": "Emotions0",
|
||||||
|
"@type": "emotionSet",
|
||||||
|
"onyx:hasEmotion": [
|
||||||
|
{
|
||||||
|
"@id": "_:Emotion_1538121033.74",
|
||||||
|
"@type": "emotion",
|
||||||
|
"onyx:hasEmotionCategory": "joy",
|
||||||
|
"onyx:hasEmotionIntensity": 0.3333333333333333
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prov:wasGeneratedBy" : 'maxSentiment'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nif:isString": "This text makes me sad.\nwhilst this text makes me happy and surprised at the same time.\nI cannot believe it!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"entry": {
|
||||||
|
"@type": "entry",
|
||||||
|
"emotions": [
|
||||||
|
{
|
||||||
|
"@id": "Emotions0",
|
||||||
|
"@type": "emotionSet",
|
||||||
|
"onyx:hasEmotion": [
|
||||||
|
{
|
||||||
|
"@id": "_:Emotion_1538121033.74",
|
||||||
|
"@type": "emotion",
|
||||||
|
"onyx:hasEmotionCategory": "anger",
|
||||||
|
"onyx:hasEmotionIntensity": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@id": "_:Emotion_1538121033.74",
|
||||||
|
"@type": "emotion",
|
||||||
|
"onyx:hasEmotionCategory": "joy",
|
||||||
|
"onyx:hasEmotionIntensity": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@id": "_:Emotion_1538121033.74",
|
||||||
|
"@type": "emotion",
|
||||||
|
"onyx:hasEmotionCategory": "negative-fear",
|
||||||
|
"onyx:hasEmotionIntensity": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@id": "_:Emotion_1538121033.74",
|
||||||
|
"@type": "emotion",
|
||||||
|
"onyx:hasEmotionCategory": "sadness",
|
||||||
|
"onyx:hasEmotionIntensity": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@id": "_:Emotion_1538121033.74",
|
||||||
|
"@type": "emotion",
|
||||||
|
"onyx:hasEmotionCategory": "disgust",
|
||||||
|
"onyx:hasEmotionIntensity": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nif:isString": "This text makes me sad.\nwhilst this text makes me happy and surprised at the same time.\nI cannot believe it!"
|
||||||
|
},
|
||||||
|
'params': {
|
||||||
|
'max': True
|
||||||
|
},
|
||||||
|
'expected' : {
|
||||||
|
|
||||||
|
"@type": "entry",
|
||||||
|
"emotions": [
|
||||||
|
{
|
||||||
|
"@id": "Emotions0",
|
||||||
|
"@type": "emotionSet",
|
||||||
|
"onyx:hasEmotion": [
|
||||||
|
{
|
||||||
|
"@id": "_:Emotion_1538121033.74",
|
||||||
|
"@type": "emotion",
|
||||||
|
"onyx:hasEmotionCategory": "neutral",
|
||||||
|
"onyx:hasEmotionIntensity": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prov:wasGeneratedBy" : 'maxSentiment'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nif:isString": "This text makes me sad.\nwhilst this text makes me happy and surprised at the same time.\nI cannot believe it!"
|
||||||
|
}
|
||||||
|
|
||||||
|
}]
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
easy()
|
||||||
|
|
@@ -70,7 +70,7 @@ class BlueprintsTest(TestCase):
|
|||||||
|
|
||||||
def test_analysis_extra(self):
|
def test_analysis_extra(self):
|
||||||
"""
|
"""
|
||||||
Extra params that have a default should
|
Extra params that have a default should use it
|
||||||
"""
|
"""
|
||||||
resp = self.client.get("/api/?i=My aloha mohame&algo=Dummy&with_parameters=true")
|
resp = self.client.get("/api/?i=My aloha mohame&algo=Dummy&with_parameters=true")
|
||||||
self.assertCode(resp, 200)
|
self.assertCode(resp, 200)
|
||||||
@@ -95,6 +95,44 @@ class BlueprintsTest(TestCase):
|
|||||||
resp = self.client.get("/api/?i=My aloha mohame&algo=DummyRequired&example=a")
|
resp = self.client.get("/api/?i=My aloha mohame&algo=DummyRequired&example=a")
|
||||||
self.assertCode(resp, 200)
|
self.assertCode(resp, 200)
|
||||||
|
|
||||||
|
def test_analysis_url(self):
|
||||||
|
"""
|
||||||
|
The algorithm can also be specified as part of the URL
|
||||||
|
"""
|
||||||
|
self.app.config['TESTING'] = False # Errors are expected in this case
|
||||||
|
resp = self.client.get("/api/DummyRequired?i=My aloha mohame")
|
||||||
|
self.assertCode(resp, 400)
|
||||||
|
js = parse_resp(resp)
|
||||||
|
logging.debug("Got response: %s", js)
|
||||||
|
assert isinstance(js, models.Error)
|
||||||
|
resp = self.client.get("/api/DummyRequired?i=My aloha mohame&example=notvalid")
|
||||||
|
self.assertCode(resp, 400)
|
||||||
|
resp = self.client.get("/api/DummyRequired?i=My aloha mohame&example=a")
|
||||||
|
self.assertCode(resp, 200)
|
||||||
|
|
||||||
|
def test_analysis_chain(self):
|
||||||
|
"""
|
||||||
|
More than one algorithm can be specified. Plugins will then be chained
|
||||||
|
"""
|
||||||
|
resp = self.client.get("/api/Dummy?i=My aloha mohame")
|
||||||
|
js = parse_resp(resp)
|
||||||
|
assert len(js['analysis']) == 1
|
||||||
|
assert js['entries'][0]['nif:isString'] == 'My aloha mohame'[::-1]
|
||||||
|
|
||||||
|
resp = self.client.get("/api/Dummy/Dummy?i=My aloha mohame")
|
||||||
|
# Calling dummy twice, should return the same string
|
||||||
|
self.assertCode(resp, 200)
|
||||||
|
js = parse_resp(resp)
|
||||||
|
assert len(js['analysis']) == 2
|
||||||
|
assert js['entries'][0]['nif:isString'] == 'My aloha mohame'
|
||||||
|
|
||||||
|
resp = self.client.get("/api/Dummy+Dummy?i=My aloha mohame")
|
||||||
|
# Same with pluses instead of slashes
|
||||||
|
self.assertCode(resp, 200)
|
||||||
|
js = parse_resp(resp)
|
||||||
|
assert len(js['analysis']) == 2
|
||||||
|
assert js['entries'][0]['nif:isString'] == 'My aloha mohame'
|
||||||
|
|
||||||
def test_error(self):
|
def test_error(self):
|
||||||
"""
|
"""
|
||||||
The dummy plugin returns an empty response,\
|
The dummy plugin returns an empty response,\
|
||||||
|
Reference in New Issue
Block a user