Exemplo n.º 1
0
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="0.0.0.0",
                        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 plugin dependencies')
    args = parser.parse_args()
    logging.basicConfig()
    rl = logging.getLogger()
    rl.setLevel(getattr(logging, args.level))
    app = Flask(__name__)
    app.debug = args.debug
    if args.debug:
        sys.excepthook = info
    sp = Senpy(app, args.plugins_folder, default_plugins=args.default_plugins)
    if args.only_install:
        sp.install_deps()
        return
    sp.activate_all()
    http_server = WSGIServer((args.host, args.port), app)
    try:
        print('Senpy version {}'.format(senpy.__version__))
        print('Server running on port %s:%d. Ctrl+C to quit' %
              (args.host, args.port))
        http_server.serve_forever()
    except KeyboardInterrupt:
        print('Bye!')
    http_server.stop()
    sp.deactivate_all()
Exemplo n.º 2
0
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.')
    args = parser.parse_args()
    logging.basicConfig()
    rl = logging.getLogger()
    rl.setLevel(getattr(logging, args.level))
    app = Flask(__name__)
    app.debug = args.debug
    sp = Senpy(app, args.plugins_folder, default_plugins=args.default_plugins)
    if args.only_install:
        sp.install_deps()
        return
    sp.activate_all()
    http_server = WSGIServer((args.host, args.port), app)
    try:
        print('Senpy version {}'.format(senpy.__version__))
        print('Server running on port %s:%d. Ctrl+C to quit' % (args.host,
                                                                args.port))
        http_server.serve_forever()
    except KeyboardInterrupt:
        http_server.stop()
        print('Bye!')
Exemplo n.º 3
0
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=5000,
                        help='Port to listen on.')
    parser.add_argument('--plugins-folder',
                        '-f',
                        type=str,
                        default="plugins",
                        help='Where to look for plugins.')
    args = parser.parse_args()
    logging.basicConfig(level=getattr(logging, args.level))
    app = Flask(__name__)
    app.debug = args.debug
    sp = Senpy(app, args.plugins_folder, default_plugins=args.default_plugins)
    sp.activate_all()
    http_server = WSGIServer((args.host, args.port), app)
    try:
        print("Server running on port %s:%d. Ctrl+C to quit" % (args.host,
                                                                args.port))
        http_server.serve_forever()
    except KeyboardInterrupt:
        http_server.stop()
        print("Bye!")
Exemplo n.º 4
0
class ExtensionsTest(TestCase):
    def setUp(self):
        self.app = Flask("test_extensions")
        self.dir = os.path.join(os.path.dirname(__file__))
        self.senpy = Senpy(plugin_folder=self.dir, default_plugins=False)
        self.senpy.init_app(self.app)
        self.senpy.activate_plugin("Dummy", sync=True)

    def test_init(self):
        """ Initialising the app with the extension.  """
        assert hasattr(self.app, "senpy")
        tapp = Flask("temp app")
        self.senpy.init_app(tapp)
        assert hasattr(tapp, "senpy")

    def test_discovery(self):
        """ Discovery of plugins in given folders.  """
        # noinspection PyProtectedMember
        assert self.dir in self.senpy._search_folders
        print(self.senpy.plugins)
        assert "Dummy" in self.senpy.plugins

    def test_enabling(self):
        """ Enabling a plugin """
        info = {
            'name': 'TestPip',
            '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'
        assert module
        import noop

    def test_installing(self):
        """ Enabling a plugin """
        self.senpy.activate_all(sync=True)
        assert len(self.senpy.plugins) == 2
        assert self.senpy.plugins["Sleep"].is_activated

    def test_disabling(self):
        """ Disabling a plugin """
        self.senpy.deactivate_all(sync=True)
        assert not self.senpy.plugins["Dummy"].is_activated
        assert not self.senpy.plugins["Sleep"].is_activated

    def test_default(self):
        """ Default plugin should be set """
        assert self.senpy.default_plugin
        assert self.senpy.default_plugin.name == "Dummy"
        self.senpy.deactivate_all(sync=True)
        logging.debug("Default: {}".format(self.senpy.default_plugin))
        assert self.senpy.default_plugin is None

    def test_noplugin(self):
        """ Don't analyse if there isn't any plugin installed """
        self.senpy.deactivate_all(sync=True)
        self.assertRaises(Error, partial(self.senpy.analyse, input="tupni"))

    def test_analyse(self):
        """ Using a plugin """
        # I was using mock until plugin started inheriting
        # Leaf (defaultdict with  __setattr__ and __getattr__.
        r1 = self.senpy.analyse(algorithm="Dummy",
                                input="tupni",
                                output="tuptuo")
        r2 = self.senpy.analyse(input="tupni", output="tuptuo")
        assert r1.analysis[0].id[:5] == "Dummy"
        assert r2.analysis[0].id[:5] == "Dummy"

    def test_filtering(self):
        """ Filtering plugins """
        assert len(self.senpy.filter_plugins(name="Dummy")) > 0
        assert not len(self.senpy.filter_plugins(name="notdummy"))
        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))
