Example #1
0
    def _run_local_app_internal(self, app_id, params, widget_state, tag, version, cell_id, run_id):
        self._send_comm_message('run_status', {
            'event': 'validating_app',
            'event_at': datetime.datetime.utcnow().isoformat() + 'Z',
            'cell_id': cell_id,
            'run_id': run_id
        })

        spec = self._get_validated_app_spec(app_id, tag, False, version=version)

        # Here, we just deal with two behaviors:
        # 1. None of the above - it's a viewer.
        # 2. ***TODO*** python_class / python_function.
        #    Import and exec the python code.

        # for now, just map the inputs to outputs.
        # First, validate.
        # Preflight check the params - all required ones are present, all
        # values are the right type, all numerical values are in given ranges
        spec_params = self.spec_manager.app_params(spec)
        (params, ws_refs) = validate_parameters(app_id, tag, spec_params, params)

        # Log that we're trying to run a job...
        log_info = {
            'app_id': app_id,
            'tag': tag,
            'username': system_variable('user_id'),
            'ws': system_variable('workspace')
        }
        kblogging.log_event(self._log, "run_local_app", log_info)

        self._send_comm_message('run_status', {
            'event': 'success',
            'event_at': datetime.datetime.utcnow().isoformat() + 'Z',
            'cell_id': cell_id,
            'run_id': run_id
        })

        (output_widget, widget_params) = map_outputs_from_state([],
                                                                params,
                                                                spec)

        # All a local app does is route the inputs to outputs through the
        # spec's mapping, and then feed that into the specified output widget.
        wm = WidgetManager()
        if widget_state is not None:
            return wm.show_advanced_viewer_widget(
                output_widget, widget_params, widget_state, cell_id=cell_id, tag=tag
            )
        else:
            return wm.show_output_widget(
                output_widget, widget_params, cell_id=cell_id, tag=tag
            )
Example #2
0
 def setUpClass(self):
     config = TestConfig()
     os.environ[
         "KB_WORKSPACE_ID"] = "12345"  # That's the same workspace as my luggage!
     app_specs_list = config.load_json_file(
         config.get("specs", "app_specs_file"))
     app_specs_dict = dict()
     for s in app_specs_list:
         app_specs_dict[s["info"]["id"]] = s
     self.wm = WidgetManager()
     self.good_widget = "kbaseTabTable"
     self.bad_widget = "notAWidget"
     self.good_tag = "release"
     self.bad_tag = "notATag"
     self.widget_with_consts = "kbaseContigSetView"
Example #3
0
 def setUpClass(self):
     config = TestConfig()
     os.environ[
         'KB_WORKSPACE_ID'] = '12345'  # That's the same workspace as my luggage!
     app_specs_list = config.load_json_file(
         config.get('specs', 'app_specs_file'))
     app_specs_dict = dict()
     for s in app_specs_list:
         app_specs_dict[s['info']['id']] = s
     self.wm = WidgetManager()
     self.good_widget = "kbaseTabTable"
     self.bad_widget = "notAWidget"
     self.good_tag = "release"
     self.bad_tag = "notATag"
     self.widget_with_consts = "kbaseContigSetView"
Example #4
0
 def test_missing_env_path(self):
     backup_dir = os.environ["NARRATIVE_DIR"]
     del os.environ["NARRATIVE_DIR"]
     test_wm = WidgetManager()
     self.assertIsInstance(test_wm.widget_param_map, dict)
     self.assertFalse(test_wm.widget_param_map)
     os.environ["NARRATIVE_DIR"] = backup_dir
Example #5
0
    def _run_widget_app_internal(self, app_id, tag, version, cell_id, run_id):
        self._send_comm_message('run_status', {
            'event': 'validating_app',
            'event_at': datetime.datetime.utcnow().isoformat() + 'Z',
            'cell_id': cell_id,
            'run_id': run_id
        })

        # Intro tests:
        self.spec_manager.check_app(app_id, tag, raise_exception=True)

        if version is not None and tag != "release":
            raise ValueError("App versions only apply to released app modules!")

        # Get the spec & params
        spec = self.spec_manager.get_spec(app_id, tag)

        if 'behavior' not in spec:
            raise ValueError("This app appears invalid - it has no defined behavior")

        behavior = spec['behavior']

        if 'kb_service_input_mapping' in behavior:
            # it's a service! Should run this with run_app!
            raise ValueError('This app appears to be a long-running job! Please start it using the run_app function instead.')

        if 'script_module' in behavior or 'script_name' in behavior:
            # It's an old NJS script. These don't work anymore.
            raise ValueError('This app relies on a service that is now obsolete. Please contact the administrator.')

        # Here, we just deal with two behaviors:
        # 1. None of the above - it's a viewer.
        # 2. ***TODO*** python_class / python_function. Import and exec the python code.

        # for now, just map the inputs to outputs.
        # First, validate.
        # Preflight check the params - all required ones are present, all values are the right type, all numerical values are in given ranges
        #spec_params = self.spec_manager.app_params(spec)
        #(params, ws_refs) = self._validate_parameters(app_id, tag, spec_params, kwargs)

        log_info = {
            'app_id': app_id,
            'tag': tag,
            'username': system_variable('user_id'),
            'ws': system_variable('workspace')
        }
        kblogging.log_event(self._log, "run_widget_app", log_info)

        self._send_comm_message('run_status', {
            'event': 'success',
            'event_at': datetime.datetime.utcnow().isoformat() + 'Z',
            'cell_id': cell_id,
            'run_id': run_id
        })

        # now just map onto outputs.
        custom_widget = spec.get('widgets', {}).get('input', None)
        return WidgetManager().show_custom_widget(custom_widget, app_id, version, tag, spec, cell_id)
