Commit 2b688385 authored by J. Fernando Sánchez's avatar J. Fernando Sánchez
Browse files

PEP8 compliance

parent eaf65f0c
...@@ -14,11 +14,11 @@ ...@@ -14,11 +14,11 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
''' """
Simple Sentiment Analysis server for EUROSENTIMENT Simple Sentiment Analysis server for EUROSENTIMENT
This class shows how to use the nif_server module to create custom services. This class shows how to use the nif_server module to create custom services.
''' """
import config import config
from flask import Flask from flask import Flask
from senpy.extensions import Senpy from senpy.extensions import Senpy
......
mock
\ No newline at end of file
from senpy.plugins import SenpyPlugin
class Prueba(SenpyPlugin):
def __init__(self, **kwargs):
super(Prueba, self).__init__(name="prueba",
version="4.0",
**kwargs)
plugin = Prueba()
import requests import requests
import json import json
import sys
from senpy.plugins import SentimentPlugin from senpy.plugins import SentimentPlugin
from senpy.models import Response, Opinion, Entry from senpy.models import Response, Opinion, Entry
class Sentiment140Plugin(SentimentPlugin): class Sentiment140Plugin(SentimentPlugin):
EXTRA_PARAMS = { EXTRA_PARAMS = {
"language": {"aliases": ["language", "l"], "language": {"aliases": ["language", "l"],
...@@ -13,6 +12,7 @@ class Sentiment140Plugin(SentimentPlugin): ...@@ -13,6 +12,7 @@ class Sentiment140Plugin(SentimentPlugin):
"options": ["es", "en", "auto"], "options": ["es", "en", "auto"],
} }
} }
def __init__(self, **kwargs): def __init__(self, **kwargs):
super(Sentiment140Plugin, self).__init__(name="sentiment140", super(Sentiment140Plugin, self).__init__(name="sentiment140",
version="2.0", version="2.0",
...@@ -22,23 +22,21 @@ class Sentiment140Plugin(SentimentPlugin): ...@@ -22,23 +22,21 @@ class Sentiment140Plugin(SentimentPlugin):
def analyse(self, **params): def analyse(self, **params):
lang = params.get("language", "auto") lang = params.get("language", "auto")
res = requests.post("http://www.sentiment140.com/api/bulkClassifyJson", res = requests.post("http://www.sentiment140.com/api/bulkClassifyJson",
json.dumps({ json.dumps({"language": lang,
"language": lang, "data": [{"text": params["input"]}]
"data": [{"text": params["input"]}]} }
)) )
)
response = Response() response = Response()
polarityValue = int(res.json()["data"][0]["polarity"]) * 25 polarity_value = int(res.json()["data"][0]["polarity"]) * 25
polarity = "marl:Neutral" polarity = "marl:Neutral"
if polarityValue > 50: if polarity_value > 50:
polarity = "marl:Positive" polarity = "marl:Positive"
elif polarityValue < 50: elif polarity_value < 50:
polarity = "marl:Negative" polarity = "marl:Negative"
entry = Entry(text=params["input"]) entry = Entry(text=params["input"])
opinion = Opinion(polarity=polarity, polarityValue=polarityValue) opinion = Opinion(polarity=polarity, polarity_value=polarity_value)
entry.opinions.append(opinion) entry.opinions.append(opinion)
entry.language = lang entry.language = lang
response.entries.append(entry) response.entries.append(entry)
......
Flask==0.10.1 Flask==0.10.1
gunicorn==19.0.0 gunicorn==19.0.0
requests==2.4.1 requests==2.4.1
Flask-Plugins==1.4 GitPython==0.3.2.RC1
GitPython==0.3.2.RC1 \ No newline at end of file
...@@ -14,21 +14,12 @@ ...@@ -14,21 +14,12 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
''' """
Sentiment analysis server in Python Sentiment analysis server in Python
''' """
VERSION = "0.2.6" VERSION = "0.2.7"
import extensions import extensions
import blueprints import blueprints
import plugins import plugins
if __name__ == '__main__':
from flask import Flask
app = Flask(__name__)
sp = extensions.Senpy()
sp.init_app(app)
app.debug = config.DEBUG
app.run()
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2014 J. Fernando Sánchez Rada - Grupo de Sistemas Inteligentes # Copyright 2014 J. Fernando Sánchez Rada - Grupo de Sistemas Inteligentes
# DIT, UPM # DIT, UPM
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
# You may obtain a copy of the License at # You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
''' """
Simple Sentiment Analysis server Blueprints for Senpy
''' """
import json import json
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
from flask import Blueprint, render_template, request, jsonify, current_app from flask import Blueprint, request, jsonify, current_app
nif_blueprint = Blueprint("NIF Sentiment Analysis Server", __name__) nif_blueprint = Blueprint("NIF Sentiment Analysis Server", __name__)
...@@ -31,8 +32,8 @@ BASIC_PARAMS = { ...@@ -31,8 +32,8 @@ BASIC_PARAMS = {
}, },
} }
def get_params(req, params=BASIC_PARAMS): def get_params(req, params=BASIC_PARAMS):
indict = None
if req.method == 'POST': if req.method == 'POST':
indict = req.form indict = req.form
elif req.method == 'GET': elif req.method == 'GET':
...@@ -41,37 +42,37 @@ def get_params(req, params=BASIC_PARAMS): ...@@ -41,37 +42,37 @@ def get_params(req, params=BASIC_PARAMS):
raise ValueError("Invalid data") raise ValueError("Invalid data")
outdict = {} outdict = {}
wrongParams = {} wrong_params = {}
for param, options in params.iteritems(): for param, options in params.iteritems():
for alias in options["aliases"]: for alias in options["aliases"]:
if alias in indict: if alias in indict:
outdict[param] = indict[alias] outdict[param] = indict[alias]
if param not in outdict: if param not in outdict:
if options.get("required", False): if options.get("required", False):
wrongParams[param] = params[param] wrong_params[param] = params[param]
else: else:
if "default" in options: if "default" in options:
outdict[param] = options["default"] outdict[param] = options["default"]
else: else:
if "options" in params[param] and \ if "options" in params[param] and outdict[param] not in params[param]["options"]:
outdict[param] not in params[param]["options"]: wrong_params[param] = params[param]
wrongParams[param] = params[param] if wrong_params:
if wrongParams: message = {"status": "failed",
message = {"status": "failed", "message": "Missing or invalid parameters"} "message": "Missing or invalid parameters",
message["parameters"] = outdict "parameters": outdict,
message["errors"] = {param:error for param, error in wrongParams.iteritems()} "errors": {param: error for param, error in wrong_params.iteritems()}
}
raise ValueError(json.dumps(message)) raise ValueError(json.dumps(message))
return outdict return outdict
def basic_analysis(params): def basic_analysis(params):
response = {"@context": ["http://demos.gsi.dit.upm.es/eurosentiment/static/context.jsonld", response = {"@context": ["http://demos.gsi.dit.upm.es/eurosentiment/static/context.jsonld",
{ {
"@base": "{}#".format(request.url.encode('utf-8')) "@base": "{}#".format(request.url.encode('utf-8'))
} }
], ],
"analysis": [{ "analysis": [{"@type": "marl:SentimentAnalysis"}],
"@type": "marl:SentimentAnalysis"
}],
"entries": [] "entries": []
} }
if "language" in params: if "language" in params:
...@@ -83,8 +84,9 @@ def basic_analysis(params): ...@@ -83,8 +84,9 @@ def basic_analysis(params):
}) })
return response return response
@nif_blueprint.route('/', methods=['POST', 'GET']) @nif_blueprint.route('/', methods=['POST', 'GET'])
def home(entries=None): def home():
try: try:
algo = get_params(request).get("algorithm", None) algo = get_params(request).get("algorithm", None)
specific_params = current_app.senpy.parameters(algo) specific_params = current_app.senpy.parameters(algo)
...@@ -96,11 +98,13 @@ def home(entries=None): ...@@ -96,11 +98,13 @@ def home(entries=None):
except Exception as ex: except Exception as ex:
return jsonify(status="400", message=ex.message) return jsonify(status="400", message=ex.message)
@nif_blueprint.route("/default") @nif_blueprint.route("/default")
def default(): def default():
return current_app.senpy.default_plugin return current_app.senpy.default_plugin
#return plugins(action="list", plugin=current_app.senpy.default_algorithm) #return plugins(action="list", plugin=current_app.senpy.default_algorithm)
@nif_blueprint.route('/plugins/', methods=['POST', 'GET']) @nif_blueprint.route('/plugins/', methods=['POST', 'GET'])
@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'])
...@@ -113,7 +117,7 @@ def plugins(plugin=None, action="list"): ...@@ -113,7 +117,7 @@ def plugins(plugin=None, action="list"):
return "Plugin not found", 400 return "Plugin not found", 400
if action == "list": if action == "list":
with_params = request.args.get("params", "") == "1" with_params = request.args.get("params", "") == "1"
dic = {plug:plugs[plug].jsonable(with_params) for plug in plugs} dic = {plug: plugs[plug].jsonable(with_params) for plug in plugs}
return jsonify(dic) return jsonify(dic)
if action == "disable": if action == "disable":
current_app.senpy.disable_plugin(plugin) current_app.senpy.disable_plugin(plugin)
...@@ -127,9 +131,11 @@ def plugins(plugin=None, action="list"): ...@@ -127,9 +131,11 @@ def plugins(plugin=None, action="list"):
else: else:
return "action '{}' not allowed".format(action), 400 return "action '{}' not allowed".format(action), 400
if __name__ == '__main__': if __name__ == '__main__':
import config import config
from flask import Flask from flask import Flask
app = Flask(__name__) app = Flask(__name__)
app.register_blueprint(nif_blueprint) app.register_blueprint(nif_blueprint)
app.debug = config.DEBUG app.debug = config.DEBUG
......
"""
"""
import os import os
import sys import sys
import imp import imp
...@@ -55,7 +57,6 @@ class Senpy(object): ...@@ -55,7 +57,6 @@ class Senpy(object):
else: else:
return False return False
def analyse(self, **params): def analyse(self, **params):
algo = None algo = None
logger.debug("analysing with params: {}".format(params)) logger.debug("analysing with params: {}".format(params))
...@@ -69,12 +70,12 @@ class Senpy(object): ...@@ -69,12 +70,12 @@ class Senpy(object):
resp.analysis.append(plug.jsonable()) resp.analysis.append(plug.jsonable())
return resp return resp
else: else:
return {"status": 400, "message": "The algorithm '{}' is not valid".format(algo) } return {"status": 400, "message": "The algorithm '{}' is not valid".format(algo)}
@property @property
def default_plugin(self): def default_plugin(self):
candidates = self.filter_plugins(enabled=True) candidates = self.filter_plugins(enabled=True)
if len(candidates)>1: if len(candidates) > 1:
candidate = candidates.keys()[0] candidate = candidates.keys()[0]
logger.debug("Default: {}".format(candidate)) logger.debug("Default: {}".format(candidate))
return candidate return candidate
...@@ -97,7 +98,8 @@ class Senpy(object): ...@@ -97,7 +98,8 @@ class Senpy(object):
del self.plugins[plugin] del self.plugins[plugin]
self.plugins[nplug.name] = nplug self.plugins[nplug.name] = nplug
def _load_plugin(self, plugin, search_folder, enabled=True): @staticmethod
def _load_plugin(plugin, search_folder, enabled=True):
logger.debug("Loading plugins") logger.debug("Loading plugins")
sys.path.append(search_folder) sys.path.append(search_folder)
(fp, pathname, desc) = imp.find_module(plugin) (fp, pathname, desc) = imp.find_module(plugin)
...@@ -118,14 +120,14 @@ class Senpy(object): ...@@ -118,14 +120,14 @@ class Senpy(object):
logger.debug("Exception importing {}: {}".format(plugin, ex)) logger.debug("Exception importing {}: {}".format(plugin, ex))
return tmp return tmp
def _load_plugins(self): def _load_plugins(self):
plugins = {} plugins = {}
for search_folder in self._search_folders: for search_folder in self._search_folders:
for item in os.listdir(search_folder): for item in os.listdir(search_folder):
if os.path.isdir(os.path.join(search_folder, item)) \ if os.path.isdir(os.path.join(search_folder, item)) \
and os.path.exists( and os.path.exists(os.path.join(search_folder,
os.path.join(search_folder, item, "__init__.py")): item,
"__init__.py")):
plugin = self._load_plugin(item, search_folder) plugin = self._load_plugin(item, search_folder)
if plugin: if plugin:
plugins[plugin.name] = plugin plugins[plugin.name] = plugin
...@@ -140,12 +142,6 @@ class Senpy(object): ...@@ -140,12 +142,6 @@ class Senpy(object):
for plugin in self.plugins: for plugin in self.plugins:
self.enable_plugin(plugin) self.enable_plugin(plugin)
def enable_plugin(self, item):
self.plugins[item].enabled = True
def disable_plugin(self, item):
self.plugins[item].enabled = False
@property @property
def plugins(self): def plugins(self):
""" Return the plugins registered for a given application. """ """ Return the plugins registered for a given application. """
...@@ -157,27 +153,20 @@ class Senpy(object): ...@@ -157,27 +153,20 @@ class Senpy(object):
def filter_plugins(self, **kwargs): def filter_plugins(self, **kwargs):
""" Filter plugins by different criteria """ """ Filter plugins by different criteria """
def matches(plug): def matches(plug):
res = all(getattr(plug, k, None) == v for (k, v) in kwargs.items()) res = all(getattr(plug, k, None) == v for (k, v) in kwargs.items())
logger.debug("matching {} with {}: {}".format(plug.name, logger.debug("matching {} with {}: {}".format(plug.name,
kwargs, kwargs,
res)) res))
return res return res
if not kwargs: if not kwargs:
return self.plugins return self.plugins
else: else:
return {n:p for n, p in self.plugins.items() if matches(p)} return {n: p for n, p in self.plugins.items() if matches(p)}
def sentiment_plugins(self): def sentiment_plugins(self):
""" Return only the sentiment plugins """ """ Return only the sentiment plugins """
return {p:plugin for p, plugin in self.plugins.items() if return {p: plugin for p, plugin in self.plugins.items() if
isinstance(plugin, SentimentPlugin)} isinstance(plugin, SentimentPlugin)}
\ No newline at end of file
if __name__ == '__main__':
from flask import Flask
app = Flask(__name__)
sp = Senpy()
sp.init_app(APP)
with APP.app_context():
sp._load_plugins()
...@@ -2,6 +2,7 @@ import json ...@@ -2,6 +2,7 @@ import json
import os import os
from collections import defaultdict from collections import defaultdict
class Leaf(defaultdict): class Leaf(defaultdict):
def __init__(self, ofclass=list): def __init__(self, ofclass=list):
super(Leaf, self).__init__(ofclass) super(Leaf, self).__init__(ofclass)
...@@ -15,6 +16,7 @@ class Leaf(defaultdict): ...@@ -15,6 +16,7 @@ class Leaf(defaultdict):
def __delattr__(self, name): def __delattr__(self, name):
return super(Leaf, self).__delitem__(name) return super(Leaf, self).__delitem__(name)
class Response(Leaf): class Response(Leaf):
def __init__(self, context=None): def __init__(self, context=None):
super(Response, self).__init__() super(Response, self).__init__()
...@@ -22,10 +24,10 @@ class Response(Leaf): ...@@ -22,10 +24,10 @@ class Response(Leaf):
self["entries"] = [] self["entries"] = []
if context is None: if context is None:
context = "{}/context.jsonld".format(os.path.dirname( context = "{}/context.jsonld".format(os.path.dirname(
os.path.realpath(__file__))) os.path.realpath(__file__)))
if isinstance(context, dict): if isinstance(context, dict):
self["@context"] = context self["@context"] = context
if isinstance(context, basestring): if isinstance(context, str) or isinstance(context, unicode):
try: try:
with open(context) as f: with open(context) as f:
self["@context"] = json.loads(f.read()) self["@context"] = json.loads(f.read())
...@@ -34,26 +36,28 @@ class Response(Leaf): ...@@ -34,26 +36,28 @@ class Response(Leaf):
class Entry(Leaf): class Entry(Leaf):
def __init__(self, text=None, emotionSets=None, opinions=None, **kwargs): def __init__(self, text=None, emotion_sets=None, opinions=None, **kwargs):
super(Entry, self).__init__(**kwargs) super(Entry, self).__init__(**kwargs)
if text: if text:
self.text = text self.text = text
if emotionSets: if emotion_sets:
self.emotionSets = emotionSets self.emotionSets = emotion_sets
if opinions: if opinions:
self.opinions = opinions self.opinions = opinions
class Opinion(Leaf): class Opinion(Leaf):
def __init__(self, polarityValue=None, polarity=None, **kwargs): def __init__(self, polarity_value=None, polarity=None, **kwargs):
super(Opinion, self).__init__(**kwargs) super(Opinion, self).__init__(**kwargs)
if polarityValue is not None: if polarity_value is not None:
self.polarityValue = polarityValue self.polarity_value = polarity_value
if polarity is not None: if polarity is not None:
self.polarity = polarity self.polarity = polarity
class EmotionSet(Leaf): class EmotionSet(Leaf):
def __init__(self, emotions=[], **kwargs): def __init__(self, emotions=None, **kwargs):
if not emotions:
emotions = []
super(EmotionSet, self).__init__(**kwargs) super(EmotionSet, self).__init__(**kwargs)
self.emotions = emotions or [] self.emotions = emotions or []
...@@ -32,6 +32,7 @@ PARAMS = {"input": {"aliases": ["i", "input"], ...@@ -32,6 +32,7 @@ PARAMS = {"input": {"aliases": ["i", "input"],
}, },
} }
class SenpyPlugin(object): class SenpyPlugin(object):
def __init__(self, name=None, version=None, extraparams=None, params=None): def __init__(self, name=None, version=None, extraparams=None, params=None):
logger.debug("Initialising {}".format(name)) logger.debug("Initialising {}".format(name))
...@@ -56,11 +57,11 @@ class SenpyPlugin(object): ...@@ -56,11 +57,11 @@ class SenpyPlugin(object):
self.enabled = False self.enabled = False