Exemplo n.º 5
0
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(
        '--log-format',
        metavar='log_format',
        type=str,
        default='%(asctime)s %(levelname)-10s %(name)-30s \t %(message)s',
        help='Logging format')
    parser.add_argument(
        '--debug',
        '-d',
        action='store_true',
        default=False,
        help='Run the application in debug mode')
    parser.add_argument(
        '--no-default-plugins',
        action='store_true',
        default=False,
        help='Do not load the default plugins')
    parser.add_argument(
        '--host',
        type=str,
        default="0.0.0.0",
        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,
        action='append',
        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 plugin dependencies')
    parser.add_argument(
        '--only-test',
        action='store_true',
        default=False,
        help='Do not run a server, just test all plugins')
    parser.add_argument(
        '--test',
        '-t',
        action='store_true',
        default=False,
        help='Test all plugins before launching the server')
    parser.add_argument(
        '--only-list',
        '--list',
        action='store_true',
        default=False,
        help='Do not run a server, only list plugins found')
    parser.add_argument(
        '--data-folder',
        '--data',
        type=str,
        default=None,
        help='Where to look for data. It be set with the SENPY_DATA environment variable as well.')
    parser.add_argument(
        '--no-threaded',
        action='store_true',
        default=False,
        help='Run a single-threaded server')
    parser.add_argument(
        '--no-deps',
        '-n',
        action='store_true',
        default=False,
        help='Skip installing dependencies')
    parser.add_argument(
        '--version',
        '-v',
        action='store_true',
        default=False,
        help='Output the senpy version and exit')
    parser.add_argument(
        '--allow-fail',
        '--fail',
        action='store_true',
        default=False,
        help='Do not exit if some plugins fail to activate')
    args = parser.parse_args()
    print('Senpy version {}'.format(senpy.__version__))
    print(sys.version)
    if args.version:
        exit(1)
    rl = logging.getLogger()
    rl.setLevel(getattr(logging, args.level))
    logger_handler = rl.handlers[0]

    # First, generic formatter:
    logger_handler.setFormatter(logging.Formatter(args.log_format))

    app = Flask(__name__)
    app.debug = args.debug
    sp = Senpy(app,
               plugin_folder=None,
               default_plugins=not args.no_default_plugins,
               data_folder=args.data_folder)
    folders = list(args.plugins_folder) if args.plugins_folder else []
    if not folders:
        folders.append(".")
    for p in folders:
        sp.add_folder(p)

    plugins = sp.plugins(plugin_type=None, is_activated=False)
    maxname = max(len(x.name) for x in plugins)
    maxversion = max(len(str(x.version)) for x in plugins)
    print('Found {} plugins:'.format(len(plugins)))
    for plugin in plugins:
        import inspect
        fpath = inspect.getfile(plugin.__class__)
        print('\t{: <{maxname}} @ {: <{maxversion}} -> {}'.format(plugin.name,
                                                                  plugin.version,
                                                                  fpath,
                                                                  maxname=maxname,
                                                                  maxversion=maxversion))
    if args.only_list:
        return
    if not args.no_deps:
        sp.install_deps()
    if args.only_install:
        return
    sp.activate_all(allow_fail=args.allow_fail)
    if args.test or args.only_test:
        easy_test(sp.plugins(), debug=args.debug)
        if args.only_test:
            return
    print('Senpy version {}'.format(senpy.__version__))
    print('Server running on port %s:%d. Ctrl+C to quit' % (args.host,
                                                            args.port))
    try:
        app.run(args.host,
                args.port,
                threaded=not args.no_threaded,
                debug=app.debug)
    except KeyboardInterrupt:
        print('Bye!')
    sp.deactivate_all()
Exemplo n.º 6
0
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, default_plugins=False)
        self.senpy.init_app(self.app)
        self.senpy.activate_plugin("Dummy", sync=True)
        return self.app

    def test_init(self):
        """ Initialising the app with the extension.  """
        assert hasattr(self.app, "senpy")
        tapp = Flask("temp app")
        self.senpy.init_app(tapp)
        assert hasattr(tapp, "senpy")

    def test_discovery(self):
        """ Discovery of plugins in given folders.  """
        # noinspection PyProtectedMember
        assert self.dir in self.senpy._search_folders
        print(self.senpy.plugins)
        assert "Dummy" in self.senpy.plugins

    def test_enabling(self):
        """ Enabling a plugin """
        self.senpy.activate_all(sync=True)
        assert len(self.senpy.plugins) == 2
        assert self.senpy.plugins["Sleep"].is_activated

    def test_disabling(self):
        """ Disabling a plugin """
        self.senpy.deactivate_all(sync=True)
        assert not self.senpy.plugins["Dummy"].is_activated
        assert not self.senpy.plugins["Sleep"].is_activated

    def test_default(self):
        """ Default plugin should be set """
        assert self.senpy.default_plugin
        assert self.senpy.default_plugin.name == "Dummy"
        self.senpy.deactivate_all(sync=True)
        logging.debug("Default: {}".format(self.senpy.default_plugin))
        assert self.senpy.default_plugin is None

    def test_noplugin(self):
        """ Don't analyse if there isn't any plugin installed """
        self.senpy.deactivate_all(sync=True)
        self.assertRaises(Error, partial(self.senpy.analyse, input="tupni"))

    def test_analyse(self):
        """ Using a plugin """
        # I was using mock until plugin started inheriting
        # Leaf (defaultdict with  __setattr__ and __getattr__.
        r1 = self.senpy.analyse(
            algorithm="Dummy", input="tupni", output="tuptuo")
        r2 = self.senpy.analyse(input="tupni", output="tuptuo")
        assert r1.analysis[0].id[:5] == "Dummy"
        assert r2.analysis[0].id[:5] == "Dummy"

    def test_filtering(self):
        """ Filtering plugins """
        assert len(self.senpy.filter_plugins(name="Dummy")) > 0
        assert not len(self.senpy.filter_plugins(name="notdummy"))
        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))