Example #6
0
 def setUpClass(self, mock_sm):
     os.environ[
         'KB_WORKSPACE_ID'] = '12345'  # That's the same workspace as my luggage!
     specs_list = read_json_file('data/specs.json')
     specs_dict = dict()
     for s in specs_list:
         specs_dict[s['info']['id']] = s
     mock_sm.return_value.app_specs = {
         'release': specs_dict,
         'beta': specs_dict,
         'dev': specs_dict
     }
     # mock_njs.return_value.list_methods_spec.return_value = read_narrative_file('data/specs.json')
     self.wm = WidgetManager()
     self.good_widget = "kbaseTabTable"
     self.bad_widget = "notAWidget"
     self.good_tag = "release"
     self.bad_tag = "notATag"
 def setUpClass(self, mock_sm):
     config = TestConfig()
     os.environ[
         'KB_WORKSPACE_ID'] = '12345'  # That's the same workspace as my luggage!
     specs_list = config.load_json_file(
         config.get('specs', 'app_specs_file'))
     specs_dict = dict()
     for s in specs_list:
         specs_dict[s['info']['id']] = s
     mock_sm.return_value.app_specs = {
         'release': specs_dict,
         'beta': specs_dict,
         'dev': specs_dict
     }
     self.wm = WidgetManager()
     self.good_widget = "kbaseTabTable"
     self.bad_widget = "notAWidget"
     self.good_tag = "release"
     self.bad_tag = "notATag"
 def setUpClass(self, mock_sm):
     os.environ['KB_WORKSPACE_ID'] = '12345'  # That's the same workspace as my luggage!
     specs_list = read_json_file('data/specs.json')
     specs_dict = dict()
     for s in specs_list:
         specs_dict[s['info']['id']] = s
     mock_sm.return_value.app_specs = {'release': specs_dict, 'beta': specs_dict, 'dev': specs_dict}
     # mock_njs.return_value.list_methods_spec.return_value = read_narrative_file('data/specs.json')
     self.wm = WidgetManager()
     self.good_widget = "kbaseTabTable"
     self.bad_widget = "notAWidget"
     self.good_tag = "release"
     self.bad_tag = "notATag"
Example #9
0
 def show_output_widget(self, state=None):
     """
     For a complete job, returns the job results.
     An incomplete job throws an exception
     """
     from biokbase.narrative.widgetmanager import WidgetManager
     if state is None:
         state = self.state()
     if state['job_state'] == 'completed' and 'result' in state:
         (output_widget, widget_params) = self._get_output_info(state)
         return WidgetManager().show_output_widget(output_widget, widget_params, tag=self.tag)
     else:
         return "Job is incomplete! It has status '{}'".format(state['job_state'])
Example #10
0
 def setUpClass(self):
     config = TestConfig()
     os.environ['KB_WORKSPACE_ID'] = '12345'  # That's the same workspace as my luggage!
     app_specs_list = config.load_json_file(config.get('specs', 'app_specs_file'))
     app_specs_dict = dict()
     for s in app_specs_list:
         app_specs_dict[s['info']['id']] = s
     self.wm = WidgetManager()
     self.good_widget = "kbaseTabTable"
     self.bad_widget = "notAWidget"
     self.good_tag = "release"
     self.bad_tag = "notATag"
     self.widget_with_consts = "kbaseContigSetView"
Example #11
0
    def show_output_widget(self, state=None):
        """
        For a complete job, returns the job results.
        An incomplete job throws an exception
        """
        from biokbase.narrative.widgetmanager import WidgetManager

        if not state:
            state = self.state()
        else:
            self._update_state(state)
            state = self._internal_state()

        if state["status"] == COMPLETED_STATUS and "job_output" in state:
            (output_widget, widget_params) = self._get_output_info(state)
            return WidgetManager().show_output_widget(output_widget,
                                                      widget_params,
                                                      tag=self.tag)
        else:
            return f"Job is incomplete! It has status '{state['status']}'"
