diff --git a/MANIFEST.in b/MANIFEST.in index 57789a5..928332d 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,5 @@ include requirements.txt +include test-requirements.txt include README.md include senpy/context.jsonld -recursive-include *.senpy +graft senpy/plugins diff --git a/logo.svg b/logo.svg new file mode 100644 index 0000000..1105195 --- /dev/null +++ b/logo.svg @@ -0,0 +1,2728 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + py + + + + + + + + + + py + + + + + + + py + + + + + + + + py + + + + + + + py + + + + + + + py + + + + + + + + + + + + + + py + + + + + + + p + y + + + + + + + py + + + + + + + p + y + + diff --git a/senpy/blueprints.py b/senpy/blueprints.py index a331a09..91bc055 100644 --- a/senpy/blueprints.py +++ b/senpy/blueprints.py @@ -18,7 +18,7 @@ Blueprints for Senpy """ from flask import Blueprint, request, current_app -from .models import Error, Response +from .models import Error, Response, Leaf import json import logging @@ -158,9 +158,9 @@ def plugins(plugin=None, action="list"): method = "{}_plugin".format(action) if(hasattr(sp, method)): getattr(sp, method)(plugin) - return "Ok" + return Leaf(message="Ok").flask() else: - return "action '{}' not allowed".format(action), 400 + return Error("action '{}' not allowed".format(action)).flask() if __name__ == '__main__': diff --git a/senpy/extensions.py b/senpy/extensions.py index 4d903a6..93e14f5 100644 --- a/senpy/extensions.py +++ b/senpy/extensions.py @@ -1,5 +1,9 @@ """ """ +import gevent +from gevent import monkey +monkey.patch_all() + from .plugins import SenpyPlugin, SentimentPlugin, EmotionPlugin from .models import Error from .blueprints import nif_blueprint @@ -23,15 +27,16 @@ class Senpy(object): """ Default Senpy extension for Flask """ - def __init__(self, app=None, plugin_folder="plugins"): + def __init__(self, app=None, plugin_folder="plugins", base_plugins=True): self.app = app - base_folder = os.path.join(os.path.dirname(__file__), "plugins") self._search_folders = set() self._outdated = True - for folder in (base_folder, plugin_folder): - self.add_folder(folder) + self.add_folder(plugin_folder) + if base_plugins: + base_folder = os.path.join(os.path.dirname(__file__), "plugins") + self.add_folder(base_folder) if app is not None: self.init_app(app) @@ -124,7 +129,13 @@ class Senpy(object): def activate_plugin(self, plugin_name, sync=False): plugin = self.plugins[plugin_name] - th = gevent.spawn(plugin.activate) + def act(): + try: + plugin.activate() + except Exception as ex: + logger.error("Error activating plugin {}: {}".format(plugin.name, + ex)) + th = gevent.spawn(act) th.link_value(partial(self._set_active_plugin, plugin_name, True)) if sync: th.join() diff --git a/senpy/models.py b/senpy/models.py index 20517eb..b32c5a8 100644 --- a/senpy/models.py +++ b/senpy/models.py @@ -239,7 +239,7 @@ class Emotion(Leaf): _context = {} -class Error(Response): +class Error(Leaf): # A better pattern would be this: # http://flask.pocoo.org/docs/0.10/patterns/apierrors/ _frame = {} diff --git a/plugins/rand/rand.py b/senpy/plugins/rand/rand.py similarity index 100% rename from plugins/rand/rand.py rename to senpy/plugins/rand/rand.py diff --git a/plugins/rand/rand.senpy b/senpy/plugins/rand/rand.senpy similarity index 100% rename from plugins/rand/rand.senpy rename to senpy/plugins/rand/rand.senpy diff --git a/plugins/sentiment140/sentiment140.py b/senpy/plugins/sentiment140/sentiment140.py similarity index 100% rename from plugins/sentiment140/sentiment140.py rename to senpy/plugins/sentiment140/sentiment140.py diff --git a/plugins/sentiment140/sentiment140.senpy b/senpy/plugins/sentiment140/sentiment140.senpy similarity index 100% rename from plugins/sentiment140/sentiment140.senpy rename to senpy/plugins/sentiment140/sentiment140.senpy diff --git a/setup.py b/setup.py index f3f8fab..1a3bc2b 100644 --- a/setup.py +++ b/setup.py @@ -1,16 +1,21 @@ +import pip from setuptools import setup from pip.req import parse_requirements - # parse_requirements() returns generator of pip.req.InstallRequirement objects -install_reqs = parse_requirements("requirements.txt") + +try: + install_reqs = parse_requirements("requirements.txt", session=pip.download.PipSession()) + test_reqs = parse_requirements("test-requirements.txt", session=pip.download.PipSession()) +except AttributeError: + install_reqs = parse_requirements("requirements.txt") + test_reqs = parse_requirements("test-requirements.txt") # reqs is a list of requirement # e.g. ['django==1.5.1', 'mezzanine==1.4.6'] -reqs = [str(ir.req) for ir in install_reqs] +install_reqs = [str(ir.req) for ir in install_reqs] +test_reqs = [str(ir.req) for ir in test_reqs] -VERSION = "0.4.1" - -print(reqs) +VERSION = "0.4.6" setup( name='senpy', @@ -27,6 +32,7 @@ extendable, so new algorithms and sources can be used. .format(VERSION), keywords=['eurosentiment', 'sentiment', 'emotions', 'nif'], classifiers=[], - install_requires=reqs, + install_requires=install_reqs, + tests_require=test_reqs, include_package_data=True, ) diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 0000000..e69de29 diff --git a/tests/extensions_test/__init__.py b/tests/extensions_test/__init__.py index 0cbbee6..204269d 100644 --- a/tests/extensions_test/__init__.py +++ b/tests/extensions_test/__init__.py @@ -15,7 +15,7 @@ class ExtensionsTest(TestCase): def create_app(self): self.app = Flask("test_extensions") self.dir = os.path.join(os.path.dirname(__file__), "..") - self.senpy = Senpy(plugin_folder=self.dir) + self.senpy = Senpy(plugin_folder=self.dir, base_plugins=False) self.senpy.init_app(self.app) self.senpy.activate_plugin("Dummy", sync=True) return self.app @@ -75,7 +75,7 @@ class ExtensionsTest(TestCase): resp = self.senpy.analyse(input="tupni") logging.debug("Response: {}".format(resp)) assert resp["status"] == 404 - + def test_filtering(self): """ Filtering plugins """