Exemplo n.º 7
0
def main():
    parser = argparse.ArgumentParser(description='Run a Senpy server')
    parser.add_argument(
        '--level',
        '-l',
        metavar='logging_level',
        type=str,
        default="WARN",
        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="0.0.0.0",
        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='.',
        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 plugin dependencies')
    parser.add_argument(
        '--only-test',
        action='store_true',
        default=False,
        help='Do not run a server, just test all plugins')
    parser.add_argument(
        '--test',
        '-t',
        action='store_true',
        default=False,
        help='Test all plugins before launching the server')
    parser.add_argument(
        '--only-list',
        '--list',
        action='store_true',
        default=False,
        help='Do not run a server, only list plugins found')
    parser.add_argument(
        '--data-folder',
        '--data',
        type=str,
        default=None,
        help='Where to look for data. It be set with the SENPY_DATA environment variable as well.')
    parser.add_argument(
        '--threaded',
        action='store_false',
        default=True,
        help='Run a threaded server')
    parser.add_argument(
        '--no-deps',
        '-n',
        action='store_true',
        default=False,
        help='Skip installing dependencies')
    parser.add_argument(
        '--version',
        '-v',
        action='store_true',
        default=False,
        help='Output the senpy version and exit')
    parser.add_argument(
        '--allow-fail',
        '--fail',
        action='store_true',
        default=False,
        help='Do not exit if some plugins fail to activate')
    args = parser.parse_args()
    if args.version:
        print('Senpy version {}'.format(senpy.__version__))
        print(sys.version)
        exit(1)
    rl = logging.getLogger()
    rl.setLevel(getattr(logging, args.level))
    app = Flask(__name__)
    app.debug = args.debug
    sp = Senpy(app, args.plugins_folder,
               default_plugins=args.default_plugins,
               data_folder=args.data_folder)
    if args.only_list:
        plugins = sp.plugins()
        maxname = max(len(x.name) for x in plugins)
        maxversion = max(len(x.version) for x in plugins)
        print('Found {} plugins:'.format(len(plugins)))
        for plugin in plugins:
            import inspect
            fpath = inspect.getfile(plugin.__class__)
            print('\t{: <{maxname}} @ {: <{maxversion}} -> {}'.format(plugin.name,
                                                                      plugin.version,
                                                                      fpath,
                                                                      maxname=maxname,
                                                                      maxversion=maxversion))
        return
    if not args.no_deps:
        sp.install_deps()
    if args.only_install:
        return
    sp.activate_all(allow_fail=args.allow_fail)
    if args.test or args.only_test:
        easy_test(sp.plugins(), debug=args.debug)
        if args.only_test:
            return
    print('Senpy version {}'.format(senpy.__version__))
    print('Server running on port %s:%d. Ctrl+C to quit' % (args.host,
                                                            args.port))
    app.run(args.host,
            args.port,
            threaded=args.threaded,
            debug=app.debug)
    sp.deactivate_all()
Exemplo n.º 8
0
class ExtensionsTest(TestCase):
    def setUp(self):
        self.app = Flask('test_extensions')
        self.examples_dir = os.path.join(os.path.dirname(__file__), '..',
                                         'example-plugins')
        self.senpy = Senpy(plugin_folder=self.examples_dir,
                           app=self.app,
                           default_plugins=False)
        self.senpy.deactivate_all()
        self.senpy.activate_plugin("Dummy", sync=True)
        self.app.config['TESTING'] = True  # Tell Flask not to catch Exceptions

    def test_init(self):
        """ Initialising the app with the extension.  """
        assert hasattr(self.app, "senpy")
        tapp = Flask("temp app")
        self.senpy.init_app(tapp)
        assert hasattr(tapp, "senpy")

    def test_discovery(self):
        """ Discovery of plugins in given folders.  """
        # noinspection PyProtectedMember
        print(self.senpy.plugins())
        assert self.senpy.get_plugin("dummy")

    def test_add_delete(self):
        '''Should be able to add and delete new plugins. '''
        new = plugins.Analyser(name='new', description='new', version=0)
        self.senpy.add_plugin(new)
        assert new in self.senpy.plugins(is_activated=False)
        self.senpy.delete_plugin(new)
        assert new not in self.senpy.plugins(is_activated=False)

    def test_adding_folder(self):
        """ It should be possible for senpy to look for plugins in more folders. """
        senpy = Senpy(plugin_folder=None, app=self.app, default_plugins=False)
        assert not senpy.analysis_plugins()
        senpy.add_folder(self.examples_dir)
        assert senpy.plugins(plugin_type=plugins.Analyser, is_activated=False)
        self.assertRaises(AttributeError, senpy.add_folder, 'DOES NOT EXIST')

    def test_installing(self):
        """ Installing a plugin """
        info = {
            'name': 'TestPip',
            'module': 'mynoop',
            'description': None,
            'requirements': ['noop'],
            'version': 0
        }
        module = plugins.from_info(info, root=self.examples_dir, install=True)
        assert module.name == 'TestPip'
        assert module
        import noop
        dir(noop)

    def test_enabling(self):
        """ Enabling a plugin """
        self.senpy.activate_all(sync=True)
        assert len(self.senpy.plugins()) >= 3
        assert self.senpy.get_plugin("Sleep").is_activated

    def test_installing_nonexistent(self):
        """ Fail if the dependencies cannot be met """
        info = {
            'name': 'TestPipFail',
            'module': 'dummy',
            'description': None,
            'requirements': ['IAmMakingThisPackageNameUpToFail'],
            'version': 0
        }
        with self.assertRaises(Error):
            plugins.install_deps(info)

    def test_disabling(self):
        """ Disabling a plugin """
        self.senpy.deactivate_all(sync=True)
        assert not self.senpy.get_plugin("dummy").is_activated
        assert not self.senpy.get_plugin("sleep").is_activated

    def test_default(self):
        """ Default plugin should be set """
        assert self.senpy.default_plugin
        assert self.senpy.default_plugin.name == "dummy"
        self.senpy.deactivate_all(sync=True)
        logging.debug("Default: {}".format(self.senpy.default_plugin))
        assert self.senpy.default_plugin is None

    def test_noplugin(self):
        """ Don't analyse if there isn't any plugin installed """
        self.senpy.deactivate_all(sync=True)
        self.assertRaises(Error, partial(analyse, self.senpy, input="tupni"))

    def test_analyse(self):
        """ Using a plugin """
        # I was using mock until plugin started inheriting
        # Leaf (defaultdict with  __setattr__ and __getattr__.
        r1 = analyse(self.senpy,
                     algorithm="Dummy",
                     input="tupni",
                     output="tuptuo")
        r2 = analyse(self.senpy, input="tupni", output="tuptuo")
        assert r1.activities[0].algorithm == "endpoint:plugins/dummy_0.1"
        assert r2.activities[0].algorithm == "endpoint:plugins/dummy_0.1"
        assert r1.entries[0]['nif:isString'] == 'input'

    def test_analyse_empty(self):
        """ Trying to analyse when no plugins are installed should raise an error."""
        senpy = Senpy(plugin_folder=None, app=self.app, default_plugins=False)
        self.assertRaises(Error, senpy.analyse, Results(), [])

    def test_analyse_wrong(self):
        """ Trying to analyse with a non-existent plugin should raise an error."""
        self.assertRaises(Error,
                          analyse,
                          self.senpy,
                          algorithm='DOES NOT EXIST',
                          input='test')

    def test_analyse_jsonld(self):
        """ Using a plugin with JSON-LD input"""
        js_input = '''{
        "@id": "prueba",
        "@type": "results",
        "entries": [
          {"@id": "entry1",
           "nif:isString": "tupni",
           "@type": "entry"
          }
        ]
        }'''
        r1 = analyse(self.senpy,
                     algorithm="Dummy",
                     input=js_input,
                     informat="json-ld",
                     output="tuptuo")
        r2 = analyse(self.senpy, input="tupni", output="tuptuo")
        assert r1.activities[0].algorithm == "endpoint:plugins/dummy_0.1"
        assert r2.activities[0].algorithm == "endpoint:plugins/dummy_0.1"
        assert r1.entries[0]['nif:isString'] == 'input'

    def test_analyse_error(self):
        class ErrorPlugin(plugins.Analyser):
            author = 'nobody'
            version = 0
            ex = Error()

            def process(self, *args, **kwargs):
                raise self.ex

        m = ErrorPlugin(ex=Error('error in analysis', status=500))
        self.senpy.add_plugin(m)
        try:
            analyse(self.senpy, input='nothing', algorithm='ErrorPlugin')
            assert False
        except Error as ex:
            assert 'error in analysis' in ex['message']
            assert ex['status'] == 500

        m.ex = Exception('generic exception on analysis')

        try:
            analyse(self.senpy, input='nothing', algorithm='ErrorPlugin')
            assert False
        except Exception as ex:
            assert 'generic exception on analysis' in str(ex)

    def test_filtering(self):
        """ Filtering plugins """
        assert len(self.senpy.plugins(name="Dummy")) > 0
        assert not len(self.senpy.plugins(name="NotDummy"))
        assert self.senpy.plugins(name="Dummy", is_activated=True)
        self.senpy.deactivate_plugin("Dummy", sync=True)
        assert not len(self.senpy.plugins(name="Dummy", is_activated=True))

    def test_load_default_plugins(self):
        senpy = Senpy(plugin_folder=self.examples_dir, default_plugins=True)
        assert len(senpy.plugins(is_activated=False)) > 1

    def test_convert_emotions(self):
        self.senpy.activate_all(sync=True)
        plugin = Plugin({
            'id': 'imaginary',
            'onyx:usesEmotionModel': 'emoml:fsre-dimensions'
        })
        eSet1 = EmotionSet()
        activity = plugin.activity()
        eSet1.prov(activity)
        eSet1['onyx:hasEmotion'].append(
            Emotion({
                'emoml:arousal': 1,
                'emoml:potency': 0,
                'emoml:valence': 0
            }))
        response = Results({
            'activities': [activity],
            'entries': [
                Entry({
                    'nif:isString': 'much ado about nothing',
                    'onyx:hasEmotionSet': [eSet1]
                })
            ]
        })
        params = {
            'emotion-model': 'emoml:big6',
            'algorithm': ['conversion'],
            'conversion': 'full'
        }
        r1 = deepcopy(response)
        r1.parameters = params
        self.senpy.analyse(r1)
        assert len(r1.entries[0].emotions) == 2
        params['conversion'] = 'nested'
        r2 = deepcopy(response)
        r2.parameters = params
        self.senpy.analyse(r2)
        assert len(r2.entries[0].emotions) == 1
        assert r2.entries[0].emotions[0]['prov:wasDerivedFrom'] == eSet1
        params['conversion'] = 'filtered'
        r3 = deepcopy(response)
        r3.parameters = params
        self.senpy.analyse(r3)
        assert len(r3.entries[0].emotions) == 1
        r3.jsonld()
Exemplo n.º 9
0
class ExtensionsTest(TestCase):
    def setUp(self):
        self.app = Flask('test_extensions')
        self.dir = os.path.dirname(__file__)
        self.senpy = Senpy(plugin_folder=self.dir,
                           app=self.app,
                           default_plugins=False)
        self.senpy.activate_plugin("Dummy", sync=True)

    def test_init(self):
        """ Initialising the app with the extension.  """
        assert hasattr(self.app, "senpy")
        tapp = Flask("temp app")
        self.senpy.init_app(tapp)
        assert hasattr(tapp, "senpy")

    def test_discovery(self):
        """ Discovery of plugins in given folders.  """
        # noinspection PyProtectedMember
        assert self.dir in self.senpy._search_folders
        print(self.senpy.plugins)
        assert "Dummy" in self.senpy.plugins

    def test_installing(self):
        """ Installing a plugin """
        info = {
            'name': 'TestPip',
            'module': 'dummy',
            'description': None,
            'requirements': ['noop'],
            'version': 0
        }
        root = os.path.join(self.dir, 'plugins', 'dummy_plugin')
        module = plugins.load_plugin_from_info(info, root=root)
        plugins.install_deps(info)
        assert module.name == 'TestPip'
        assert module
        import noop
        dir(noop)

    def test_enabling(self):
        """ Enabling a plugin """
        self.senpy.activate_all(sync=True)
        assert len(self.senpy.plugins) >= 3
        assert self.senpy.plugins["Sleep"].is_activated

    def test_installing_nonexistent(self):
        """ Fail if the dependencies cannot be met """
        info = {
            'name': 'TestPipFail',
            'module': 'dummy',
            'description': None,
            'requirements': ['IAmMakingThisPackageNameUpToFail'],
            'version': 0
        }
        with self.assertRaises(Error):
            plugins.install_deps(info)

    def test_disabling(self):
        """ Disabling a plugin """
        self.senpy.deactivate_all(sync=True)
        assert not self.senpy.plugins["Dummy"].is_activated
        assert not self.senpy.plugins["Sleep"].is_activated

    def test_default(self):
        """ Default plugin should be set """
        assert self.senpy.default_plugin
        assert self.senpy.default_plugin.name == "Dummy"
        self.senpy.deactivate_all(sync=True)
        logging.debug("Default: {}".format(self.senpy.default_plugin))
        assert self.senpy.default_plugin is None

    def test_noplugin(self):
        """ Don't analyse if there isn't any plugin installed """
        self.senpy.deactivate_all(sync=True)
        self.assertRaises(Error, partial(analyse, self.senpy, input="tupni"))

    def test_analyse(self):
        """ Using a plugin """
        # I was using mock until plugin started inheriting
        # Leaf (defaultdict with  __setattr__ and __getattr__.
        r1 = analyse(self.senpy, algorithm="Dummy", input="tupni", output="tuptuo")
        r2 = analyse(self.senpy, input="tupni", output="tuptuo")
        assert r1.analysis[0] == "plugins/Dummy_0.1"
        assert r2.analysis[0] == "plugins/Dummy_0.1"
        assert r1.entries[0]['nif:iString'] == 'input'

    def test_analyse_jsonld(self):
        """ Using a plugin with JSON-LD input"""
        js_input = '''{
        "@id": "prueba",
        "@type": "results",
        "entries": [
          {"@id": "entry1",
           "nif:isString": "tupni",
           "@type": "entry"
          }
        ]
        }'''
        r1 = analyse(self.senpy,
                     algorithm="Dummy",
                     input=js_input,
                     informat="json-ld",
                     output="tuptuo")
        r2 = analyse(self.senpy,
                     input="tupni",
                     output="tuptuo")
        assert r1.analysis[0] == "plugins/Dummy_0.1"
        assert r2.analysis[0] == "plugins/Dummy_0.1"
        assert r1.entries[0]['nif:iString'] == 'input'

    def test_analyse_error(self):
        mm = mock.MagicMock()
        mm.id = 'magic_mock'
        mm.is_activated = True
        mm.analyse_entries.side_effect = Error('error in analysis', status=500)
        self.senpy.plugins['MOCK'] = mm
        try:
            analyse(self.senpy, input='nothing', algorithm='MOCK')
            assert False
        except Error as ex:
            assert 'error in analysis' in ex['message']
            assert ex['status'] == 500

        mm.analyse.side_effect = Exception('generic exception on analysis')
        mm.analyse_entries.side_effect = Exception(
            'generic exception on analysis')

        try:
            analyse(self.senpy, input='nothing', algorithm='MOCK')
            assert False
        except Error as ex:
            assert 'generic exception on analysis' in ex['message']
            assert ex['status'] == 500

    def test_filtering(self):
        """ Filtering plugins """
        assert len(self.senpy.filter_plugins(name="Dummy")) > 0
        assert not len(self.senpy.filter_plugins(name="notdummy"))
        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))

    def test_load_default_plugins(self):
        senpy = Senpy(plugin_folder=self.dir, default_plugins=True)
        assert len(senpy.plugins) > 1

    def test_convert_emotions(self):
        self.senpy.activate_all(sync=True)
        plugin = Plugin({
            'id': 'imaginary',
            'onyx:usesEmotionModel': 'emoml:fsre-dimensions'
        })
        eSet1 = EmotionSet()
        eSet1.prov__wasGeneratedBy = plugin['@id']
        eSet1['onyx:hasEmotion'].append(Emotion({
            'emoml:arousal': 1,
            'emoml:potency': 0,
            'emoml:valence': 0
        }))
        response = Results({
            'analysis': [{'plugin': plugin}],
            'entries': [Entry({
                'nif:iString': 'much ado about nothing',
                'emotions': [eSet1]
            })]
        })
        params = {'emotionModel': 'emoml:big6',
                  'conversion': 'full'}
        r1 = deepcopy(response)
        r1.parameters = params
        self.senpy.convert_emotions(r1)
        assert len(r1.entries[0].emotions) == 2
        params['conversion'] = 'nested'
        r2 = deepcopy(response)
        r2.parameters = params
        self.senpy.convert_emotions(r2)
        assert len(r2.entries[0].emotions) == 1
        assert r2.entries[0].emotions[0]['prov:wasDerivedFrom'] == eSet1
        params['conversion'] = 'filtered'
        r3 = deepcopy(response)
        r3.parameters = params
        self.senpy.convert_emotions(r3)
        assert len(r3.entries[0].emotions) == 1
        r3.jsonld()