Example #12
0
    def _run_local_app_internal(self, app_id, params, widget_state, tag,
                                version, cell_id, run_id):
        self._send_comm_message(
            'run_status', {
                'event': 'validating_app',
                'event_at': datetime.datetime.utcnow().isoformat() + 'Z',
                'cell_id': cell_id,
                'run_id': run_id
            })

        spec = self._get_validated_app_spec(app_id,
                                            tag,
                                            False,
                                            version=version)

        # Here, we just deal with two behaviors:
        # 1. None of the above - it's a viewer.
        # 2. ***TODO*** python_class / python_function.
        #    Import and exec the python code.

        # for now, just map the inputs to outputs.
        # First, validate.
        # Preflight check the params - all required ones are present, all
        # values are the right type, all numerical values are in given ranges
        spec_params = self.spec_manager.app_params(spec)
        (params, ws_refs) = validate_parameters(app_id, tag, spec_params,
                                                params)

        # Log that we're trying to run a job...
        log_info = {
            'app_id': app_id,
            'tag': tag,
            'username': system_variable('user_id'),
            'ws': system_variable('workspace')
        }
        kblogging.log_event(self._log, "run_local_app", log_info)

        self._send_comm_message(
            'run_status', {
                'event': 'success',
                'event_at': datetime.datetime.utcnow().isoformat() + 'Z',
                'cell_id': cell_id,
                'run_id': run_id
            })

        (output_widget, widget_params) = map_outputs_from_state([], params,
                                                                spec)

        # All a local app does is route the inputs to outputs through the
        # spec's mapping, and then feed that into the specified output widget.
        wm = WidgetManager()
        if widget_state is not None:
            return wm.show_advanced_viewer_widget(output_widget,
                                                  widget_params,
                                                  widget_state,
                                                  cell_id=cell_id,
                                                  tag=tag)
        else:
            return wm.show_output_widget(output_widget,
                                         widget_params,
                                         cell_id=cell_id,
                                         tag=tag)
Example #13
0
    def _run_local_app_advanced_internal(self, app_id, params, widget_state,
                                         tag, version, cell_id, run_id,
                                         **kwargs):
        self._send_comm_message(
            'run_status', {
                'event': 'validating_app',
                'event_at': datetime.datetime.utcnow().isoformat() + 'Z',
                'cell_id': cell_id,
                'run_id': run_id
            })

        # Intro tests:
        self.spec_manager.check_app(app_id, tag, raise_exception=True)

        if version is not None and tag != "release":
            raise ValueError("App versions only apply to released modules!")

        # Get the spec & params
        spec = self.spec_manager.get_spec(app_id, tag)

        if 'behavior' not in spec:
            raise ValueError("This app appears invalid - " +
                             "it has no defined behavior")

        behavior = spec['behavior']

        if 'script_module' in behavior or 'script_name' in behavior:
            # It's an old NJS script. These don't work anymore.
            raise ValueError('This app relies on a service that is now ' +
                             'obsolete. Please contact the administrator.')

        # Here, we just deal with two behaviors:
        # 1. None of the above - it's a viewer.
        # 2. ***TODO*** python_class / python_function.
        #    Import and exec the python code.

        # for now, just map the inputs to outputs.
        # First, validate.
        # Preflight check the params - all required ones are present, all
        # values are the right type, all numerical values are in given ranges
        spec_params = self.spec_manager.app_params(spec)
        (params, ws_refs) = self._validate_parameters(app_id, tag, spec_params,
                                                      params)

        # Log that we're trying to run a job...
        log_info = {
            'app_id': app_id,
            'tag': tag,
            'username': system_variable('user_id'),
            'ws': system_variable('workspace')
        }
        kblogging.log_event(self._log, "run_local_app", log_info)

        self._send_comm_message(
            'run_status', {
                'event': 'success',
                'event_at': datetime.datetime.utcnow().isoformat() + 'Z',
                'cell_id': cell_id,
                'run_id': run_id
            })

        (output_widget, widget_params) = map_outputs_from_state([], params,
                                                                spec)

        # All a local app does is route the inputs to outputs through the
        # spec's mapping, and then feed that into the specified output widget.
        return WidgetManager().show_advanced_viewer_widget(output_widget,
                                                           widget_params,
                                                           widget_state,
                                                           cell_id=cell_id,
                                                           tag=tag)
