mirror of
https://github.com/gsi-upm/senpy
synced 2024-11-22 08:12:27 +00:00
Improved docs and client
* Client now raises an exception on error * Added conversion to the documentation
This commit is contained in:
parent
97bd245dfc
commit
a0ff528a4b
116
docs/api.rst
116
docs/api.rst
@ -62,6 +62,7 @@ NIF API
|
|||||||
:query o outformat: one of `turtle` (default), `text`, `json-ld`
|
:query o outformat: one of `turtle` (default), `text`, `json-ld`
|
||||||
:query p prefix: prefix for the URIs
|
:query p prefix: prefix for the URIs
|
||||||
:query algo algorithm: algorithm/plugin to use for the analysis. For a list of options, see :http:get:`/api/plugins`. If not provided, the default plugin will be used (:http:get:`/api/plugins/default`).
|
:query algo algorithm: algorithm/plugin to use for the analysis. For a list of options, see :http:get:`/api/plugins`. If not provided, the default plugin will be used (:http:get:`/api/plugins/default`).
|
||||||
|
:query algo emotionModel: desired emotion model in the results. If the requested algorithm does not use that emotion model, there are conversion plugins specifically for this. If none of the plugins match, an error will be returned, which includes the results *as is*.
|
||||||
|
|
||||||
:reqheader Accept: the response content type depends on
|
:reqheader Accept: the response content type depends on
|
||||||
:mailheader:`Accept` header
|
:mailheader:`Accept` header
|
||||||
@ -69,6 +70,7 @@ NIF API
|
|||||||
header of request
|
header of request
|
||||||
:statuscode 200: no error
|
:statuscode 200: no error
|
||||||
:statuscode 404: service not found
|
:statuscode 404: service not found
|
||||||
|
:statuscode 400: error while processing the request
|
||||||
|
|
||||||
.. http:post:: /api
|
.. http:post:: /api
|
||||||
|
|
||||||
@ -94,50 +96,52 @@ NIF API
|
|||||||
"@context": {
|
"@context": {
|
||||||
...
|
...
|
||||||
},
|
},
|
||||||
"sentiment140": {
|
"@type": "plugins",
|
||||||
"name": "sentiment140",
|
"plugins": [
|
||||||
"is_activated": true,
|
{
|
||||||
"version": "0.1",
|
"name": "sentiment140",
|
||||||
"extra_params": {
|
"is_activated": true,
|
||||||
"@id": "extra_params_sentiment140_0.1",
|
"version": "0.1",
|
||||||
"language": {
|
"extra_params": {
|
||||||
"required": false,
|
"@id": "extra_params_sentiment140_0.1",
|
||||||
"@id": "lang_sentiment140",
|
"language": {
|
||||||
"options": [
|
"required": false,
|
||||||
"es",
|
"@id": "lang_sentiment140",
|
||||||
"en",
|
"options": [
|
||||||
"auto"
|
"es",
|
||||||
],
|
"en",
|
||||||
"aliases": [
|
"auto"
|
||||||
"language",
|
],
|
||||||
"l"
|
"aliases": [
|
||||||
]
|
"language",
|
||||||
}
|
"l"
|
||||||
},
|
]
|
||||||
"@id": "sentiment140_0.1"
|
}
|
||||||
},
|
},
|
||||||
"rand": {
|
"@id": "sentiment140_0.1"
|
||||||
"name": "rand",
|
}, {
|
||||||
"is_activated": true,
|
"name": "rand",
|
||||||
"version": "0.1",
|
"is_activated": true,
|
||||||
"extra_params": {
|
"version": "0.1",
|
||||||
"@id": "extra_params_rand_0.1",
|
"extra_params": {
|
||||||
"language": {
|
"@id": "extra_params_rand_0.1",
|
||||||
"required": false,
|
"language": {
|
||||||
"@id": "lang_rand",
|
"required": false,
|
||||||
"options": [
|
"@id": "lang_rand",
|
||||||
"es",
|
"options": [
|
||||||
"en",
|
"es",
|
||||||
"auto"
|
"en",
|
||||||
],
|
"auto"
|
||||||
"aliases": [
|
],
|
||||||
"language",
|
"aliases": [
|
||||||
"l"
|
"language",
|
||||||
]
|
"l"
|
||||||
}
|
]
|
||||||
},
|
}
|
||||||
"@id": "rand_0.1"
|
},
|
||||||
}
|
"@id": "rand_0.1"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -148,7 +152,7 @@ NIF API
|
|||||||
|
|
||||||
.. sourcecode:: http
|
.. sourcecode:: http
|
||||||
|
|
||||||
GET /api/plugins/rand HTTP/1.1
|
GET /api/plugins/rand/ HTTP/1.1
|
||||||
Host: localhost
|
Host: localhost
|
||||||
Accept: application/json, text/javascript
|
Accept: application/json, text/javascript
|
||||||
|
|
||||||
@ -159,6 +163,7 @@ NIF API
|
|||||||
|
|
||||||
{
|
{
|
||||||
"@id": "rand_0.1",
|
"@id": "rand_0.1",
|
||||||
|
"@type": "sentimentPlugin",
|
||||||
"extra_params": {
|
"extra_params": {
|
||||||
"@id": "extra_params_rand_0.1",
|
"@id": "extra_params_rand_0.1",
|
||||||
"language": {
|
"language": {
|
||||||
@ -185,24 +190,3 @@ NIF API
|
|||||||
|
|
||||||
Return the information about the default plugin.
|
Return the information about the default plugin.
|
||||||
|
|
||||||
.. http:get:: /api/plugins/<pluginname>/{de}activate
|
|
||||||
|
|
||||||
{De}activate a plugin.
|
|
||||||
|
|
||||||
**Example request**:
|
|
||||||
|
|
||||||
.. sourcecode:: http
|
|
||||||
|
|
||||||
GET /api/plugins/rand/deactivate HTTP/1.1
|
|
||||||
Host: localhost
|
|
||||||
Accept: application/json, text/javascript
|
|
||||||
|
|
||||||
|
|
||||||
**Example response**:
|
|
||||||
|
|
||||||
.. sourcecode:: http
|
|
||||||
|
|
||||||
{
|
|
||||||
"@context": {},
|
|
||||||
"message": "Ok"
|
|
||||||
}
|
|
||||||
|
116
docs/conversion.rst
Normal file
116
docs/conversion.rst
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
Introduction
|
||||||
|
------------
|
||||||
|
|
||||||
|
Senpy includes experimental support for emotion/sentiment conversion plugins.
|
||||||
|
|
||||||
|
|
||||||
|
Use
|
||||||
|
---
|
||||||
|
|
||||||
|
Consider the original query: `http://127.0.0.1:5000/api/?i=hello&algo=emoRand`_
|
||||||
|
|
||||||
|
The requested plugin (emoRand) returns emotions using Ekman's model (or big6 in EmotionML):
|
||||||
|
|
||||||
|
.. code:: json
|
||||||
|
|
||||||
|
|
||||||
|
... rest of the document ...
|
||||||
|
{
|
||||||
|
"@type": "emotionSet",
|
||||||
|
"onyx:hasEmotion": {
|
||||||
|
"@type": "emotion",
|
||||||
|
"onyx:hasEmotionCategory": "emoml:big6anger"
|
||||||
|
},
|
||||||
|
"prov:wasGeneratedBy": "plugins/emoRand_0.1"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
To get these emotions in VAD space (FSRE dimensions in EmotionML), we'd do this:
|
||||||
|
|
||||||
|
`http://127.0.0.1:5000/api/?i=hello&algo=emoRand&emotionModel=emoml:fsre-dimensions`_
|
||||||
|
|
||||||
|
This call, provided there is a valid conversion plugin from Ekman's to VAD, would return something like this:
|
||||||
|
|
||||||
|
.. code:: json
|
||||||
|
|
||||||
|
|
||||||
|
... rest of the document ...
|
||||||
|
{
|
||||||
|
"@type": "emotionSet",
|
||||||
|
"onyx:hasEmotion": {
|
||||||
|
"@type": "emotion",
|
||||||
|
"onyx:hasEmotionCategory": "emoml:big6anger"
|
||||||
|
},
|
||||||
|
"prov:wasGeneratedBy": "plugins/emoRand_0.1"
|
||||||
|
}, {
|
||||||
|
"@type": "emotionSet",
|
||||||
|
"onyx:hasEmotion": {
|
||||||
|
"@type": "emotion",
|
||||||
|
"A": 7.22,
|
||||||
|
"D": 6.28,
|
||||||
|
"V": 8.6
|
||||||
|
},
|
||||||
|
"prov:wasGeneratedBy": "plugins/Ekman2VAD_0.1"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
That is called a *full* response, as it simply adds the converted emotion alongside.
|
||||||
|
It is also possible to get the original emotion nested within the new converted emotion, using the `conversion=nested` parameter:
|
||||||
|
|
||||||
|
.. code:: json
|
||||||
|
|
||||||
|
|
||||||
|
... rest of the document ...
|
||||||
|
{
|
||||||
|
"@type": "emotionSet",
|
||||||
|
"onyx:hasEmotion": {
|
||||||
|
"@type": "emotion",
|
||||||
|
"onyx:hasEmotionCategory": "emoml:big6anger"
|
||||||
|
},
|
||||||
|
"prov:wasGeneratedBy": "plugins/emoRand_0.1"
|
||||||
|
"onyx:wasDerivedFrom": {
|
||||||
|
"@type": "emotionSet",
|
||||||
|
"onyx:hasEmotion": {
|
||||||
|
"@type": "emotion",
|
||||||
|
"A": 7.22,
|
||||||
|
"D": 6.28,
|
||||||
|
"V": 8.6
|
||||||
|
},
|
||||||
|
"prov:wasGeneratedBy": "plugins/Ekman2VAD_0.1"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Lastly, `conversion=filtered` would only return the converted emotions.
|
||||||
|
|
||||||
|
Developing a conversion plugin
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
Conversion plugins are discovered by the server just like any other plugin.
|
||||||
|
The difference is the slightly different API, and the need to specify the `source` and `target` of the conversion.
|
||||||
|
For instance, an emotion conversion plugin needs the following:
|
||||||
|
|
||||||
|
|
||||||
|
.. code:: yaml
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
onyx:doesConversion:
|
||||||
|
- onyx:conversionFrom: emoml:big6
|
||||||
|
onyx:conversionTo: emoml:fsre-dimensions
|
||||||
|
- onyx:conversionFrom: emoml:fsre-dimensions
|
||||||
|
onyx:conversionTo: emoml:big6
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
|
||||||
|
class MyConversion(EmotionConversionPlugin):
|
||||||
|
|
||||||
|
def convert(self, emotionSet, fromModel, toModel, params):
|
||||||
|
pass
|
@ -1,5 +1,7 @@
|
|||||||
Developing new plugins
|
Developing new plugins
|
||||||
----------------------
|
----------------------
|
||||||
|
This document describes how to develop a new analysis plugin. For an example of conversion plugins, see :doc:`conversion`.
|
||||||
|
|
||||||
Each plugin represents a different analysis process.There are two types of files that are needed by senpy for loading a plugin:
|
Each plugin represents a different analysis process.There are two types of files that are needed by senpy for loading a plugin:
|
||||||
|
|
||||||
- Definition file, has the ".senpy" extension.
|
- Definition file, has the ".senpy" extension.
|
||||||
|
@ -48,8 +48,8 @@ Once the server is launched, there is a basic endpoint in the server, which prov
|
|||||||
|
|
||||||
In case you want to know the different endpoints of the server, there is more information available in the NIF API section_.
|
In case you want to know the different endpoints of the server, there is more information available in the NIF API section_.
|
||||||
|
|
||||||
Video example
|
CLI
|
||||||
=============
|
===
|
||||||
|
|
||||||
This video shows how to use senpy through command-line tool.
|
This video shows how to use senpy through command-line tool.
|
||||||
|
|
||||||
@ -58,16 +58,17 @@ https://asciinema.org/a/9uwef1ghkjk062cw2t4mhzpyk
|
|||||||
Request example in python
|
Request example in python
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
This example shows how to make a request to a plugin.
|
This example shows how to make a request to the default plugin:
|
||||||
|
|
||||||
.. code:: python
|
.. code:: python
|
||||||
|
|
||||||
import requests
|
from senpy.client import Client
|
||||||
import json
|
|
||||||
|
|
||||||
r = requests.get('http://127.0.0.1:5000/api/?algo=rand&i=Testing')
|
c = Client('http://127.0.0.1:5000/api/')
|
||||||
response = r.content.decode('utf-8')
|
r = c.analyse('hello world')
|
||||||
response_json = json.loads(response)
|
|
||||||
|
for entry in r.entries:
|
||||||
|
print('{} -> {}'.format(entry.text, entry.emotions))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ class Client(object):
|
|||||||
try:
|
try:
|
||||||
resp = models.from_dict(response.json())
|
resp = models.from_dict(response.json())
|
||||||
resp.validate(resp)
|
resp.validate(resp)
|
||||||
return resp
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.error(('There seems to be a problem with the response:\n'
|
logger.error(('There seems to be a problem with the response:\n'
|
||||||
'\tURL: {url}\n'
|
'\tURL: {url}\n'
|
||||||
@ -33,3 +32,6 @@ class Client(object):
|
|||||||
code=response.status_code,
|
code=response.status_code,
|
||||||
content=response.content))
|
content=response.content))
|
||||||
raise ex
|
raise ex
|
||||||
|
if isinstance(resp, models.Error):
|
||||||
|
raise resp
|
||||||
|
return resp
|
||||||
|
@ -34,8 +34,11 @@ class ModelsTest(TestCase):
|
|||||||
url=endpoint + '/', method='GET', params={'input': 'hello'})
|
url=endpoint + '/', method='GET', params={'input': 'hello'})
|
||||||
error = Call(Error('Nothing'))
|
error = Call(Error('Nothing'))
|
||||||
with patch('requests.request', return_value=error) as patched:
|
with patch('requests.request', return_value=error) as patched:
|
||||||
resp = client.analyse(input='hello', algorithm='NONEXISTENT')
|
try:
|
||||||
assert isinstance(resp, Error)
|
client.analyse(input='hello', algorithm='NONEXISTENT')
|
||||||
|
raise Exception('Exceptions should be raised. This is not golang')
|
||||||
|
except Error:
|
||||||
|
pass
|
||||||
patched.assert_called_with(
|
patched.assert_called_with(
|
||||||
url=endpoint + '/',
|
url=endpoint + '/',
|
||||||
method='GET',
|
method='GET',
|
||||||
|
Loading…
Reference in New Issue
Block a user