Exemplo n.º 10
0
#    limitations under the License.
"""
This is a helper for development. If you want to run Senpy use:

    python -m senpy
"""
from gevent.monkey import patch_all

patch_all()
import gevent
import config
from flask import Flask
from senpy.extensions import Senpy
import logging
import os
from gevent.wsgi import WSGIServer

logging.basicConfig(level=logging.DEBUG)

app = Flask(__name__)
mypath = os.path.dirname(os.path.realpath(__file__))
sp = Senpy(app, os.path.join(mypath, "plugins"), default_plugins=True)
sp.activate_all()

if __name__ == '__main__':
    import logging
    logging.basicConfig(level=config.DEBUG)
    app.debug = config.DEBUG
    http_server = WSGIServer(('', config.SERVER_PORT), app)
    http_server.serve_forever()
Exemplo n.º 11
0
#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#    See the License for the specific language governing permissions and
#    limitations under the License.
"""
This is a helper for development. If you want to run Senpy use:

    python -m senpy
"""
from gevent.monkey import patch_all; patch_all()
import gevent
import config
from flask import Flask
from senpy.extensions import Senpy
import logging
import os
from gevent.wsgi import WSGIServer

logging.basicConfig(level=logging.DEBUG)

app = Flask(__name__)
mypath = os.path.dirname(os.path.realpath(__file__))
sp = Senpy(app, os.path.join(mypath, "plugins"), default_plugins=True)
sp.activate_all()