Example #14
0
class WidgetManagerTestCase(unittest.TestCase):
    @classmethod
    @mock.patch('biokbase.narrative.widgetmanager.SpecManager')
    def setUpClass(self, mock_sm):
        os.environ[
            'KB_WORKSPACE_ID'] = '12345'  # That's the same workspace as my luggage!
        specs_list = read_json_file('data/specs.json')
        specs_dict = dict()
        for s in specs_list:
            specs_dict[s['info']['id']] = s
        mock_sm.return_value.app_specs = {
            'release': specs_dict,
            'beta': specs_dict,
            'dev': specs_dict
        }
        # mock_njs.return_value.list_methods_spec.return_value = read_narrative_file('data/specs.json')
        self.wm = WidgetManager()
        self.good_widget = "kbaseTabTable"
        self.bad_widget = "notAWidget"
        self.good_tag = "release"
        self.bad_tag = "notATag"

    def test_widgetmanager_reload(self):
        self.wm.load_widget_info(verbose=True)

    def test_widgetmanager_instantiated(self):
        self.assertIsInstance(self.wm, WidgetManager)

    def test_widget_inputs(self):
        self.wm.print_widget_inputs(self.good_widget)

    def test_widget_inputs_bad(self):
        with self.assertRaises(ValueError) as err:
            self.wm.print_widget_inputs(self.bad_widget)

    def test_widget_constants(self):
        constants = self.wm.get_widget_constants(self.good_widget)
        self.assertTrue('ws' in constants)

    def test_widget_constants_bad(self):
        with self.assertRaises(ValueError) as err:
            self.wm.get_widget_constants(self.bad_widget)

    def test_show_output_widget(self):
        self.assertIsInstance(
            self.wm.show_output_widget(self.good_widget,
                                       {'obj': 'TestObject'}),
            IPython.core.display.Javascript)

    def test_show_output_widget_bad(self):
        with self.assertRaises(ValueError) as err:
            self.wm.show_output_widget(self.bad_widget, {'bad': 'inputs'})

    def test_show_external_widget(self):
        widget = self.wm.show_external_widget('contigSet', 'My ContigSet View',
                                              {'objectRef': '6402/3/8'}, {})
        self.assertIsInstance(widget, IPython.core.display.Javascript)

    def test_show_external_widget_list(self):
        widget = self.wm.show_external_widget(
            ['widgets', '0.1.0', 'genomeComparison'],
            'Genome Comparison Demo', {'objectRef': '6402/5/2'}, {},
            auth_required=True)
        self.assertIsInstance(widget, IPython.core.display.Javascript)
