From 7fd69cc690dea0c4943598edd413c98beca50664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20Fernando=20S=C3=A1nchez?= Date: Tue, 10 Jan 2017 10:16:45 +0100 Subject: [PATCH] YAPFed --- Makefile | 6 +- senpy/__init__.py | 1 - senpy/__main__.py | 78 ++++++++------- senpy/api.py | 13 +-- senpy/blueprints.py | 25 +++-- senpy/cli.py | 7 +- senpy/extensions.py | 76 +++++++------- senpy/models.py | 110 ++++++++++++--------- senpy/plugins.py | 15 ++- senpy/plugins/rand/rand.py | 23 ++--- senpy/plugins/sentiment140/sentiment140.py | 27 ++--- tests/dummy_plugin/dummy.py | 1 - tests/sleep_plugin/sleep.py | 1 - tests/test_blueprints.py | 18 ++-- tests/test_cli.py | 1 - tests/test_extensions.py | 8 +- tests/test_models.py | 40 ++++---- tests/test_plugins.py | 45 +++++---- tests/test_schemas.py | 15 ++- 19 files changed, 283 insertions(+), 227 deletions(-) diff --git a/Makefile b/Makefile index cf8c4fb..b3f6a13 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,10 @@ VERSION=$(shell cat $(NAME)/VERSION) all: build run +yapf: + yapf -i -r senpy + yapf -i -r tests + dockerfiles: $(addprefix Dockerfile-,$(PYVERSIONS)) ln -s Dockerfile-$(PYMAIN) Dockerfile @@ -71,4 +75,4 @@ pip_test: $(addprefix pip_test-,$(PYVERSIONS)) run: build docker run --rm -p 5000:5000 -ti '$(REPO)/$(NAME):$(VERSION)-python$(PYMAIN)' -.PHONY: test test-% build-% build test test_pip run +.PHONY: test test-% build-% build test test_pip run yapf diff --git a/senpy/__init__.py b/senpy/__init__.py index b88e398..0947220 100644 --- a/senpy/__init__.py +++ b/senpy/__init__.py @@ -22,5 +22,4 @@ import os from .version import __version__ - __all__ = ['api', 'blueprints', 'cli', 'extensions', 'models', 'plugins'] diff --git a/senpy/__main__.py b/senpy/__main__.py index 6477317..e32e3ea 100644 --- a/senpy/__main__.py +++ b/senpy/__main__.py @@ -34,42 +34,51 @@ patch_all(thread=False) SERVER_PORT = os.environ.get("PORT", 5000) + def main(): parser = argparse.ArgumentParser(description='Run a Senpy server') - parser.add_argument('--level', - '-l', - metavar='logging_level', - type=str, - default="INFO", - help='Logging level') - parser.add_argument('--debug', - '-d', - action='store_true', - default=False, - help='Run the application in debug mode') - parser.add_argument('--default-plugins', - action='store_true', - default=False, - help='Load the default plugins') - parser.add_argument('--host', - type=str, - default="127.0.0.1", - help='Use 0.0.0.0 to accept requests from any host.') - parser.add_argument('--port', - '-p', - type=int, - default=SERVER_PORT, - help='Port to listen on.') - parser.add_argument('--plugins-folder', - '-f', - type=str, - default='plugins', - help='Where to look for plugins.') - parser.add_argument('--only-install', - '-i', - action='store_true', - default=False, - help='Do not run a server, only install the dependencies of the plugins.') + parser.add_argument( + '--level', + '-l', + metavar='logging_level', + type=str, + default="INFO", + help='Logging level') + parser.add_argument( + '--debug', + '-d', + action='store_true', + default=False, + help='Run the application in debug mode') + parser.add_argument( + '--default-plugins', + action='store_true', + default=False, + help='Load the default plugins') + parser.add_argument( + '--host', + type=str, + default="127.0.0.1", + help='Use 0.0.0.0 to accept requests from any host.') + parser.add_argument( + '--port', + '-p', + type=int, + default=SERVER_PORT, + help='Port to listen on.') + parser.add_argument( + '--plugins-folder', + '-f', + type=str, + default='plugins', + help='Where to look for plugins.') + parser.add_argument( + '--only-install', + '-i', + action='store_true', + default=False, + help='Do not run a server, only install the dependencies of the plugins.' + ) args = parser.parse_args() logging.basicConfig() rl = logging.getLogger() @@ -92,5 +101,6 @@ def main(): http_server.stop() sp.deactivate_all() + if __name__ == '__main__': main() diff --git a/senpy/api.py b/senpy/api.py index d15045b..10d30fe 100644 --- a/senpy/api.py +++ b/senpy/api.py @@ -25,7 +25,7 @@ CLI_PARAMS = { "required": True, "default": "." }, - } +} NIF_PARAMS = { "input": { @@ -96,10 +96,11 @@ def parse_params(indict, spec=NIF_PARAMS): outdict[param] not in spec[param]["options"]: wrong_params[param] = spec[param] if wrong_params: - message = Error(status=404, - message="Missing or invalid parameters", - parameters=outdict, - errors={param: error for param, error in - iteritems(wrong_params)}) + message = Error( + status=404, + message="Missing or invalid parameters", + parameters=outdict, + errors={param: error + for param, error in iteritems(wrong_params)}) raise message return outdict diff --git a/senpy/blueprints.py b/senpy/blueprints.py index 6455ae7..d34d566 100644 --- a/senpy/blueprints.py +++ b/senpy/blueprints.py @@ -30,6 +30,7 @@ logger = logging.getLogger(__name__) api_blueprint = Blueprint("api", __name__) demo_blueprint = Blueprint("demo", __name__) + def get_params(req): if req.method == 'POST': indict = req.form.to_dict(flat=True) @@ -44,17 +45,20 @@ def get_params(req): def index(): return render_template("index.html") + @api_blueprint.route('/contexts/.jsonld') def context(entity="context"): return jsonify({"@context": Response.context}) + @api_blueprint.route('/schemas/') def schema(schema="definitions"): try: return jsonify(read_schema(schema)) - except Exception: # Should be FileNotFoundError, but it's missing from py2 + except Exception: # Should be FileNotFoundError, but it's missing from py2 return Error(message="Schema not found", status=404).flask() + def basic_api(f): @wraps(f) def decorated_function(*args, **kwargs): @@ -73,12 +77,15 @@ def basic_api(f): response = ex in_headers = web_params["inHeaders"] != "0" headers = {'X-ORIGINAL-PARAMS': raw_params} - return response.flask(in_headers=in_headers, - headers=headers, - context_uri=url_for('api.context', entity=type(response).__name__, - _external=True)) + return response.flask( + in_headers=in_headers, + headers=headers, + context_uri=url_for( + 'api.context', entity=type(response).__name__, _external=True)) + return decorated_function - + + @api_blueprint.route('/', methods=['POST', 'GET']) @basic_api def api(): @@ -92,7 +99,8 @@ def plugins(): sp = current_app.senpy dic = Plugins(plugins=list(sp.plugins.values())) return dic - + + @api_blueprint.route('/plugins//', methods=['POST', 'GET']) @api_blueprint.route('/plugins//', methods=['POST', 'GET']) @basic_api @@ -110,12 +118,13 @@ def plugin(plugin=None, action="list"): if action == "list": return response method = "{}_plugin".format(action) - if(hasattr(sp, method)): + if (hasattr(sp, method)): getattr(sp, method)(plugin) return Response(message="Ok") else: return Error(message="action '{}' not allowed".format(action)) + if __name__ == '__main__': import config diff --git a/senpy/cli.py b/senpy/cli.py index 2297217..69dc93e 100644 --- a/senpy/cli.py +++ b/senpy/cli.py @@ -3,6 +3,7 @@ from .models import Error from .api import parse_params, CLI_PARAMS from .extensions import Senpy + def argv_to_dict(argv): '''Turns parameters in the form of '--key value' into a dict {'key': 'value'} ''' @@ -11,13 +12,14 @@ def argv_to_dict(argv): for i in range(len(argv)): if argv[i][0] == '-': key = argv[i].strip('-') - value = argv[i+1] if len(argv)>i+1 else None + value = argv[i + 1] if len(argv) > i + 1 else None if value and value[0] == '-': cli_dict[key] = "" else: cli_dict[key] = value return cli_dict + def parse_cli(argv): cli_dict = argv_to_dict(argv) cli_params = parse_params(cli_dict, spec=CLI_PARAMS) @@ -34,6 +36,7 @@ def main_function(argv): res = sp.analyse(**cli_dict) return res + def main(): '''This method is the entrypoint for the CLI (as configured un setup.py) ''' @@ -43,7 +46,7 @@ def main(): except Error as err: print(err.to_JSON()) sys.exit(2) - + if __name__ == '__main__': main() diff --git a/senpy/extensions.py b/senpy/extensions.py index a9228e5..ba30d1e 100644 --- a/senpy/extensions.py +++ b/senpy/extensions.py @@ -29,10 +29,12 @@ logger = logging.getLogger(__name__) class Senpy(object): - """ Default Senpy extension for Flask """ - def __init__(self, app=None, plugin_folder="plugins", default_plugins=False): + def __init__(self, + app=None, + plugin_folder="plugins", + default_plugins=False): self.app = app self._search_folders = set() @@ -80,22 +82,24 @@ class Senpy(object): elif self.plugins: algo = self.default_plugin and self.default_plugin.name if not algo: - raise Error(status=404, - message=("No plugins found." - " Please install one.").format(algo)) + raise Error( + status=404, + message=("No plugins found." + " Please install one.").format(algo)) if algo not in self.plugins: logger.debug(("The algorithm '{}' is not valid\n" "Valid algorithms: {}").format(algo, self.plugins.keys())) - raise Error(status=404, - message="The algorithm '{}' is not valid" - .format(algo)) + raise Error( + status=404, + message="The algorithm '{}' is not valid".format(algo)) if not self.plugins[algo].is_activated: logger.debug("Plugin not activated: {}".format(algo)) - raise Error(status=400, - message=("The algorithm '{}'" - " is not activated yet").format(algo)) + raise Error( + status=400, + message=("The algorithm '{}'" + " is not activated yet").format(algo)) plug = self.plugins[algo] nif_params = parse_params(params, spec=NIF_PARAMS) extra_params = plug.get('extra_params', {}) @@ -120,9 +124,8 @@ class Senpy(object): return None def parameters(self, algo): - return getattr(self.plugins.get(algo) or self.default_plugin, - "extra_params", - {}) + return getattr( + self.plugins.get(algo) or self.default_plugin, "extra_params", {}) def activate_all(self, sync=False): ps = [] @@ -146,18 +149,20 @@ class Senpy(object): try: plugin = self.plugins[plugin_name] except KeyError: - raise Error(message="Plugin not found: {}".format(plugin_name), - status=404) - + raise Error( + message="Plugin not found: {}".format(plugin_name), status=404) + logger.info("Activating plugin: {}".format(plugin.name)) + def act(): try: plugin.activate() logger.info("Plugin activated: {}".format(plugin.name)) except Exception as ex: - logger.error("Error activating plugin {}: {}".format(plugin.name, - ex)) + logger.error("Error activating plugin {}: {}".format( + plugin.name, ex)) logger.error("Trace: {}".format(traceback.format_exc())) + th = gevent.spawn(act) th.link_value(partial(self._set_active_plugin, plugin_name, True)) if sync: @@ -169,16 +174,16 @@ class Senpy(object): try: plugin = self.plugins[plugin_name] except KeyError: - raise Error(message="Plugin not found: {}".format(plugin_name), - status=404) + raise Error( + message="Plugin not found: {}".format(plugin_name), status=404) def deact(): try: plugin.deactivate() logger.info("Plugin deactivated: {}".format(plugin.name)) except Exception as ex: - logger.error("Error deactivating plugin {}: {}".format(plugin.name, - ex)) + logger.error("Error deactivating plugin {}: {}".format( + plugin.name, ex)) logger.error("Trace: {}".format(traceback.format_exc())) th = gevent.spawn(deact) @@ -199,7 +204,6 @@ class Senpy(object): logger.error('Error reloading {}: {}'.format(name, ex)) self.plugins[name] = plugin - @classmethod def validate_info(cls, info): return all(x in info for x in ('name', 'module', 'version')) @@ -215,15 +219,15 @@ class Senpy(object): pip_args = [] pip_args.append('install') for req in requirements: - pip_args.append( req ) + pip_args.append(req) logger.info('Installing requirements: ' + str(requirements)) - pip.main(pip_args) + pip.main(pip_args) @classmethod def _load_plugin_from_info(cls, info, root): if not cls.validate_info(info): logger.warn('The module info is not valid.\n\t{}'.format(info)) - return None, None + return None, None module = info["module"] name = info["name"] requirements = info.get("requirements", []) @@ -237,8 +241,8 @@ class Senpy(object): for _, obj in inspect.getmembers(tmp): if inspect.isclass(obj) and inspect.getmodule(obj) == tmp: logger.debug(("Found plugin class:" - " {}@{}").format(obj, inspect.getmodule(obj)) - ) + " {}@{}").format(obj, inspect.getmodule( + obj))) candidate = obj break if not candidate: @@ -248,7 +252,8 @@ class Senpy(object): repo_path = root module._repo = Repo(repo_path) except InvalidGitRepositoryError: - logger.debug("The plugin {} is not in a Git repository".format(module)) + logger.debug("The plugin {} is not in a Git repository".format( + module)) module._repo = None except Exception as ex: logger.error("Exception importing {}: {}".format(module, ex)) @@ -265,7 +270,6 @@ class Senpy(object): logger.debug("Info: {}".format(info)) return cls._load_plugin_from_info(info, root) - def _load_plugins(self): plugins = {} for search_folder in self._search_folders: @@ -293,8 +297,7 @@ class Senpy(object): def matches(plug): res = all(getattr(plug, k, None) == v for (k, v) in kwargs.items()) - logger.debug("matching {} with {}: {}".format(plug.name, - kwargs, + logger.debug("matching {} with {}: {}".format(plug.name, kwargs, res)) return res @@ -305,5 +308,8 @@ class Senpy(object): def sentiment_plugins(self): """ Return only the sentiment plugins """ - return {p: plugin for p, plugin in self.plugins.items() if - isinstance(plugin, SentimentPlugin)} + return { + p: plugin + for p, plugin in self.plugins.items() + if isinstance(plugin, SentimentPlugin) + } diff --git a/senpy/models.py b/senpy/models.py index 26e1f10..3de3c74 100644 --- a/senpy/models.py +++ b/senpy/models.py @@ -18,15 +18,18 @@ import jsonschema from flask import Response as FlaskResponse - DEFINITIONS_FILE = 'definitions.json' -CONTEXT_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'schemas', 'context.jsonld') +CONTEXT_PATH = os.path.join( + os.path.dirname(os.path.realpath(__file__)), 'schemas', 'context.jsonld') + def get_schema_path(schema_file, absolute=False): if absolute: return os.path.realpath(schema_file) else: - return os.path.join(os.path.dirname(os.path.realpath(__file__)), 'schemas', schema_file) + return os.path.join( + os.path.dirname(os.path.realpath(__file__)), 'schemas', + schema_file) def read_schema(schema_file, absolute=False): @@ -34,13 +37,13 @@ def read_schema(schema_file, absolute=False): schema_uri = 'file://{}'.format(schema_path) with open(schema_path) as f: return jsonref.load(f, base_uri=schema_uri) - - + + base_schema = read_schema(DEFINITIONS_FILE) logging.debug(base_schema) -class Context(dict): +class Context(dict): @staticmethod def load(context): logging.debug('Loading context: {}'.format(context)) @@ -60,17 +63,16 @@ class Context(dict): except IOError: return context else: - raise AttributeError('Please, provide a valid context') + raise AttributeError('Please, provide a valid context') + base_context = Context.load(CONTEXT_PATH) + class SenpyMixin(object): context = base_context["@context"] - def flask(self, - in_headers=False, - headers=None, - **kwargs): + def flask(self, in_headers=False, headers=None, **kwargs): """ Return the values and error to be used in flask. So far, it returns a fixed context. We should store/generate different @@ -87,33 +89,34 @@ class SenpyMixin(object): 'rel="http://www.w3.org/ns/json-ld#context";' ' type="application/ld+json"' % url) }) - return FlaskResponse(json.dumps(js, indent=2, sort_keys=True), - status=getattr(self, "status", 200), - headers=headers, - mimetype="application/json") - + return FlaskResponse( + json.dumps( + js, indent=2, sort_keys=True), + status=getattr(self, "status", 200), + headers=headers, + mimetype="application/json") def serializable(self): def ser_or_down(item): - if hasattr(item, 'serializable'): - return item.serializable() - elif isinstance(item, dict): - temp = dict() - for kp in item: - vp = item[kp] - temp[kp] = ser_or_down(vp) - return temp - elif isinstance(item, list): - return list(ser_or_down(i) for i in item) - else: - return item - return ser_or_down(self._plain_dict()) + if hasattr(item, 'serializable'): + return item.serializable() + elif isinstance(item, dict): + temp = dict() + for kp in item: + vp = item[kp] + temp[kp] = ser_or_down(vp) + return temp + elif isinstance(item, list): + return list(ser_or_down(i) for i in item) + else: + return item + return ser_or_down(self._plain_dict()) def jsonld(self, with_context=True, context_uri=None): ser = self.serializable() - if with_context: + if with_context: context = [] if context_uri: context = context_uri @@ -133,10 +136,8 @@ class SenpyMixin(object): ser["@context"] = context return ser - def to_JSON(self, *args, **kwargs): - js = json.dumps(self.jsonld(*args, **kwargs), indent=4, - sort_keys=True) + js = json.dumps(self.jsonld(*args, **kwargs), indent=4, sort_keys=True) return js def validate(self, obj=None): @@ -145,18 +146,19 @@ class SenpyMixin(object): if hasattr(obj, "jsonld"): obj = obj.jsonld() jsonschema.validate(obj, self.schema) - + + class SenpyModel(SenpyMixin, dict): schema = base_schema def __init__(self, *args, **kwargs): - self.id = kwargs.pop('id', '{}_{}'.format(type(self).__name__, - time.time())) + self.id = kwargs.pop('id', '{}_{}'.format( + type(self).__name__, time.time())) temp = dict(*args, **kwargs) - for obj in [self.schema,]+self.schema.get('allOf', []): + for obj in [self.schema, ] + self.schema.get('allOf', []): for k, v in obj.get('properties', {}).items(): if 'default' in v: temp[k] = copy.deepcopy(v['default']) @@ -172,7 +174,6 @@ class SenpyModel(SenpyMixin, dict): self.__dict__['context'] = Context.load(context) super(SenpyModel, self).__init__(temp) - def _get_key(self, key): key = key.replace("__", ":", 1) return key @@ -180,7 +181,6 @@ class SenpyModel(SenpyMixin, dict): def __setitem__(self, key, value): dict.__setitem__(self, key, value) - def __delitem__(self, key): dict.__delitem__(self, key) @@ -195,62 +195,80 @@ class SenpyModel(SenpyMixin, dict): def __delattr__(self, key): self.__delitem__(self._get_key(key)) - - + def _plain_dict(self): - d = { k: v for (k,v) in self.items() if k[0] != "_"} + d = {k: v for (k, v) in self.items() if k[0] != "_"} d["@id"] = d.pop('id') return d + class Response(SenpyModel): schema = read_schema('response.json') + class Results(SenpyModel): schema = read_schema('results.json') + class Entry(SenpyModel): schema = read_schema('entry.json') + class Sentiment(SenpyModel): schema = read_schema('sentiment.json') + class Analysis(SenpyModel): schema = read_schema('analysis.json') + class EmotionSet(SenpyModel): schema = read_schema('emotionSet.json') + class Emotion(SenpyModel): schema = read_schema('emotion.json') + class EmotionModel(SenpyModel): schema = read_schema('emotionModel.json') + class Suggestion(SenpyModel): schema = read_schema('suggestion.json') + class PluginModel(SenpyModel): schema = read_schema('plugin.json') + class EmotionPluginModel(SenpyModel): schema = read_schema('plugin.json') + class SentimentPluginModel(SenpyModel): schema = read_schema('plugin.json') + class Plugins(SenpyModel): schema = read_schema('plugins.json') -class Error(SenpyMixin, BaseException ): - def __init__(self, message, status=500, params=None, errors=None, *args, **kwargs): +class Error(SenpyMixin, BaseException): + def __init__(self, + message, + status=500, + params=None, + errors=None, + *args, + **kwargs): self.message = message self.status = status self.params = params or {} self.errors = errors or "" def _plain_dict(self): - return self.__dict__ + return self.__dict__ def __str__(self): - return str(self.jsonld()) + return str(self.jsonld()) diff --git a/senpy/plugins.py b/senpy/plugins.py index ff496d5..d18e923 100644 --- a/senpy/plugins.py +++ b/senpy/plugins.py @@ -10,8 +10,8 @@ from .models import Response, PluginModel, Error logger = logging.getLogger(__name__) -class SenpyPlugin(PluginModel): +class SenpyPlugin(PluginModel): def __init__(self, info=None): if not info: raise Error(message=("You need to provide configuration" @@ -39,8 +39,8 @@ class SenpyPlugin(PluginModel): ''' Destructor, to make sure all the resources are freed ''' self.deactivate() -class SentimentPlugin(SenpyPlugin): +class SentimentPlugin(SenpyPlugin): def __init__(self, info, *args, **kwargs): super(SentimentPlugin, self).__init__(info, *args, **kwargs) self.minPolarityValue = float(info.get("minPolarityValue", 0)) @@ -49,7 +49,6 @@ class SentimentPlugin(SenpyPlugin): class EmotionPlugin(SenpyPlugin): - def __init__(self, info, *args, **kwargs): resp = super(EmotionPlugin, self).__init__(info, *args, **kwargs) self.minEmotionValue = float(info.get("minEmotionValue", 0)) @@ -58,7 +57,6 @@ class EmotionPlugin(SenpyPlugin): class ShelfMixin(object): - @property def sh(self): if not hasattr(self, '_sh') or self._sh is None: @@ -75,7 +73,7 @@ class ShelfMixin(object): self.save() def __del__(self): - self.save() + self.save() super(ShelfMixin, self).__del__() @property @@ -84,12 +82,13 @@ class ShelfMixin(object): if hasattr(self, '_info') and 'shelf_file' in self._info: self.__dict__['_shelf_file'] = self._info['shelf_file'] else: - self._shelf_file = os.path.join(tempfile.gettempdir(), self.name + '.p') - return self._shelf_file + self._shelf_file = os.path.join(tempfile.gettempdir(), + self.name + '.p') + return self._shelf_file def save(self): logger.debug('closing pickle') if hasattr(self, '_sh') and self._sh is not None: with open(self.shelf_file, 'wb') as f: pickle.dump(self._sh, f) - del(self.__dict__['_sh']) + del (self.__dict__['_sh']) diff --git a/senpy/plugins/rand/rand.py b/senpy/plugins/rand/rand.py index 3c345e4..dff55a6 100644 --- a/senpy/plugins/rand/rand.py +++ b/senpy/plugins/rand/rand.py @@ -16,26 +16,15 @@ class Sentiment140Plugin(SentimentPlugin): polarity = "marl:Positive" elif polarity_value < 0: polarity = "marl:Negative" - entry = Entry({"id":":Entry0", - "nif:isString": params["input"]}) - sentiment = Sentiment({"id": ":Sentiment0", - "marl:hasPolarity": polarity, - "marl:polarityValue": polarity_value}) + entry = Entry({"id": ":Entry0", "nif:isString": params["input"]}) + sentiment = Sentiment({ + "id": ":Sentiment0", + "marl:hasPolarity": polarity, + "marl:polarityValue": polarity_value + }) sentiment["prov:wasGeneratedBy"] = self.id entry.sentiments = [] entry.sentiments.append(sentiment) entry.language = lang response.entries.append(entry) return response - - - - - - - - - - - - diff --git a/senpy/plugins/sentiment140/sentiment140.py b/senpy/plugins/sentiment140/sentiment140.py index ad9704a..3090c02 100644 --- a/senpy/plugins/sentiment140/sentiment140.py +++ b/senpy/plugins/sentiment140/sentiment140.py @@ -9,16 +9,17 @@ class Sentiment140Plugin(SentimentPlugin): def analyse(self, **params): lang = params.get("language", "auto") res = requests.post("http://www.sentiment140.com/api/bulkClassifyJson", - json.dumps({"language": lang, - "data": [{"text": params["input"]}] - } - ) - ) + json.dumps({ + "language": lang, + "data": [{ + "text": params["input"] + }] + })) p = params.get("prefix", None) response = Results(prefix=p) - polarity_value = self.maxPolarityValue*int(res.json()["data"][0] - ["polarity"]) * 0.25 + polarity_value = self.maxPolarityValue * int(res.json()["data"][0][ + "polarity"]) * 0.25 polarity = "marl:Neutral" neutral_value = self.maxPolarityValue / 2.0 if polarity_value > neutral_value: @@ -26,12 +27,12 @@ class Sentiment140Plugin(SentimentPlugin): elif polarity_value < neutral_value: polarity = "marl:Negative" - entry = Entry(id="Entry0", - nif__isString=params["input"]) - sentiment = Sentiment(id="Sentiment0", - prefix=p, - marl__hasPolarity=polarity, - marl__polarityValue=polarity_value) + entry = Entry(id="Entry0", nif__isString=params["input"]) + sentiment = Sentiment( + id="Sentiment0", + prefix=p, + marl__hasPolarity=polarity, + marl__polarityValue=polarity_value) sentiment.prov__wasGeneratedBy = self.id entry.sentiments = [] entry.sentiments.append(sentiment) diff --git a/tests/dummy_plugin/dummy.py b/tests/dummy_plugin/dummy.py index bb39102..7ab4a2d 100644 --- a/tests/dummy_plugin/dummy.py +++ b/tests/dummy_plugin/dummy.py @@ -3,6 +3,5 @@ from senpy.models import Results class DummyPlugin(SentimentPlugin): - def analyse(self, *args, **kwargs): return Results() diff --git a/tests/sleep_plugin/sleep.py b/tests/sleep_plugin/sleep.py index 29d514d..bcc1cbe 100644 --- a/tests/sleep_plugin/sleep.py +++ b/tests/sleep_plugin/sleep.py @@ -4,7 +4,6 @@ from time import sleep class SleepPlugin(SenpyPlugin): - def activate(self, *args, **kwargs): sleep(self.timeout) diff --git a/tests/test_blueprints.py b/tests/test_blueprints.py index 454324d..71a4c7d 100644 --- a/tests/test_blueprints.py +++ b/tests/test_blueprints.py @@ -12,12 +12,12 @@ from itertools import product def check_dict(indic, template): return all(item in indic.items() for item in template.items()) + def parse_resp(resp): return json.loads(resp.data.decode('utf-8')) class BlueprintsTest(TestCase): - def setUp(self): self.app = Flask("test_extensions") self.client = self.app.test_client() @@ -29,7 +29,7 @@ class BlueprintsTest(TestCase): def assertCode(self, resp, code): self.assertEqual(resp.status_code, code) - + def test_home(self): """ Calling with no arguments should ask the user for more arguments @@ -55,7 +55,7 @@ class BlueprintsTest(TestCase): js = parse_resp(resp) logging.debug("Got response: %s", js) assert "@context" in js - assert "entries" in js + assert "entries" in js def test_list(self): """ List the plugins """ @@ -77,13 +77,13 @@ class BlueprintsTest(TestCase): assert "@context" in js resp = self.client.get("%s&%s=0" % (i, j)) js = parse_resp(resp) - assert "@context" in js + assert "@context" in js resp = self.client.get("%s&%s=1" % (i, j)) js = parse_resp(resp) - assert "@context" not in js + assert "@context" not in js resp = self.client.get("%s&%s=true" % (i, j)) js = parse_resp(resp) - assert "@context" not in js + assert "@context" not in js def test_detail(self): """ Show only one plugin""" @@ -110,7 +110,7 @@ class BlueprintsTest(TestCase): resp = self.client.get("/api/plugins/Dummy/") self.assertCode(resp, 200) js = parse_resp(resp) - assert "is_activated" in js + assert "is_activated" in js assert js["is_activated"] == True def test_default(self): @@ -119,7 +119,7 @@ class BlueprintsTest(TestCase): self.assertCode(resp, 200) js = parse_resp(resp) logging.debug(js) - assert "@id" in js + assert "@id" in js assert js["@id"] == "Dummy_0.1" resp = self.client.get("/api/plugins/Dummy/deactivate") self.assertCode(resp, 200) @@ -140,4 +140,4 @@ class BlueprintsTest(TestCase): resp = self.client.get("/api/schemas/definitions.json") self.assertCode(resp, 200) js = parse_resp(resp) - assert "$schema" in js + assert "$schema" in js diff --git a/tests/test_cli.py b/tests/test_cli.py index 28d9a08..067fb3c 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -10,7 +10,6 @@ from senpy.models import Error class CLITest(TestCase): - def test_basic(self): self.assertRaises(Error, partial(main_function, [])) res = main_function(['--input', 'test']) diff --git a/tests/test_extensions.py b/tests/test_extensions.py index 9198b65..0263a9f 100644 --- a/tests/test_extensions.py +++ b/tests/test_extensions.py @@ -2,7 +2,7 @@ from __future__ import print_function import os import logging -from functools import partial +from functools import partial from senpy.extensions import Senpy from senpy.models import Error from flask import Flask @@ -10,7 +10,6 @@ from unittest import TestCase class ExtensionsTest(TestCase): - def setUp(self): self.app = Flask("test_extensions") self.dir = os.path.join(os.path.dirname(__file__)) @@ -39,7 +38,7 @@ class ExtensionsTest(TestCase): 'module': 'dummy', 'requirements': ['noop'], 'version': 0 - } + } root = os.path.join(self.dir, 'dummy_plugin') name, module = self.senpy._load_plugin_from_info(info, root=root) assert name == 'TestPip' @@ -88,4 +87,5 @@ class ExtensionsTest(TestCase): assert self.senpy.filter_plugins(name="Dummy", is_activated=True) self.senpy.deactivate_plugin("Dummy", sync=True) assert not len( - self.senpy.filter_plugins(name="Dummy", is_activated=True)) + self.senpy.filter_plugins( + name="Dummy", is_activated=True)) diff --git a/tests/test_models.py b/tests/test_models.py index f2408eb..6ec8021 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -12,12 +12,11 @@ from pprint import pprint class ModelsTest(TestCase): - def test_jsonld(self): - ctx = os.path.normpath(os.path.join(__file__, "..", "..", "..", "senpy", "schemas", "context.jsonld")) - prueba = {"id": "test", - "analysis": [], - "entries": []} + ctx = os.path.normpath( + os.path.join(__file__, "..", "..", "..", "senpy", "schemas", + "context.jsonld")) + prueba = {"id": "test", "analysis": [], "entries": []} r = Results(**prueba) print("Response's context: ") pprint(r.context) @@ -27,28 +26,32 @@ class ModelsTest(TestCase): j = r.jsonld(with_context=True) print("As JSON:") pprint(j) - assert("@context" in j) - assert("marl" in j["@context"]) - assert("entries" in j["@context"]) - assert(j["@id"] == "test") + assert ("@context" in j) + assert ("marl" in j["@context"]) + assert ("entries" in j["@context"]) + assert (j["@id"] == "test") assert "id" not in j r6 = Results(**prueba) - r6.entries.append(Entry({"@id":"ohno", "nif:isString":"Just testing"})) + r6.entries.append( + Entry({ + "@id": "ohno", + "nif:isString": "Just testing" + })) logging.debug("Reponse 6: %s", r6) - assert("marl" in r6.context) - assert("entries" in r6.context) + assert ("marl" in r6.context) + assert ("entries" in r6.context) j6 = r6.jsonld(with_context=True) logging.debug("jsonld: %s", j6) - assert("@context" in j6) - assert("entries" in j6) - assert("analysis" in j6) + assert ("@context" in j6) + assert ("entries" in j6) + assert ("analysis" in j6) resp = r6.flask() received = json.loads(resp.data.decode()) logging.debug("Response: %s", j6) - assert(received["entries"]) - assert(received["entries"][0]["nif:isString"] == "Just testing") - assert(received["entries"][0]["nif:isString"] != "Not testing") + assert (received["entries"]) + assert (received["entries"][0]["nif:isString"] == "Just testing") + assert (received["entries"][0]["nif:isString"] != "Not testing") def test_id(self): ''' Adding the id after creation should overwrite the automatic ID @@ -61,7 +64,6 @@ class ModelsTest(TestCase): assert j2['@id'] == 'test' assert 'id' not in j2 - def test_entries(self): e = Entry() self.assertRaises(jsonschema.ValidationError, e.validate) diff --git a/tests/test_plugins.py b/tests/test_plugins.py index b4cd728..c56d7ff 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -13,8 +13,8 @@ from flask import Flask from senpy.models import Results, Entry from senpy.plugins import SentimentPlugin, ShelfMixin -class ShelfDummyPlugin(SentimentPlugin, ShelfMixin): +class ShelfDummyPlugin(SentimentPlugin, ShelfMixin): def activate(self, *args, **kwargs): if 'counter' not in self.sh: self.sh['counter'] = 0 @@ -24,15 +24,15 @@ class ShelfDummyPlugin(SentimentPlugin, ShelfMixin): self.save() def analyse(self, *args, **kwargs): - self.sh['counter'] = self.sh['counter']+1 + self.sh['counter'] = self.sh['counter'] + 1 e = Entry() e.nif__isString = self.sh['counter'] r = Results() r.entries.append(e) return r -class PluginsTest(TestCase): +class PluginsTest(TestCase): def tearDown(self): if os.path.exists(self.shelf_dir): shutil.rmtree(self.shelf_dir) @@ -43,10 +43,11 @@ class PluginsTest(TestCase): def setUp(self): self.shelf_dir = tempfile.mkdtemp() self.shelf_file = os.path.join(self.shelf_dir, "shelf") - + def test_shelf_file(self): - a = ShelfDummyPlugin(info={'name': 'default_shelve_file', - 'version': 'test'}) + a = ShelfDummyPlugin( + info={'name': 'default_shelve_file', + 'version': 'test'}) assert os.path.dirname(a.shelf_file) == tempfile.gettempdir() a.activate() assert os.path.isfile(a.shelf_file) @@ -54,9 +55,11 @@ class PluginsTest(TestCase): def test_shelf(self): ''' A shelf is created and the value is stored ''' - a = ShelfDummyPlugin(info={'name': 'shelve', - 'version': 'test', - 'shelf_file': self.shelf_file}) + a = ShelfDummyPlugin(info={ + 'name': 'shelve', + 'version': 'test', + 'shelf_file': self.shelf_file + }) assert a.sh == {} a.activate() assert a.sh == {'counter': 0} @@ -72,9 +75,11 @@ class PluginsTest(TestCase): assert sh['a'] == 'fromA' def test_dummy_shelf(self): - a = ShelfDummyPlugin(info={'name': 'DummyShelf', - 'shelf_file': self.shelf_file, - 'version': 'test'}) + a = ShelfDummyPlugin(info={ + 'name': 'DummyShelf', + 'shelf_file': self.shelf_file, + 'version': 'test' + }) a.activate() res1 = a.analyse(input=1) @@ -84,17 +89,21 @@ class PluginsTest(TestCase): def test_two(self): ''' Reusing the values of a previous shelf ''' - a = ShelfDummyPlugin(info={'name': 'shelve', - 'version': 'test', - 'shelf_file': self.shelf_file}) + a = ShelfDummyPlugin(info={ + 'name': 'shelve', + 'version': 'test', + 'shelf_file': self.shelf_file + }) a.activate() print('Shelf file: %s' % a.shelf_file) a.sh['a'] = 'fromA' a.save() - b = ShelfDummyPlugin(info={'name': 'shelve', - 'version': 'test', - 'shelf_file': self.shelf_file}) + b = ShelfDummyPlugin(info={ + 'name': 'shelve', + 'version': 'test', + 'shelf_file': self.shelf_file + }) b.activate() assert b.sh['a'] == 'fromA' b.sh['a'] = 'fromB' diff --git a/tests/test_schemas.py b/tests/test_schemas.py index b448d27..759bd7b 100644 --- a/tests/test_schemas.py +++ b/tests/test_schemas.py @@ -14,9 +14,11 @@ schema_folder = path.join(root_path, 'senpy', 'schemas') examples_path = path.join(root_path, 'docs', 'examples') bad_examples_path = path.join(root_path, 'docs', 'bad-examples') + class JSONSchemaTests(unittest.TestCase): pass + def do_create_(jsfile, success): def do_expected(self): with open(jsfile) as f: @@ -24,7 +26,8 @@ def do_create_(jsfile, success): try: assert '@type' in js schema_name = js['@type'] - with open(os.path.join(schema_folder, schema_name+".json")) as file_object: + with open(os.path.join(schema_folder, schema_name + + ".json")) as file_object: schema = json.load(file_object) resolver = RefResolver('file://' + schema_folder + '/', schema) validator = Draft4Validator(schema, resolver=resolver) @@ -32,19 +35,25 @@ def do_create_(jsfile, success): except (AssertionError, ValidationError, KeyError) as ex: if success: raise + return do_expected + def add_examples(dirname, success): for dirpath, dirnames, filenames in os.walk(dirname): for i in filenames: if fnmatch(i, '*.json'): filename = path.join(dirpath, i) test_method = do_create_(filename, success) - test_method.__name__ = 'test_file_%s_success_%s' % (filename, success) - test_method.__doc__ = '%s should %svalidate' % (filename, '' if success else 'not' ) + test_method.__name__ = 'test_file_%s_success_%s' % (filename, + success) + test_method.__doc__ = '%s should %svalidate' % (filename, '' + if success else + 'not') setattr(JSONSchemaTests, test_method.__name__, test_method) del test_method + add_examples(examples_path, True) add_examples(bad_examples_path, False)