Commit 8a516d92 authored by J. Fernando Sánchez's avatar J. Fernando Sánchez
Browse files

Multiple changes in the API, schemas and UI

Check out the CHANGELOG.md file for more information
parent 4ba30304
......@@ -28,6 +28,7 @@ test-3.5:
test-2.7:
<<: *test_definition
allow_failure: true
variables:
PYTHON_VERSION: "2.7"
......
......@@ -29,7 +29,7 @@ build: $(addprefix build-, $(PYVERSIONS)) ## Build all images / python versions
docker tag $(IMAGEWTAG)-python$(PYMAIN) $(IMAGEWTAG)
build-%: version Dockerfile-% ## Build a specific version (e.g. build-2.7)
docker build -t '$(IMAGEWTAG)-python$*' -f Dockerfile-$* .;
docker build --pull -t '$(IMAGEWTAG)-python$*' -f Dockerfile-$* .;
dev-%: ## Launch a specific development environment using docker (e.g. dev-2.7)
@docker start $(NAME)-dev$* || (\
......
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
* Objects can control the keys that will be used in `serialize`/`jsonld`/`as_dict` by specifying a list of keys in `terse_keys`.
e.g.
```python
>>> class MyModel(senpy.models.BaseModel):
... _terse_keys = ['visible']
... invisible = 5
... visible = 1
...
>>> m = MyModel(id='testing')
>>> m.jsonld()
{'invisible': 5, 'visible': 1, '@id': 'testing'}
>>> m.jsonld(verbose=False)
{'visible': 1}
```
* Configurable logging format.
* Added default terse keys for the most common classes (entry, sentiment, emotion...).
* Flag parameters (boolean) are set to true even when no value is added (e.g. `&verbose` is the same as `&verbose=true`).
* Plugin and parameter descriptions are now formatted with (showdown)[https://github.com/showdownjs/showdown].
* The web UI requests extra_parameters from the server. This is useful for pipelines. See #52
* First batch of semantic tests (using SPARQL)
### Changed
* `install_deps` now checks what requirements are already met before installing with pip.
* Help is now provided verbosely by default
* Other outputs are terse by default. This means some properties are now hidden unless verbose is set.
* `sentiments` and `emotions` are now `marl:hasOpinion` and `onyx:hasEmotionSet`, respectively.
* Nicer logging format
* Context aliases (e.g. `sentiments` and `emotions` properties) have been replaced with the original properties (e.g. `marl:hasOpinion` and `onyx:hasEmotionSet**), to use aliases, pass the `aliases** parameter.
* Several UI improvements
* Dedicated tab to show the list of plugins
* URLs in plugin descriptions are shown as links
* The format of the response is selected by clicking on a tab instead of selecting from a drop-down
* list of examples
* Bootstrap v4
* RandEmotion and RandSentiment are no longer included in the base set of plugins
* The `--plugin-folder` option can be used more than once, and every folder will be added to the app.
### Deprecated
### Removed
* Python 2.7 is no longer test or officially supported
### Fixed
* Plugin descriptions are now dedented when they are extracted from the docstring.
### Security
......@@ -5,7 +5,7 @@ IMAGENAME=gsiupm/senpy
# The first version is the main one (used for quick builds)
# See .makefiles/python.mk for more info
PYVERSIONS=3.5 2.7
PYVERSIONS=3.6 3.7
DEVPORT=5000
......
web: python -m senpy --host 0.0.0.0 --port $PORT --default-plugins
web: python -m senpy --host 0.0.0.0 --port $PORT
.. image:: img/header.png
:width: 100%
:target: http://demos.gsi.dit.upm.es/senpy
:target: http://senpy.gsi.upm.es
.. image:: https://travis-ci.org/gsi-upm/senpy.svg?branch=master
:target: https://travis-ci.org/gsi-upm/senpy
.. image:: https://lab.gsi.upm.es/senpy/senpy/badges/master/pipeline.svg
:target: https://lab.gsi.upm.es/senpy/senpy/commits/master
.. image:: https://lab.gsi.upm.es/senpy/senpy/badges/master/coverage.svg
:target: https://lab.gsi.upm.es/senpy/senpy/commits/master
.. image:: https://img.shields.io/pypi/l/requests.svg
:target: https://lab.gsi.upm.es/senpy/senpy/
Senpy lets you create sentiment analysis web services easily, fast and using a well known API.
As a bonus, senpy services use semantic vocabularies (e.g. `NIF <http://persistence.uni-leipzig.org/nlp2rdf/>`_, `Marl <http://www.gsi.dit.upm.es/ontologies/marl>`_, `Onyx <http://www.gsi.dit.upm.es/ontologies/onyx>`_) and formats (turtle, JSON-LD, xml-rdf).
......@@ -12,7 +21,7 @@ Have you ever wanted to turn your sentiment analysis algorithms into a service?
With senpy, now you can.
It provides all the tools so you just have to worry about improving your algorithms:
`See it in action. <http://senpy.cluster.gsi.dit.upm.es/>`_
`See it in action. <http://senpy.gsi.upm.es/>`_
Installation
------------
......@@ -38,9 +47,9 @@ If you want to install senpy globally, use sudo instead of the ``--user`` flag.
Docker Image
************
Build the image or use the pre-built one: ``docker run -ti -p 5000:5000 gsiupm/senpy --default-plugins``.
Build the image or use the pre-built one: ``docker run -ti -p 5000:5000 gsiupm/senpy``.
To add custom plugins, add a volume and tell senpy where to find the plugins: ``docker run -ti -p 5000:5000 -v <PATH OF PLUGINS>:/plugins gsiupm/senpy --default-plugins -f /plugins``
To add custom plugins, add a volume and tell senpy where to find the plugins: ``docker run -ti -p 5000:5000 -v <PATH OF PLUGINS>:/plugins gsiupm/senpy -f /plugins``
Developing
......@@ -125,6 +134,16 @@ For more information, check out the `documentation <http://senpy.readthedocs.org
------------------------------------------------------------------------------------
Python 2.x compatibility
------------------------
Keeping compatibility between python 2.7 and 3.x is not always easy, especially for a framework that deals both with text and web requests.
Hence, starting February 2019, this project will no longer make efforts to support python 2.7, which will reach its end of life in 2020.
Most of the functionality should still work, and the compatibility shims will remain for now, but we cannot make any guarantees at this point.
Instead, the maintainers will focus their efforts on keeping the codebase compatible across different Python 3.3+ versions, including upcoming ones.
We apologize for the inconvenience.
Acknowledgement
---------------
This development has been partially funded by the European Union through the MixedEmotions Project (project number H2020 655632), as part of the `RIA ICT 15 Big data and Open Data Innovation and take-up` programme.
......
import os
SERVER_PORT = os.environ.get("SERVER_PORT", 5000)
DEBUG = os.environ.get("DEBUG", True)
......@@ -24,6 +24,7 @@ I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " entr to watch for changes and continuously make HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
......@@ -49,6 +50,9 @@ help:
clean:
rm -rf $(BUILDDIR)/*
entr:
while true; do ag -g rst | entr -d make html; done
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Consuming Senpy services
========================
This short tutorial will teach you how to consume services in several
ways, taking advantage of the features of the framework.
In particular, we will cover:
- Annotating text with sentiment
- Annotating text with emotion
- Getting results in different formats (Turtle, XML, text…)
- Asking for specific emotion models (automatic model conversion)
- Listing available services in an endpoint
- Switching to different services
- Calling multiple services in the same request (Pipelines)
The latest version of this IPython notebook is available at:
https://github.com/gsi-upm/senpy/tree/master/docs/Quickstart.ipynb
Requirements
------------
For the sake of simplicity, this tutorial will use the demo server:
http://senpy.gsi.upm.es:
.. code:: ipython3
endpoint = 'http://senpy.gsi.upm.es/api'
This server runs some open source plugins for sentiment and emotion
analysis.
The HTTP API of Senpy can be queried with your favourite tool. This is
just an example using curl:
.. code:: bash
curl "http://senpy.gsi.upm.es/api/sentiment140" --data-urlencode "input=Senpy is awesome"
For simplicity, in this tutorial we will use the requests library. We
will also add a function to add syntax highlighting for the
JSON-LD/Turtle results:
.. code:: ipython3
try:
from IPython.display import Code
def pretty(txt, language='json-ld'):
return Code(txt, language=language)
except ImportError:
def pretty(txt, **kwargs):
print(txt)
Once you’re familiar with Senpy, you can deploy your own instance quite
easily. e.g. using docker:
::
docker run -ti --name 'SenpyEndpoint' -d -p 5000:5000 gsiupm/senpy
Then, feel free to change the endpoint variable to run the examples in
your own instance.
Sentiment Analysis of Text
--------------------------
To start, let us analyse the sentiment in the following sentence: *senpy
is a wonderful service*.
For now, we will use the `sentiment140 <http://www.sentiment140.com/>`__
service, through the sentiment140 plugin. We will later cover how to use
a different service.
.. code:: ipython3
import requests
res = requests.get(f'{endpoint}/sentiment140',
params={"input": "Senpy is awesome",})
pretty(res.text)
.. raw:: html
<style>.output_html .hll { background-color: #ffffcc }
.output_html { background: #f8f8f8; }
.output_html .c { color: #408080; font-style: italic } /* Comment */
.output_html .err { border: 1px solid #FF0000 } /* Error */
.output_html .k { color: #008000; font-weight: bold } /* Keyword */
.output_html .o { color: #666666 } /* Operator */
.output_html .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
.output_html .cm { color: #408080; font-style: italic } /* Comment.Multiline */
.output_html .cp { color: #BC7A00 } /* Comment.Preproc */
.output_html .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
.output_html .c1 { color: #408080; font-style: italic } /* Comment.Single */
.output_html .cs { color: #408080; font-style: italic } /* Comment.Special */
.output_html .gd { color: #A00000 } /* Generic.Deleted */
.output_html .ge { font-style: italic } /* Generic.Emph */
.output_html .gr { color: #FF0000 } /* Generic.Error */
.output_html .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.output_html .gi { color: #00A000 } /* Generic.Inserted */
.output_html .go { color: #888888 } /* Generic.Output */
.output_html .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.output_html .gs { font-weight: bold } /* Generic.Strong */
.output_html .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.output_html .gt { color: #0044DD } /* Generic.Traceback */
.output_html .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.output_html .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.output_html .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.output_html .kp { color: #008000 } /* Keyword.Pseudo */
.output_html .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.output_html .kt { color: #B00040 } /* Keyword.Type */
.output_html .m { color: #666666 } /* Literal.Number */
.output_html .s { color: #BA2121 } /* Literal.String */
.output_html .na { color: #7D9029 } /* Name.Attribute */
.output_html .nb { color: #008000 } /* Name.Builtin */
.output_html .nc { color: #0000FF; font-weight: bold } /* Name.Class */
.output_html .no { color: #880000 } /* Name.Constant */
.output_html .nd { color: #AA22FF } /* Name.Decorator */
.output_html .ni { color: #999999; font-weight: bold } /* Name.Entity */
.output_html .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
.output_html .nf { color: #0000FF } /* Name.Function */
.output_html .nl { color: #A0A000 } /* Name.Label */
.output_html .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.output_html .nt { color: #008000; font-weight: bold } /* Name.Tag */
.output_html .nv { color: #19177C } /* Name.Variable */
.output_html .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.output_html .w { color: #bbbbbb } /* Text.Whitespace */
.output_html .mb { color: #666666 } /* Literal.Number.Bin */
.output_html .mf { color: #666666 } /* Literal.Number.Float */
.output_html .mh { color: #666666 } /* Literal.Number.Hex */
.output_html .mi { color: #666666 } /* Literal.Number.Integer */
.output_html .mo { color: #666666 } /* Literal.Number.Oct */
.output_html .sa { color: #BA2121 } /* Literal.String.Affix */
.output_html .sb { color: #BA2121 } /* Literal.String.Backtick */
.output_html .sc { color: #BA2121 } /* Literal.String.Char */
.output_html .dl { color: #BA2121 } /* Literal.String.Delimiter */
.output_html .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.output_html .s2 { color: #BA2121 } /* Literal.String.Double */
.output_html .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
.output_html .sh { color: #BA2121 } /* Literal.String.Heredoc */
.output_html .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
.output_html .sx { color: #008000 } /* Literal.String.Other */
.output_html .sr { color: #BB6688 } /* Literal.String.Regex */
.output_html .s1 { color: #BA2121 } /* Literal.String.Single */
.output_html .ss { color: #19177C } /* Literal.String.Symbol */
.output_html .bp { color: #008000 } /* Name.Builtin.Pseudo */
.output_html .fm { color: #0000FF } /* Name.Function.Magic */
.output_html .vc { color: #19177C } /* Name.Variable.Class */
.output_html .vg { color: #19177C } /* Name.Variable.Global */
.output_html .vi { color: #19177C } /* Name.Variable.Instance */
.output_html .vm { color: #19177C } /* Name.Variable.Magic */
.output_html .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class="highlight"><pre><span></span><span class="p">{</span>
<span class="nd">&quot;@context&quot;</span><span class="p">:</span> <span class="s2">&quot;http://senpy.gsi.upm.es/api/contexts/YXBpL3NlbnRpbWVudDE0MD9pbnB1dD1TZW5weStpcythd2Vzb21lIw%3D%3D&quot;</span><span class="p">,</span>
<span class="nd">&quot;@type&quot;</span><span class="p">:</span> <span class="s2">&quot;Results&quot;</span><span class="p">,</span>
<span class="nt">&quot;entries&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nd">&quot;@id&quot;</span><span class="p">:</span> <span class="s2">&quot;prefix:&quot;</span><span class="p">,</span>
<span class="nd">&quot;@type&quot;</span><span class="p">:</span> <span class="s2">&quot;Entry&quot;</span><span class="p">,</span>
<span class="nt">&quot;marl:hasOpinion&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nd">&quot;@type&quot;</span><span class="p">:</span> <span class="s2">&quot;Sentiment&quot;</span><span class="p">,</span>
<span class="nt">&quot;marl:hasPolarity&quot;</span><span class="p">:</span> <span class="s2">&quot;marl:Positive&quot;</span><span class="p">,</span>
<span class="nt">&quot;prov:wasGeneratedBy&quot;</span><span class="p">:</span> <span class="s2">&quot;prefix:Analysis_1554364667.7955277&quot;</span>
<span class="p">}</span>
<span class="p">],</span>
<span class="nt">&quot;nif:isString&quot;</span><span class="p">:</span> <span class="s2">&quot;Senpy is awesome&quot;</span><span class="p">,</span>
<span class="nt">&quot;onyx:hasEmotionSet&quot;</span><span class="p">:</span> <span class="p">[]</span>
<span class="p">}</span>
<span class="p">]</span>
<span class="p">}</span>
</pre></div>
Senpy services always return an object of type ``senpy:Results``, with a
list of entries. You can think of an entry as a self-contained textual
context (``nif:Context`` and ``senpy:Entry``). Entries can be as short
as a sentence, or as long as a news article.
Each entry has a ``nif:isString`` property that contains the original
text of the entry, and several other properties that are provided by the
plugins.
For instance, sentiment annotations are provided through
``marl:hasOpinion``.
The annotations are semantic. We can ask Senpy for the expanded JSON-LD
output to reveal the full URIs of each property and entity:
.. code:: ipython3
import requests
res = requests.get(f'{endpoint}/sentiment140',
params={"input": "Senpy is awesome",
"expanded": True})
pretty(res.text)
.. raw:: html
<style>.output_html .hll { background-color: #ffffcc }
.output_html { background: #f8f8f8; }
.output_html .c { color: #408080; font-style: italic } /* Comment */
.output_html .err { border: 1px solid #FF0000 } /* Error */
.output_html .k { color: #008000; font-weight: bold } /* Keyword */
.output_html .o { color: #666666 } /* Operator */
.output_html .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
.output_html .cm { color: #408080; font-style: italic } /* Comment.Multiline */
.output_html .cp { color: #BC7A00 } /* Comment.Preproc */
.output_html .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
.output_html .c1 { color: #408080; font-style: italic } /* Comment.Single */
.output_html .cs { color: #408080; font-style: italic } /* Comment.Special */
.output_html .gd { color: #A00000 } /* Generic.Deleted */
.output_html .ge { font-style: italic } /* Generic.Emph */
.output_html .gr { color: #FF0000 } /* Generic.Error */
.output_html .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.output_html .gi { color: #00A000 } /* Generic.Inserted */
.output_html .go { color: #888888 } /* Generic.Output */
.output_html .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.output_html .gs { font-weight: bold } /* Generic.Strong */
.output_html .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.output_html .gt { color: #0044DD } /* Generic.Traceback */
.output_html .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.output_html .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.output_html .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.output_html .kp { color: #008000 } /* Keyword.Pseudo */
.output_html .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.output_html .kt { color: #B00040 } /* Keyword.Type */
.output_html .m { color: #666666 } /* Literal.Number */
.output_html .s { color: #BA2121 } /* Literal.String */
.output_html .na { color: #7D9029 } /* Name.Attribute */
.output_html .nb { color: #008000 } /* Name.Builtin */
.output_html .nc { color: #0000FF; font-weight: bold } /* Name.Class */
.output_html .no { color: #880000 } /* Name.Constant */
.output_html .nd { color: #AA22FF } /* Name.Decorator */
.output_html .ni { color: #999999; font-weight: bold } /* Name.Entity */
.output_html .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
.output_html .nf { color: #0000FF } /* Name.Function */
.output_html .nl { color: #A0A000 } /* Name.Label */
.output_html .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.output_html .nt { color: #008000; font-weight: bold } /* Name.Tag */
.output_html .nv { color: #19177C } /* Name.Variable */
.output_html .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.output_html .w { color: #bbbbbb } /* Text.Whitespace */
.output_html .mb { color: #666666 } /* Literal.Number.Bin */
.output_html .mf { color: #666666 } /* Literal.Number.Float */
.output_html .mh { color: #666666 } /* Literal.Number.Hex */
.output_html .mi { color: #666666 } /* Literal.Number.Integer */
.output_html .mo { color: #666666 } /* Literal.Number.Oct */
.output_html .sa { color: #BA2121 } /* Literal.String.Affix */
.output_html .sb { color: #BA2121 } /* Literal.String.Backtick */
.output_html .sc { color: #BA2121 } /* Literal.String.Char */
.output_html .dl { color: #BA2121 } /* Literal.String.Delimiter */
.output_html .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.output_html .s2 { color: #BA2121 } /* Literal.String.Double */
.output_html .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
.output_html .sh { color: #BA2121 } /* Literal.String.Heredoc */
.output_html .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
.output_html .sx { color: #008000 } /* Literal.String.Other */
.output_html .sr { color: #BB6688 } /* Literal.String.Regex */
.output_html .s1 { color: #BA2121 } /* Literal.String.Single */
.output_html .ss { color: #19177C } /* Literal.String.Symbol */
.output_html .bp { color: #008000 } /* Name.Builtin.Pseudo */
.output_html .fm { color: #0000FF } /* Name.Function.Magic */
.output_html .vc { color: #19177C } /* Name.Variable.Class */
.output_html .vg { color: #19177C } /* Name.Variable.Global */
.output_html .vi { color: #19177C } /* Name.Variable.Instance */
.output_html .vm { color: #19177C } /* Name.Variable.Magic */
.output_html .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class="highlight"><pre><span></span><span class="p">{</span>
<span class="nd">&quot;@context&quot;</span><span class="p">:</span> <span class="s2">&quot;http://senpy.gsi.upm.es/api/contexts/YXBpL3NlbnRpbWVudDE0MD9pbnB1dD1TZW5weStpcythd2Vzb21lJmV4cGFuZGVkPVRydWUj&quot;</span><span class="p">,</span>
<span class="nd">&quot;@type&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="s2">&quot;http://www.gsi.upm.es/onto/senpy/ns#Results&quot;</span>
<span class="p">],</span>
<span class="nt">&quot;http://www.w3.org/ns/prov#used&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nd">&quot;@id&quot;</span><span class="p">:</span> <span class="s2">&quot;http://senpy.invalid/&quot;</span><span class="p">,</span>
<span class="nd">&quot;@type&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="s2">&quot;http://www.gsi.upm.es/onto/senpy/ns#Entry&quot;</span>
<span class="p">],</span>
<span class="nt">&quot;http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core#isString&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nd">&quot;@value&quot;</span><span class="p">:</span> <span class="s2">&quot;Senpy is awesome&quot;</span>
<span class="p">}</span>
<span class="p">],</span>
<span class="nt">&quot;http://www.gsi.dit.upm.es/ontologies/marl/ns#hasOpinion&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nd">&quot;@type&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="s2">&quot;http://www.gsi.upm.es/onto/senpy/ns#Sentiment&quot;</span>
<span class="p">],</span>
<span class="nt">&quot;http://www.gsi.dit.upm.es/ontologies/marl/ns#hasPolarity&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nd">&quot;@value&quot;</span><span class="p">:</span> <span class="s2">&quot;marl:Positive&quot;</span>
<span class="p">}</span>
<span class="p">],</span>
<span class="nt">&quot;http://www.w3.org/ns/prov#wasGeneratedBy&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nd">&quot;@id&quot;</span><span class="p">:</span> <span class="s2">&quot;http://senpy.invalid/Analysis_1554364668.1011338&quot;</span>
<span class="p">}</span>
<span class="p">]</span>
<span class="p">}</span>
<span class="p">],</span>
<span class="nt">&quot;http://www.gsi.dit.upm.es/ontologies/onyx/ns#hasEmotionSet&quot;</span><span class="p">:</span> <span class="p">[]</span>
<span class="p">}</span>
<span class="p">]</span>
<span class="p">}</span>
</pre></div>
.. code:: ipython3
pretty(res.text)
.. raw:: html
<style>.output_html .hll { background-color: #ffffcc }
.output_html { background: #f8f8f8; }
.output_html .c { color: #408080; font-style: italic } /* Comment */
.output_html .err { border: 1px solid #FF0000 } /* Error */
.output_html .k { color: #008000; font-weight: bold } /* Keyword */
.output_html .o { color: #666666 } /* Operator */
.output_html .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
.output_html .cm { color: #408080; font-style: italic } /* Comment.Multiline */
.output_html .cp { color: #BC7A00 } /* Comment.Preproc */
.output_html .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
.output_html .c1 { color: #408080; font-style: italic } /* Comment.Single */
.output_html .cs { color: #408080; font-style: italic } /* Comment.Special */
.output_html .gd { color: #A00000 } /* Generic.Deleted */
.output_html .ge { font-style: italic } /* Generic.Emph */
.output_html .gr { color: #FF0000 } /* Generic.Error */
.output_html .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.output_html .gi { color: #00A000 } /* Generic.Inserted */
.output_html .go { color: #888888 } /* Generic.Output */
.output_html .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.output_html .gs { font-weight: bold } /* Generic.Strong */
.output_html .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.output_html .gt { color: #0044DD } /* Generic.Traceback */
.output_html .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.output_html .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.output_html .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.output_html .kp { color: #008000 } /* Keyword.Pseudo */
.output_html .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.output_html .kt { color: #B00040 } /* Keyword.Type */
.output_html .m { color: #666666 } /* Literal.Number */
.output_html .s { color: #BA2121 } /* Literal.String */
.output_html .na { color: #7D9029 } /* Name.Attribute */
.output_html .nb { color: #008000 } /* Name.Builtin */
.output_html .nc { color: #0000FF; font-weight: bold } /* Name.Class */
.output_html .no { color: #880000 } /* Name.Constant */
.output_html .nd { color: #AA22FF } /* Name.Decorator */
.output_html .ni { color: #999999; font-weight: bold } /* Name.Entity */
.output_html .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
.output_html .nf { color: #0000FF } /* Name.Function */
.output_html .nl { color: #A0A000 } /* Name.Label */
.output_html .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.output_html .nt { color: #008000; font-weight: bold } /* Name.Tag */
.output_html .nv { color: #19177C } /* Name.Variable */
.output_html .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.output_html .w { color: #bbbbbb } /* Text.Whitespace */
.output_html .mb { color: #666666 } /* Literal.Number.Bin */
.output_html .mf { color: #666666 } /* Literal.Number.Float */
.output_html .mh { color: #666666 } /* Literal.Number.Hex */
.output_html .mi { color: #666666 } /* Literal.Number.Integer */
.output_html .mo { color: #666666 } /* Literal.Number.Oct */
.output_html .sa { color: #BA2121 } /* Literal.String.Affix */
.output_html .sb { color: #BA2121 } /* Literal.String.Backtick */
.output_html .sc { color: #BA2121 } /* Literal.String.Char */
.output_html .dl { color: #BA2121 } /* Literal.String.Delimiter */
.output_html .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.output_html .s2 { color: #BA2121 } /* Literal.String.Double */
.output_html .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
.output_html .sh { color: #BA2121 } /* Literal.String.Heredoc */
.output_html .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
.output_html .sx { color: #008000 } /* Literal.String.Other */
.output_html .sr { color: #BB6688 } /* Literal.String.Regex */
.output_html .s1 { color: #BA2121 } /* Literal.String.Single */
.output_html .ss { color: #19177C } /* Literal.String.Symbol */
.output_html .bp { color: #008000 } /* Name.Builtin.Pseudo */
.output_html .fm { color: #0000FF } /* Name.Function.Magic */
.output_html .vc { color: #19177C } /* Name.Variable.Class */
.output_html .vg { color: #19177C } /* Name.Variable.Global */
.output_html .vi { color: #19177C } /* Name.Variable.Instance */
.output_html .vm { color: #19177C } /* Name.Variable.Magic */
.output_html .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class="highlight"><pre><span></span><span class="p">{</span>
<span class="nd">&quot;@context&quot;</span><span class="p">:</span> <span class="s2">&quot;http://senpy.gsi.upm.es/api/contexts/YXBpL3NlbnRpbWVudDE0MD9pbnB1dD1TZW5weStpcythd2Vzb21lJmV4cGFuZGVkPVRydWUj&quot;</span><span class="p">,</span>
<span class="nd">&quot;@type&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="s2">&quot;http://www.gsi.upm.es/onto/senpy/ns#Results&quot;</span>
<span class="p">],</span>
<span class="nt">&quot;http://www.w3.org/ns/prov#used&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nd">&quot;@id&quot;</span><span class="p">:</span> <span class="s2">&quot;http://senpy.invalid/&quot;</span><span class="p">,</span>
<span class="nd">&quot;@type&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="s2">&quot;http://www.gsi.upm.es/onto/senpy/ns#Entry&quot;</span>
<span class="p">],</span>
<span class="nt">&quot;http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core#isString&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nd">&quot;@value&quot;</span><span class="p">:</span> <span class="s2">&quot;Senpy is awesome&quot;</span>
<span class="p">}</span>
<span class="p">],</span>
<span class="nt">&quot;http://www.gsi.dit.upm.es/ontologies/marl/ns#hasOpinion&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nd">&quot;@type&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="s2">&quot;http://www.gsi.upm.es/onto/senpy/ns#Sentiment&quot;</span>
<span class="p">],</span>
<span class="nt">&quot;http://www.gsi.dit.upm.es/ontologies/marl/ns#hasPolarity&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nd">&quot;@value&quot;</span><span class="p">:</span> <span class="s2">&quot;marl:Positive&quot;</span>
<span class="p">}</span>
<span class="p">],</span>
<span class="nt">&quot;http://www.w3.org/ns/prov#wasGeneratedBy&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span>
<span class="nd">&quot;@id&quot;</span><span class="p">:</span> <span class="s2">&quot;http://senpy.invalid/Analysis_1554364668.1011338&quot;</span>
<span class="p">}</span>
<span class="p">]</span>
<span class="p">}</span>
<span class="p">],</span>
<span class="nt">&quot;http://www.gsi.dit.upm.es/ontologies/onyx/ns#hasEmotionSet&quot;</span><span class="p">:</span> <span class="p">[]</span>
<span class="p">}</span>
<span class="p">]</span>
<span class="p">}</span>
</pre></div>
Other output formats
--------------------
Senpy supports several semantic formats, like turtle and xml-RDF. You
can select the format of the output with the ``outformat`` parameter:
.. code:: ipython3
res = requests.get(f'{endpoint}/sentiment140',
params={"input": "Senpy is the best framework for semantic sentiment analysis, and very easy to use",
"outformat": "turtle"})
pretty(res.text, language='turtle')
.. raw:: html
<style>.output_html .hll { background-color: #ffffcc }
.output_html { background: #f8f8f8; }
.output_html .c { color: #408080; font-style: italic } /* Comment */
.output_html .err { border: 1px solid #FF0000 } /* Error */
.output_html .k { color: #008000; font-weight: bold } /* Keyword */
.output_html .o { color: #666666 } /* Operator */
.output_html .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
.output_html .cm { color: #408080; font-style: italic } /* Comment.Multiline */
.output_html .cp { color: #BC7A00 } /* Comment.Preproc */
.output_html .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
.output_html .c1 { color: #408080; font-style: italic } /* Comment.Single */
.output_html .cs { color: #408080; font-style: italic } /* Comment.Special */
.output_html .gd { color: #A00000 } /* Generic.Deleted */
.output_html .ge { font-style: italic } /* Generic.Emph */
.output_html .gr { color: #FF0000 } /* Generic.Error */
.output_html .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.output_html .gi { color: #00A000 } /* Generic.Inserted */
.output_html .go { color: #888888 } /* Generic.Output */
.output_html .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.output_html .gs { font-weight: bold } /* Generic.Strong */