Example #15
0
class WidgetManagerTestCase(unittest.TestCase):
    @classmethod
    def setUpClass(self):
        config = TestConfig()
        os.environ[
            "KB_WORKSPACE_ID"] = "12345"  # That's the same workspace as my luggage!
        app_specs_list = config.load_json_file(
            config.get("specs", "app_specs_file"))
        app_specs_dict = dict()
        for s in app_specs_list:
            app_specs_dict[s["info"]["id"]] = s
        self.wm = WidgetManager()
        self.good_widget = "kbaseTabTable"
        self.bad_widget = "notAWidget"
        self.good_tag = "release"
        self.bad_tag = "notATag"
        self.widget_with_consts = "kbaseContigSetView"

    def test_widgetmanager_reload(self):
        self.wm.load_widget_info(verbose=True)

    def test_widgetmanager_instantiated(self):
        self.assertIsInstance(self.wm, WidgetManager)

    def test_widget_inputs(self):
        self.wm.print_widget_inputs(self.good_widget)

    def test_widget_inputs_bad(self):
        with self.assertRaises(ValueError):
            self.wm.print_widget_inputs(self.bad_widget)

    def test_widget_constants(self):
        constants = self.wm.get_widget_constants(self.widget_with_consts)
        self.assertTrue("ws" in constants)

    def test_widget_constants_bad(self):
        with self.assertRaises(ValueError):
            self.wm.get_widget_constants(self.bad_widget)

    def test_show_output_widget(self):
        self.assertIsInstance(
            self.wm.show_output_widget(
                self.good_widget,
                {"obj": "TestObject"},
                upas={"obj": "1/2/3"},
                check_widget=True,
            ),
            IPython.core.display.Javascript,
        )

    def test_show_output_widget_bad(self):
        with self.assertRaises(ValueError):
            self.wm.show_output_widget(
                self.bad_widget,
                {"bad": "inputs"},
                upas={"bad": "1/2/3"},
                check_widget=True,
            )

    def test_show_advanced_viewer_widget(self):
        title = "Widget Viewer"
        cell_id = "abcde"
        widget_name = "CustomOutputDemo"
        widget_js = self.wm.show_advanced_viewer_widget(
            widget_name,
            {
                "param1": "value1",
                "param2": "value2"
            },
            {
                "param1": "value1",
                "param2": "value2"
            },
            title=title,
            cell_id=cell_id,
            tag="dev",
            check_widget=True,
        )
        self.assertIsInstance(widget_js, IPython.core.display.Javascript)
        widget_code = widget_js.data
        self.assertIn("widget: '{}'".format(widget_name), widget_code)
        self.assertIn('cellId: "{}"'.format(cell_id), widget_code)
        self.assertIn("title: '{}'".format(title), widget_code)

    def test_show_advanced_viewer_widget_bad(self):
        with self.assertRaises(ValueError):
            self.wm.show_advanced_viewer_widget(self.bad_widget,
                                                {"bad": "inputs"},
                                                {"bad": "state"},
                                                check_widget=True)

    def test_show_external_widget(self):
        widget = self.wm.show_external_widget("contigSet", "My ContigSet View",
                                              {"objectRef": "6402/3/8"}, {})
        self.assertIsInstance(widget, IPython.core.display.Javascript)

    def test_show_external_widget_list(self):
        widget = self.wm.show_external_widget(
            ["widgets", "0.1.0", "genomeComparison"],
            "Genome Comparison Demo",
            {"objectRef": "6402/5/2"},
            {},
            auth_required=True,
        )
        self.assertIsInstance(widget, IPython.core.display.Javascript)

    @mock.patch("biokbase.narrative.widgetmanager.clients.get",
                get_mock_client)
    def test_show_data_cell(self):
        """
        Tests - should do the following:
            def show_data_widget(self, upa, title=None, cell_id=None, tag="release"):
        fail message with no upa
        fail message with malformed upa
        shouldn't care what title or cell_id are, but should test to make sure they wind up in
            output code properly
        fail if type spec'd app isn't present for some tag
        otherwise, succeed and produce JS code.

        test mocks.
        """
        js_obj = self.wm.show_data_widget("18836/5/1", "some title", "no_id")
        print(js_obj.data)
        self.assertIsValidCellCode(js_obj, {}, "viewer", "kbaseGenomeView",
                                   "no_id", "some title")

    @mock.patch("biokbase.narrative.widgetmanager.clients.get",
                get_mock_client)
    def test_infer_upas(self):
        test_result_upa = "18836/5/1"
        upas = self.wm.infer_upas(
            "testCrazyExample",
            {
                "obj_id1": 1,
                "obj_id2": 2,
                "obj_name1": "foo",
                "obj_name2": "bar/baz",
                "obj_names": ["a", "b", "c"],
                "obj_ref1": "1/2/3",
                "obj_ref2": "foo/bar",
                "obj_refs": ["7/8/9", "0/1/2"],
                "ws_name": "some_ws",
                "extra_param": "extra_value",
                "other_extra_param": 0,
            },
        )
        self.assertEqual(upas["obj_id1"], test_result_upa)
        self.assertEqual(upas["obj_id2"], test_result_upa)
        self.assertEqual(upas["obj_name1"], test_result_upa)
        self.assertEqual(upas["obj_name2"], test_result_upa)
        self.assertEqual(upas["obj_names"], [test_result_upa] * 3)
        self.assertEqual(upas["obj_ref1"], "1/2/3")
        self.assertEqual(upas["obj_ref2"], test_result_upa)
        self.assertEqual(upas["obj_refs"], [test_result_upa] * 2)
        self.assertEqual(len(upas.keys()), 8)

    @mock.patch("biokbase.narrative.widgetmanager.clients.get",
                get_mock_client)
    def test_infer_upas_none(self):
        """
        Test infer_upas when no upas are given. Should return an empty dict.
        """
        upas = self.wm.infer_upas(
            "testCrazyExample",
            {
                "some_param": "some_value",
                "another_param": "another_value"
            },
        )
        self.assertIsInstance(upas, dict)
        self.assertFalse(upas)

    @mock.patch("biokbase.narrative.widgetmanager.clients.get",
                get_mock_client)
    def test_infer_upas_simple_widget(self):
        """
        Test infer_upas against the "default" widget - i.e. params don't matter and UPAs don't matter.
        """
        upas = self.wm.infer_upas(
            "kbaseDefaultNarrativeOutput",
            {
                "some_param": "some_value",
                "another_param": "another_value",
                "obj_ref": "1/2/3",
                "ws_name": "some_workspace",
            },
        )
        self.assertIsInstance(upas, dict)
        self.assertFalse(upas)

    @mock.patch("biokbase.narrative.widgetmanager.clients.get",
                get_mock_client)
    def test_infer_upas_nulls(self):
        """
        Test infer_upas when None is passed to it as an object name. Fields with None
        as input should not map to an UPA.
        """
        test_result_upa = "18836/5/1"
        upas = self.wm.infer_upas(
            "testCrazyExample",
            {
                "obj_id1": None,
                "obj_id2": None,
                "obj_name1": "foo",
                "obj_name2": "bar/baz",
                "obj_names": ["a", "b", "c"],
                "obj_ref1": "1/2/3",
                "obj_ref2": "foo/bar",
                "obj_refs": ["7/8/9", "0/1/2"],
                "ws_name": "some_ws",
                "extra_param": "extra_value",
                "other_extra_param": 0,
            },
        )
        self.assertIsInstance(upas, dict)
        self.assertNotIn("obj_id1", upas)
        self.assertNotIn("obj_id2", upas)
        self.assertEqual(upas["obj_name1"], test_result_upa)
        self.assertEqual(upas["obj_name2"], test_result_upa)
        self.assertEqual(upas["obj_names"], [test_result_upa] * 3)
        self.assertEqual(upas["obj_ref1"], "1/2/3")
        self.assertEqual(upas["obj_ref2"], test_result_upa)
        self.assertEqual(upas["obj_refs"], [test_result_upa] * 2)

    @mock.patch("biokbase.narrative.widgetmanager.clients.get",
                get_mock_client)
    def test_missing_env_path(self):
        backup_dir = os.environ["NARRATIVE_DIR"]
        del os.environ["NARRATIVE_DIR"]
        test_wm = WidgetManager()
        self.assertIsInstance(test_wm.widget_param_map, dict)
        self.assertFalse(test_wm.widget_param_map)
        os.environ["NARRATIVE_DIR"] = backup_dir

    def assertIsValidCellCode(self, js_obj, data, type, widget, cellId, title):
        code_lines = js_obj.data.strip().split("\n")
        self.assertTrue(
            code_lines[0].strip().startswith("element.html(\"<div id='kb-vis"))
        self.assertEqual(
            code_lines[1].strip(),
            "require(['kbaseNarrativeOutputCell'], function(KBaseNarrativeOutputCell) {",
        )
        self.assertTrue(code_lines[2].strip().startswith(
            r"var w = new KBaseNarrativeOutputCell($('#kb-vis"))