if __name__ == '__main__':
    import logging
    logging.basicConfig(level=config.DEBUG)
    app.debug = config.DEBUG
    http_server = WSGIServer(('', config.SERVER_PORT), app)
    http_server.serve_forever()
Exemplo n.º 12
0
class ExtensionsTest(TestCase):
    def setUp(self):
        self.app = Flask('test_extensions')
        self.examples_dir = os.path.join(os.path.dirname(__file__), '..', 'example-plugins')
        self.senpy = Senpy(plugin_folder=self.examples_dir,
                           app=self.app,
                           default_plugins=False)
        self.senpy.deactivate_all()
        self.senpy.activate_plugin("Dummy", sync=True)
        self.app.config['TESTING'] = True  # Tell Flask not to catch Exceptions

    def test_init(self):
        """ Initialising the app with the extension.  """
        assert hasattr(self.app, "senpy")
        tapp = Flask("temp app")
        self.senpy.init_app(tapp)
        assert hasattr(tapp, "senpy")

    def test_discovery(self):
        """ Discovery of plugins in given folders.  """
        # noinspection PyProtectedMember
        print(self.senpy.plugins())
        assert self.senpy.get_plugin("dummy")

    def test_add_delete(self):
        '''Should be able to add and delete new plugins. '''
        new = plugins.Analyser(name='new', description='new', version=0)
        self.senpy.add_plugin(new)
        assert new in self.senpy.plugins(is_activated=False)
        self.senpy.delete_plugin(new)
        assert new not in self.senpy.plugins(is_activated=False)

    def test_adding_folder(self):
        """ It should be possible for senpy to look for plugins in more folders. """
        senpy = Senpy(plugin_folder=None,
                      app=self.app,
                      default_plugins=False)
        assert not senpy.analysis_plugins()
        senpy.add_folder(self.examples_dir)
        assert senpy.plugins(plugin_type=plugins.Analyser, is_activated=False)
        self.assertRaises(AttributeError, senpy.add_folder, 'DOES NOT EXIST')

    def test_installing(self):
        """ Installing a plugin """
        info = {
            'name': 'TestPip',
            'module': 'mynoop',
            'description': None,
            'requirements': ['noop'],
            'version': 0
        }
        module = plugins.from_info(info, root=self.examples_dir, install=True)
        assert module.name == 'TestPip'
        assert module
        import noop
        dir(noop)

    def test_enabling(self):
        """ Enabling a plugin """
        self.senpy.activate_all(sync=True)
        assert len(self.senpy.plugins()) >= 3
        assert self.senpy.get_plugin("Sleep").is_activated

    def test_installing_nonexistent(self):
        """ Fail if the dependencies cannot be met """
        info = {
            'name': 'TestPipFail',
            'module': 'dummy',
            'description': None,
            'requirements': ['IAmMakingThisPackageNameUpToFail'],
            'version': 0
        }
        with self.assertRaises(Error):
            plugins.install_deps(info)

    def test_disabling(self):
        """ Disabling a plugin """
        self.senpy.deactivate_all(sync=True)
        assert not self.senpy.get_plugin("dummy").is_activated
        assert not self.senpy.get_plugin("sleep").is_activated

    def test_default(self):
        """ Default plugin should be set """
        assert self.senpy.default_plugin
        assert self.senpy.default_plugin.name == "dummy"
        self.senpy.deactivate_all(sync=True)
        logging.debug("Default: {}".format(self.senpy.default_plugin))
        assert self.senpy.default_plugin is None

    def test_noplugin(self):
        """ Don't analyse if there isn't any plugin installed """
        self.senpy.deactivate_all(sync=True)
        self.assertRaises(Error, partial(analyse, self.senpy, input="tupni"))

    def test_analyse(self):
        """ Using a plugin """
        # I was using mock until plugin started inheriting
        # Leaf (defaultdict with  __setattr__ and __getattr__.
        r1 = analyse(self.senpy, algorithm="Dummy", input="tupni", output="tuptuo")
        r2 = analyse(self.senpy, input="tupni", output="tuptuo")
        assert r1.activities[0].algorithm == "endpoint:plugins/dummy_0.1"
        assert r2.activities[0].algorithm == "endpoint:plugins/dummy_0.1"
        assert r1.entries[0]['nif:isString'] == 'input'

    def test_analyse_empty(self):
        """ Trying to analyse when no plugins are installed should raise an error."""
        senpy = Senpy(plugin_folder=None,
                      app=self.app,
                      default_plugins=False)
        self.assertRaises(Error, senpy.analyse, Results(), [])

    def test_analyse_wrong(self):
        """ Trying to analyse with a non-existent plugin should raise an error."""
        self.assertRaises(Error, analyse, self.senpy, algorithm='DOES NOT EXIST', input='test')

    def test_analyse_jsonld(self):
        """ Using a plugin with JSON-LD input"""
        js_input = '''{
        "@id": "prueba",
        "@type": "results",
        "entries": [
          {"@id": "entry1",
           "nif:isString": "tupni",
           "@type": "entry"
          }
        ]
        }'''
        r1 = analyse(self.senpy,
                     algorithm="Dummy",
                     input=js_input,
                     informat="json-ld",
                     output="tuptuo")
        r2 = analyse(self.senpy,
                     input="tupni",
                     output="tuptuo")
        assert r1.activities[0].algorithm == "endpoint:plugins/dummy_0.1"
        assert r2.activities[0].algorithm == "endpoint:plugins/dummy_0.1"
        assert r1.entries[0]['nif:isString'] == 'input'

    def test_analyse_error(self):
        class ErrorPlugin(plugins.Analyser):
            author = 'nobody'
            version = 0
            ex = Error()

            def process(self, *args, **kwargs):
                raise self.ex

        m = ErrorPlugin(ex=Error('error in analysis', status=500))
        self.senpy.add_plugin(m)
        try:
            analyse(self.senpy, input='nothing', algorithm='ErrorPlugin')
            assert False
        except Error as ex:
            assert 'error in analysis' in ex['message']
            assert ex['status'] == 500

        m.ex = Exception('generic exception on analysis')

        try:
            analyse(self.senpy, input='nothing', algorithm='ErrorPlugin')
            assert False
        except Exception as ex:
            assert 'generic exception on analysis' in str(ex)

    def test_filtering(self):
        """ Filtering plugins """
        assert len(self.senpy.plugins(name="Dummy")) > 0
        assert not len(self.senpy.plugins(name="NotDummy"))
        assert self.senpy.plugins(name="Dummy", is_activated=True)
        self.senpy.deactivate_plugin("Dummy", sync=True)
        assert not len(self.senpy.plugins(name="Dummy",
                                          is_activated=True))

    def test_load_default_plugins(self):
        senpy = Senpy(plugin_folder=self.examples_dir, default_plugins=True)
        assert len(senpy.plugins(is_activated=False)) > 1

    def test_convert_emotions(self):
        self.senpy.activate_all(sync=True)
        plugin = Plugin({
            'id': 'imaginary',
            'onyx:usesEmotionModel': 'emoml:fsre-dimensions'
        })
        eSet1 = EmotionSet()
        activity = plugin.activity()
        eSet1.prov(activity)
        eSet1['onyx:hasEmotion'].append(Emotion({
            'emoml:arousal': 1,
            'emoml:potency': 0,
            'emoml:valence': 0
        }))
        response = Results({
            'activities': [activity],
            'entries': [Entry({
                'nif:isString': 'much ado about nothing',
                'onyx:hasEmotionSet': [eSet1]
            })]
        })
        params = {'emotion-model': 'emoml:big6',
                  'algorithm': ['conversion'],
                  'conversion': 'full'}
        r1 = deepcopy(response)
        r1.parameters = params
        self.senpy.analyse(r1)
        assert len(r1.entries[0].emotions) == 2
        params['conversion'] = 'nested'
        r2 = deepcopy(response)
        r2.parameters = params
        self.senpy.analyse(r2)
        assert len(r2.entries[0].emotions) == 1
        assert r2.entries[0].emotions[0]['prov:wasDerivedFrom'] == eSet1
        params['conversion'] = 'filtered'
        r3 = deepcopy(response)
        r3.parameters = params
        self.senpy.analyse(r3)
        assert len(r3.entries[0].emotions) == 1
        r3.jsonld()