class WidgetManagerTestCase(unittest.TestCase):
    @classmethod
    @mock.patch('biokbase.narrative.widgetmanager.SpecManager')
    def setUpClass(self, mock_sm):
        os.environ['KB_WORKSPACE_ID'] = '12345'  # That's the same workspace as my luggage!
        specs_list = read_json_file('data/specs.json')
        specs_dict = dict()
        for s in specs_list:
            specs_dict[s['info']['id']] = s
        mock_sm.return_value.app_specs = {'release': specs_dict, 'beta': specs_dict, 'dev': specs_dict}
        # mock_njs.return_value.list_methods_spec.return_value = read_narrative_file('data/specs.json')
        self.wm = WidgetManager()
        self.good_widget = "kbaseTabTable"
        self.bad_widget = "notAWidget"
        self.good_tag = "release"
        self.bad_tag = "notATag"

    def test_widgetmanager_reload(self):
        self.wm.load_widget_info(verbose=True)

    def test_widgetmanager_instantiated(self):
        self.assertIsInstance(self.wm, WidgetManager)

    def test_widget_inputs(self):
        self.wm.print_widget_inputs(self.good_widget)

    def test_widget_inputs_bad(self):
        with self.assertRaises(ValueError) as err:
            self.wm.print_widget_inputs(self.bad_widget)

    def test_widget_constants(self):
        constants = self.wm.get_widget_constants(self.good_widget)
        self.assertTrue('ws' in constants)

    def test_widget_constants_bad(self):
        with self.assertRaises(ValueError) as err:
            self.wm.get_widget_constants(self.bad_widget)

    def test_show_output_widget(self):
        self.assertIsInstance(self.wm.show_output_widget(self.good_widget, {'obj': 'TestObject'}), IPython.core.display.Javascript)

    def test_show_output_widget_bad(self):
        with self.assertRaises(ValueError) as err:
            self.wm.show_output_widget(self.bad_widget, {'bad': 'inputs'})

    def test_show_external_widget(self):
        widget = self.wm.show_external_widget('contigSet', 'My ContigSet View', {'objectRef': '6402/3/8'}, {})
        self.assertIsInstance(widget, IPython.core.display.Javascript)

    def test_show_external_widget_list(self):
        widget = self.wm.show_external_widget(['widgets', '0.1.0', 'genomeComparison'],
                                              'Genome Comparison Demo',
                                              {'objectRef': '6402/5/2'},
                                              {},
                                              auth_required=True)
        self.assertIsInstance(widget, IPython.core.display.Javascript)
Example #17
0
class WidgetManagerTestCase(unittest.TestCase):
    @classmethod
    def setUpClass(self):
        config = TestConfig()
        os.environ['KB_WORKSPACE_ID'] = '12345'  # That's the same workspace as my luggage!
        app_specs_list = config.load_json_file(config.get('specs', 'app_specs_file'))
        app_specs_dict = dict()
        for s in app_specs_list:
            app_specs_dict[s['info']['id']] = s
        self.wm = WidgetManager()
        self.good_widget = "kbaseTabTable"
        self.bad_widget = "notAWidget"
        self.good_tag = "release"
        self.bad_tag = "notATag"
        self.widget_with_consts = "kbaseContigSetView"

    def test_widgetmanager_reload(self):
        self.wm.load_widget_info(verbose=True)

    def test_widgetmanager_instantiated(self):
        self.assertIsInstance(self.wm, WidgetManager)

    def test_widget_inputs(self):
        self.wm.print_widget_inputs(self.good_widget)

    def test_widget_inputs_bad(self):
        with self.assertRaises(ValueError):
            self.wm.print_widget_inputs(self.bad_widget)

    def test_widget_constants(self):
        constants = self.wm.get_widget_constants(self.widget_with_consts)
        self.assertTrue('ws' in constants)

    def test_widget_constants_bad(self):
        with self.assertRaises(ValueError):
            self.wm.get_widget_constants(self.bad_widget)

    def test_show_output_widget(self):
        self.assertIsInstance(
            self.wm.show_output_widget(
                self.good_widget,
                {'obj': 'TestObject'},
                upas={'obj': '1/2/3'},
                check_widget=True
            ),
            IPython.core.display.Javascript
        )

    def test_show_output_widget_bad(self):
        with self.assertRaises(ValueError):
            self.wm.show_output_widget(
                self.bad_widget,
                {'bad': 'inputs'},
                upas={'bad': '1/2/3'},
                check_widget=True
            )

    def test_show_advanced_viewer_widget(self):
        title = "Widget Viewer"
        cell_id = "abcde"
        widget_name = "CustomOutputDemo"
        widget_js = self.wm.show_advanced_viewer_widget(
            widget_name,
            {
                "param1": "value1",
                "param2": "value2"
            },
            {
                "param1": "value1",
                "param2": "value2"
            },
            title=title,
            cell_id=cell_id,
            tag="dev",
            check_widget=True
        )
        self.assertIsInstance(
            widget_js,
            IPython.core.display.Javascript
        )
        widget_code = widget_js.data
        self.assertIn("widget: '{}'".format(widget_name), widget_code)
        self.assertIn("cellId: \"{}\"".format(cell_id), widget_code)
        self.assertIn("title: '{}'".format(title), widget_code)

    def test_show_advanced_viewer_widget_bad(self):
        with self.assertRaises(ValueError):
            self.wm.show_advanced_viewer_widget(
                self.bad_widget,
                {'bad': 'inputs'},
                {'bad': 'state'},
                check_widget=True
            )

    def test_show_external_widget(self):
        widget = self.wm.show_external_widget(
            'contigSet', 'My ContigSet View', {'objectRef': '6402/3/8'}, {}
        )
        self.assertIsInstance(widget, IPython.core.display.Javascript)

    def test_show_external_widget_list(self):
        widget = self.wm.show_external_widget(['widgets', '0.1.0', 'genomeComparison'],
                                              'Genome Comparison Demo',
                                              {'objectRef': '6402/5/2'},
                                              {},
                                              auth_required=True)
        self.assertIsInstance(widget, IPython.core.display.Javascript)

    @mock.patch('biokbase.narrative.widgetmanager.clients.get', get_mock_client)
    def test_show_data_cell(self):
        """
        Tests - should do the following:
            def show_data_widget(self, upa, title=None, cell_id=None, tag="release"):
        fail message with no upa
        fail message with malformed upa
        shouldn't care what title or cell_id are, but should test to make sure they wind up in
            output code properly
        fail if type spec'd app isn't present for some tag
        otherwise, succeed and produce JS code.

        test mocks.
        """
        js_obj = self.wm.show_data_widget("18836/5/1", "some title", "no_id")
        print(js_obj.data)
        self.assertIsValidCellCode(js_obj, {}, "viewer", "kbaseGenomeView", "no_id", "some title")

    @mock.patch('biokbase.narrative.widgetmanager.clients.get', get_mock_client)
    def test_infer_upas(self):
        test_result_upa = "18836/5/1"
        upas = self.wm.infer_upas("testCrazyExample", {
            "obj_id1": 1,
            "obj_id2": 2,
            "obj_name1": "foo",
            "obj_name2": "bar/baz",
            "obj_names": ["a", "b", "c"],
            "obj_ref1": "1/2/3",
            "obj_ref2": "foo/bar",
            "obj_refs": ["7/8/9", "0/1/2"],
            "ws_name": "some_ws",
            "extra_param": "extra_value",
            "other_extra_param": 0
        })
        self.assertEquals(upas['obj_id1'], test_result_upa)
        self.assertEquals(upas['obj_id2'], test_result_upa)
        self.assertEquals(upas['obj_name1'], test_result_upa)
        self.assertEquals(upas['obj_name2'], test_result_upa)
        self.assertEquals(upas['obj_names'], [test_result_upa]*3)
        self.assertEquals(upas['obj_ref1'], "1/2/3")
        self.assertEquals(upas['obj_ref2'], test_result_upa)
        self.assertEquals(upas['obj_refs'], [test_result_upa]*2)
        self.assertEquals(len(upas.keys()), 8)

    @mock.patch('biokbase.narrative.widgetmanager.clients.get', get_mock_client)
    def test_infer_upas_none(self):
        """
        Test infer_upas when no upas are given. Should return an empty dict.
        """
        upas = self.wm.infer_upas("testCrazyExample", {
            "some_param": "some_value",
            "another_param": "another_value"
        })
        self.assertIsInstance(upas, dict)
        self.assertFalse(upas)

    @mock.patch('biokbase.narrative.widgetmanager.clients.get', get_mock_client)
    def test_infer_upas_simple_widget(self):
        """
        Test infer_upas against the "default" widget - i.e. params don't matter and UPAs don't matter.
        """
        upas = self.wm.infer_upas("kbaseDefaultNarrativeOutput", {
            "some_param": "some_value",
            "another_param": "another_value",
            "obj_ref": "1/2/3",
            "ws_name": "some_workspace"
        })
        self.assertIsInstance(upas, dict)
        self.assertFalse(upas)

    @mock.patch('biokbase.narrative.widgetmanager.clients.get', get_mock_client)
    def test_missing_env_path(self):
        backup_dir = os.environ["NARRATIVE_DIR"]
        del os.environ["NARRATIVE_DIR"]
        test_wm = WidgetManager()
        self.assertIsInstance(test_wm.widget_param_map, dict)
        self.assertFalse(test_wm.widget_param_map)
        os.environ["NARRATIVE_DIR"] = backup_dir

    def assertIsValidCellCode(self, js_obj, data, type, widget, cellId, title):
        code_lines = js_obj.data.strip().split('\n')
        self.assertTrue(code_lines[0].strip().startswith('element.html("<div id=\'kb-vis'))
        self.assertEquals(code_lines[1].strip(), "require(['kbaseNarrativeOutputCell'], function(KBaseNarrativeOutputCell) {")
        self.assertTrue(code_lines[2].strip().startswith(r"var w = new KBaseNarrativeOutputCell($('#kb-vis"))