Exemplo n.º 13
0
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, default_plugins=False)
        self.senpy.init_app(self.app)
        self.senpy.activate_plugin("Dummy", sync=True)
        return self.app

    def test_init(self):
        """ Initialising the app with the extension.  """
        assert hasattr(self.app, "senpy")
        tapp = Flask("temp app")
        self.senpy.init_app(tapp)
        assert hasattr(tapp, "senpy")

    def test_discovery(self):
        """ Discovery of plugins in given folders.  """
        # noinspection PyProtectedMember
        assert self.dir in self.senpy._search_folders
        print self.senpy.plugins
        assert "Dummy" in self.senpy.plugins

    def test_enabling(self):
        """ Enabling a plugin """
        self.senpy.activate_all(sync=True)
        assert len(self.senpy.plugins) == 2
        assert self.senpy.plugins["Sleep"].is_activated

    def test_disabling(self):
        """ Disabling a plugin """
        self.senpy.deactivate_all(sync=True)
        assert not self.senpy.plugins["Dummy"].is_activated
        assert not self.senpy.plugins["Sleep"].is_activated

    def test_default(self):
        """ Default plugin should be set """
        assert self.senpy.default_plugin
        assert self.senpy.default_plugin.name == "Dummy"
        self.senpy.deactivate_all(sync=True)
        logging.debug("Default: {}".format(self.senpy.default_plugin))
        assert self.senpy.default_plugin is None

    def test_noplugin(self):
        """ Don't analyse if there isn't any plugin installed """
        self.senpy.deactivate_all(sync=True)
        resp = self.senpy.analyse(input="tupni")
        logging.debug("Response: {}".format(resp))
        assert resp["status"] == 404

    def test_analyse(self):
        """ Using a plugin """
        # I was using mock until plugin started inheriting
        # Leaf (defaultdict with  __setattr__ and __getattr__.
        r1 = self.senpy.analyse(
            algorithm="Dummy", input="tupni", output="tuptuo")
        r2 = self.senpy.analyse(input="tupni", output="tuptuo")
        assert r1.analysis[0].id[:5] == "Dummy"
        assert r2.analysis[0].id[:5] == "Dummy"
        for plug in self.senpy.plugins:
            self.senpy.deactivate_plugin(plug, sync=True)
        resp = self.senpy.analyse(input="tupni")
        logging.debug("Response: {}".format(resp))
        assert resp["status"] == 404


    def test_filtering(self):
        """ Filtering plugins """
        assert len(self.senpy.filter_plugins(name="Dummy")) > 0
        assert not len(self.senpy.filter_plugins(name="notdummy"))
        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))
Exemplo n.º 14
0
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="0.0.0.0",
        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 plugin dependencies')
    parser.add_argument(
        '--threaded',
        action='store_false',
        default=True,
        help='Run a threaded server')
    parser.add_argument(
        '--version',
        '-v',
        action='store_true',
        default=False,
        help='Output the senpy version and exit')
    args = parser.parse_args()
    if args.version:
        print('Senpy version {}'.format(senpy.__version__))
        exit(1)
    logging.basicConfig()
    rl = logging.getLogger()
    rl.setLevel(getattr(logging, args.level))
    app = Flask(__name__)
    app.debug = args.debug
    sp = Senpy(app, args.plugins_folder, default_plugins=args.default_plugins)
    sp.install_deps()
    if args.only_install:
        return
    sp.activate_all()
    print('Senpy version {}'.format(senpy.__version__))
    print('Server running on port %s:%d. Ctrl+C to quit' % (args.host,
                                                            args.port))
    app.run(args.host,
            args.port,
            threaded=args.threaded,
            debug=app.debug)
    sp.deactivate_all()