Example #18
0
    def run_local_app(
        self,
        app_id,
        params,
        tag="release",
        version=None,
        cell_id=None,
        run_id=None,
        widget_state=None,
    ):
        """
        Attempts to run a local app. These do not return a Job object, but just
        the result of the app. In most cases, this will be a Javascript display
        of the result, but could be anything.

        If the app_spec looks like it makes a service call, then this raises a
        ValueError. Otherwise, it validates each parameter in **kwargs against
        the app spec, executes it, and returns the result.

        Parameters:
        -----------
        app_id - should be from the app spec, e.g. 'view_expression_profile'
        params - the dictionary of parameters for the app. Should be key-value
                 pairs where they keys are strings. If any non-optional
                 parameters are missing, an informative string will be printed.
        tag - optional, one of [release|beta|dev] (default=release)
        version - optional, a semantic version string. Only released modules
                  have versions, so if the tag is not 'release', and a version
                  is given, a ValueError will be raised.

        Example:
        run_local_app('NarrativeViewers/view_expression_profile',
                      {
                          "input_expression_matrix": "MyMatrix",
                          "input_gene_ids": "1234"
                      },
                      version='0.0.1',
                      input_expression_matrix="MyMatrix")
        """
        spec = self._get_validated_app_spec(app_id, tag, False, version=version)

        # Here, we just deal with two behaviors:
        # 1. None of the above - it's a viewer.
        # 2. ***TODO*** python_class / python_function.
        #    Import and exec the python code.

        # for now, just map the inputs to outputs.
        # First, validate.
        # Preflight check the params - all required ones are present, all
        # values are the right type, all numerical values are in given ranges
        spec_params = self.spec_manager.app_params(spec)
        (params, ws_refs) = validate_parameters(app_id, tag, spec_params, params)

        # Log that we're trying to run a job...
        log_info = {
            "app_id": app_id,
            "tag": tag,
            "username": system_variable("user_id"),
            "ws": system_variable("workspace"),
        }
        kblogging.log_event(self._log, "run_local_app", log_info)

        self._send_comm_message(
            MESSAGE_TYPE["RUN_STATUS"],
            {
                "event": "success",
                "event_at": timestamp(),
                "cell_id": cell_id,
                "run_id": run_id,
            },
        )

        (output_widget, widget_params) = map_outputs_from_state([], params, spec)

        # All a local app does is route the inputs to outputs through the
        # spec's mapping, and then feed that into the specified output widget.
        wm = WidgetManager()
        if widget_state is not None:
            return wm.show_advanced_viewer_widget(
                output_widget, widget_params, widget_state, cell_id=cell_id, tag=tag
            )
        else:
            return wm.show_output_widget(
                output_widget, widget_params, cell_id=cell_id, tag=tag
            )