def createPlugin(self, logdir): multiplexer = event_multiplexer.EventMultiplexer() multiplexer.AddRunsFromDirectory(logdir) multiplexer.Reload() provider = data_provider.MultiplexerDataProvider(multiplexer, logdir) plugin_name_to_instance = {} context = base_plugin.TBContext( logdir=logdir, multiplexer=multiplexer, data_provider=provider, plugin_name_to_instance=plugin_name_to_instance, ) scalars_plugin_instance = scalars_plugin.ScalarsPlugin(context) custom_scalars_plugin_instance = ( custom_scalars_plugin.CustomScalarsPlugin(context) ) plugin_instances = [ scalars_plugin_instance, custom_scalars_plugin_instance, ] for plugin_instance in plugin_instances: plugin_name_to_instance[ plugin_instance.plugin_name ] = plugin_instance return custom_scalars_plugin_instance
def TensorBoardWSGIApp( flags, plugins, data_provider=None, assets_zip_provider=None, deprecated_multiplexer=None, ): """Constructs a TensorBoard WSGI app from plugins and data providers. Args: flags: An argparse.Namespace containing TensorBoard CLI flags. plugins: A list of plugin loader instances. assets_zip_provider: See TBContext documentation for more information. data_provider: Instance of `tensorboard.data.provider.DataProvider`. May be `None` if `flags.generic_data` is set to `"false"` in which case `deprecated_multiplexer` must be passed instead. deprecated_multiplexer: Optional `plugin_event_multiplexer.EventMultiplexer` to use for any plugins not yet enabled for the DataProvider API. Required if the data_provider argument is not passed. Returns: A WSGI application that implements the TensorBoard backend. :type plugins: list[base_plugin.TBLoader] """ plugin_name_to_instance = {} context = base_plugin.TBContext( data_provider=data_provider, flags=flags, logdir=flags.logdir, multiplexer=deprecated_multiplexer, assets_zip_provider=assets_zip_provider, plugin_name_to_instance=plugin_name_to_instance, sampling_hints=_parse_samples_per_plugin(flags), window_title=flags.window_title, ) tbplugins = [] experimental_plugins = [] for plugin_spec in plugins: loader = make_plugin_loader(plugin_spec) try: plugin = loader.load(context) except Exception: logger.error( "Failed to load plugin %s; ignoring it.", getattr(loader.load, "__qualname__", loader.load), exc_info=True, ) plugin = None if plugin is None: continue tbplugins.append(plugin) if isinstance( loader, experimental_plugin.ExperimentalPlugin ) or isinstance(plugin, experimental_plugin.ExperimentalPlugin): experimental_plugins.append(plugin.plugin_name) plugin_name_to_instance[plugin.plugin_name] = plugin return TensorBoardWSGI( tbplugins, flags.path_prefix, data_provider, experimental_plugins )
def setUp(self): self._mock_tb_context = base_plugin.TBContext() # TODO(#3425): Remove mocking or switch to mocking data provider # APIs directly. self._mock_multiplexer = mock.create_autospec( plugin_event_multiplexer.EventMultiplexer ) self._mock_tb_context.multiplexer = self._mock_multiplexer self._mock_multiplexer.PluginRunToTagToContent.side_effect = ( self._mock_plugin_run_to_tag_to_content ) self._mock_multiplexer.AllSummaryMetadata.side_effect = ( self._mock_all_summary_metadata ) self._mock_multiplexer.SummaryMetadata.side_effect = ( self._mock_summary_metadata ) self._mock_tb_context.data_provider = ( data_provider.MultiplexerDataProvider( self._mock_multiplexer, "/path/to/logs" ) ) self.session_1_start_info_ = "" self.session_2_start_info_ = "" self.session_3_start_info_ = ""
def setUp(self): super(PluginTest, self).setUp() # Log dir to save temp events into. self._log_dir = self.get_temp_dir() self._eval_result_output_dir = os.path.join(self.get_temp_dir(), "eval_result") if not os.path.isdir(self._eval_result_output_dir): os.mkdir(self._eval_result_output_dir) writer = tf.summary.create_file_writer(self._log_dir) with writer.as_default(): summary_v2.FairnessIndicators(self._eval_result_output_dir, step=1) writer.close() # Start a server that will receive requests. self._multiplexer = event_multiplexer.EventMultiplexer({ ".": self._log_dir, }) self._context = base_plugin.TBContext( logdir=self._log_dir, multiplexer=self._multiplexer) self._plugin = plugin.FairnessIndicatorsPlugin(self._context) self._multiplexer.Reload() wsgi_app = application.TensorBoardWSGI([self._plugin]) self._server = werkzeug_test.Client(wsgi_app, wrappers.BaseResponse) self._routes = self._plugin.get_plugin_apps()
def testGetEnvironmentDataWithExperimentMetadata(self): """Test environment route returns correct metadata about experiment.""" class FakeDataProvider(object): def data_location(self, ctx, *, experiment_id): del experiment_id # Unused. return "" def experiment_metadata(self, ctx, *, experiment_id): del experiment_id # Unused. return provider.ExperimentMetadata( experiment_name="Experiment #5 (実験#5)", experiment_description="Take five (😊)", creation_time=1234.5, ) self.context = base_plugin.TBContext( flags=FakeFlags(generic_data="true"), data_provider=FakeDataProvider(), ) self.plugin = core_plugin.CorePlugin(self.context) app = application.TensorBoardWSGI([self.plugin]) self.server = werkzeug_test.Client(app, wrappers.BaseResponse) parsed_object = self._get_json(self.server, "/data/environment") self.assertEqual(parsed_object["data_location"], "") self.assertEqual(parsed_object["window_title"], None) self.assertEqual( parsed_object["experiment_name"], "Experiment #5 (実験#5)" ) self.assertEqual( parsed_object["experiment_description"], "Take five (😊)" ) self.assertEqual(parsed_object["creation_time"], 1234.5)
def testGetEnvironmentDataWithNoExperimentMetadata(self): """Test environment route works when no experiment metadata exists.""" class FakeDataProvider(object): def data_location(self, ctx, *, experiment_id): del experiment_id # Unused. return "" def experiment_metadata(self, ctx, *, experiment_id): del experiment_id # Unused. return None self.context = base_plugin.TBContext( flags=FakeFlags(generic_data="true"), data_provider=FakeDataProvider(), ) self.plugin = core_plugin.CorePlugin(self.context) app = application.TensorBoardWSGI([self.plugin]) self.server = werkzeug_test.Client(app, wrappers.BaseResponse) parsed_object = self._get_json(self.server, "/data/environment") self.assertEqual(parsed_object["data_location"], "") self.assertEqual(parsed_object["window_title"], None) self.assertNotIn("experiment_name", parsed_object) self.assertNotIn("experiment_description", parsed_object) self.assertNotIn("creation_time", parsed_object)
def test_does_not_load_when_dynamic_plugin_present(self): with contextlib.ExitStack() as stack: stack.enter_context(mock.patch.dict(sys.modules)) sys.modules.pop(_DYNAMIC_PLUGIN_MODULE, None) real_import = __import__ def fake_import(name, *args, **kwargs): if name == _DYNAMIC_PLUGIN_MODULE: arbitrary_module = sys sys.modules.setdefault( _DYNAMIC_PLUGIN_MODULE, arbitrary_module ) return arbitrary_module else: return real_import(name, *args, **kwargs) stack.enter_context(mock.patch("builtins.__import__", fake_import)) plugin_class = profile_redirect_plugin._ProfileRedirectPlugin plugin_init = stack.enter_context( mock.patch.object(plugin_class, "__init__", return_value=None) ) loader = profile_redirect_plugin.ProfileRedirectPluginLoader() context = base_plugin.TBContext() result = loader.load(context) self.assertIsNone(result) plugin_init.assert_not_called()
def test_loads_when_no_dynamic_plugin(self): with contextlib.ExitStack() as stack: stack.enter_context(mock.patch.dict(sys.modules)) sys.modules.pop(_DYNAMIC_PLUGIN_MODULE, None) real_import = __import__ def fake_import(name, *args, **kwargs): if name == _DYNAMIC_PLUGIN_MODULE: raise ImportError("Pretend I'm not here") else: return real_import(name, *args, **kwargs) stack.enter_context(mock.patch("builtins.__import__", fake_import)) plugin_class = profile_redirect_plugin._ProfileRedirectPlugin plugin_init = stack.enter_context( mock.patch.object(plugin_class, "__init__", return_value=None) ) loader = profile_redirect_plugin.ProfileRedirectPluginLoader() context = base_plugin.TBContext() result = loader.load(context) self.assertIsInstance(result, plugin_class) plugin_init.assert_called_once_with(context)
def testPlugins_invalidType(self): plugin_instance = core_plugin.CorePlugin(base_plugin.TBContext()) with self.assertRaisesRegex(TypeError, "CorePlugin"): tb = program.TensorBoard( plugins=[plugin_instance], assets_zip_provider=fake_asset_provider, )
def standard_tensorboard_wsgi(logdir, purge_orphaned_data, reload_interval, plugins, db_uri="", assets_zip_provider=None): """Construct a TensorBoardWSGIApp with standard plugins and multiplexer. Args: logdir: The path to the directory containing events files. purge_orphaned_data: Whether to purge orphaned data. reload_interval: The interval at which the backend reloads more data in seconds. plugins: A list of constructor functions for TBPlugin subclasses. db_uri: A String containing the URI of the SQL database for persisting data, or empty for memory-only mode. assets_zip_provider: Delegates to TBContext or uses default if None. Returns: The new TensorBoard WSGI application. """ multiplexer = event_multiplexer.EventMultiplexer( size_guidance=DEFAULT_SIZE_GUIDANCE, purge_orphaned_data=purge_orphaned_data) db_module, db_connection_provider = get_database_info(db_uri) context = base_plugin.TBContext( db_module=db_module, db_connection_provider=db_connection_provider, logdir=logdir, multiplexer=multiplexer, assets_zip_provider=(assets_zip_provider or get_default_assets_zip_provider())) plugins = [constructor(context) for constructor in plugins] return TensorBoardWSGIApp(logdir, plugins, multiplexer, reload_interval)
def _SetupWSGIApp(self): multiplexer = event_multiplexer.EventMultiplexer() context = base_plugin.TBContext(logdir=self.log_dir, multiplexer=multiplexer) self.plugin = projector_plugin.ProjectorPlugin(context) wsgi_app = application.TensorBoardWSGI([self.plugin]) self.server = werkzeug_test.Client(wsgi_app, wrappers.BaseResponse)
def setUp(self): self.log_dir = tempfile.mkdtemp() # We use numpy.random to generate images. We seed to avoid non-determinism # in this test. numpy.random.seed(42) # Create old-style image summaries for run "foo". tf.reset_default_graph() sess = tf.Session() placeholder = tf.placeholder(tf.uint8) tf.summary.image(name="baz", tensor=placeholder) merged_summary_op = tf.summary.merge_all() foo_directory = os.path.join(self.log_dir, "foo") writer = tf.summary.FileWriter(foo_directory) writer.add_graph(sess.graph) for step in xrange(2): writer.add_summary(sess.run(merged_summary_op, feed_dict={ placeholder: (numpy.random.rand(1, 16, 42, 3) * 255).astype(numpy.uint8) }), global_step=step) writer.close() # Create new-style image summaries for run bar. tf.reset_default_graph() sess = tf.Session() placeholder = tf.placeholder(tf.uint8) summary.op(name="quux", images=placeholder, description="how do you pronounce that, anyway?") merged_summary_op = tf.summary.merge_all() bar_directory = os.path.join(self.log_dir, "bar") writer = tf.summary.FileWriter(bar_directory) writer.add_graph(sess.graph) for step in xrange(2): writer.add_summary(sess.run(merged_summary_op, feed_dict={ placeholder: (numpy.random.rand(1, 6, 8, 3) * 255).astype(numpy.uint8) }), global_step=step) writer.close() # Start a server with the plugin. multiplexer = event_multiplexer.EventMultiplexer({ "foo": foo_directory, "bar": bar_directory, }) context = base_plugin.TBContext(logdir=self.log_dir, multiplexer=multiplexer) plugin = images_plugin.ImagesPlugin(context) wsgi_app = application.TensorBoardWSGIApp(self.log_dir, [plugin], multiplexer, reload_interval=0) self.server = werkzeug_test.Client(wsgi_app, wrappers.BaseResponse) self.routes = plugin.get_plugin_apps()
def testPluginIsActiveWhenNoRuns(self): """The plugin should be inactive when there are no runs.""" multiplexer = event_multiplexer.EventMultiplexer() context = base_plugin.TBContext(logdir=self.logdir, multiplexer=multiplexer) plugin = text_plugin.TextPlugin(context) self.assertIsActive(plugin, False)
def setUp(self): self.logdir = self.get_temp_dir() self.generate_testdata() multiplexer = event_multiplexer.EventMultiplexer() multiplexer.AddRunsFromDirectory(self.logdir) multiplexer.Reload() context = base_plugin.TBContext(logdir=self.logdir, multiplexer=multiplexer) self.plugin = text_plugin.TextPlugin(context)
def is_path_safe(path): """Returns the result depending on the plugin's static file handler.""" example_plugin = plugin.ExampleRawScalarsPlugin(base_plugin.TBContext()) serve_static_file = example_plugin._serve_static_file client = test.Client(serve_static_file, wrappers.BaseResponse) response = client.get(plugin._PLUGIN_DIRECTORY_PATH_PART + path) return response.status_code == 200
def wrapper(self, *args, **kwargs): (logdir, multiplexer) = self.load_runs(run_specs) with self.subTest("bare multiplexer"): ctx = base_plugin.TBContext(logdir=logdir, multiplexer=multiplexer) fn(self, graphs_plugin.GraphsPlugin(ctx), *args, **kwargs) with self.subTest("generic data provider"): flags = argparse.Namespace(generic_data="true") provider = data_provider.MultiplexerDataProvider( multiplexer, logdir) ctx = base_plugin.TBContext( flags=flags, logdir=logdir, multiplexer=multiplexer, data_provider=provider, ) fn(self, graphs_plugin.GraphsPlugin(ctx), *args, **kwargs)
def _SetupWSGIApp(self): logdir = self.log_dir multiplexer = event_multiplexer.EventMultiplexer() provider = data_provider.MultiplexerDataProvider(multiplexer, logdir) context = base_plugin.TBContext(logdir=logdir, data_provider=provider) self.plugin = projector_plugin.ProjectorPlugin(context) wsgi_app = application.TensorBoardWSGI([self.plugin]) self.server = werkzeug_test.Client(wsgi_app, wrappers.Response)
def setUp(self): self.logdir = tf.compat.v1.test.get_temp_dir() self.context = base_plugin.TBContext(logdir=self.logdir) self.plugin = interactive_inference_plugin.InteractiveInferencePlugin( self.context) wsgi_app = application.TensorBoardWSGI([self.plugin]) self.server = werkzeug_test.Client(wsgi_app, wrappers.BaseResponse)
def testPluginIsActiveWhenTextRuns(self): """The plugin should be active when there are runs with text.""" multiplexer = event_multiplexer.EventMultiplexer() context = base_plugin.TBContext(logdir=None, multiplexer=multiplexer) plugin = text_plugin.TextPlugin(context) multiplexer.AddRunsFromDirectory(self.logdir) multiplexer.Reload() self.assertIsActive(plugin, True)
def testHealthPillsPluginIsInactive(self): plugin = debugger_plugin.DebuggerPlugin( base_plugin.TBContext( logdir=self.log_dir, multiplexer=event_multiplexer.EventMultiplexer({}))) plugin.listen(self.debugger_data_server_grpc_port) # The multiplexer lacks sampled health pills. self.assertFalse(plugin.is_active())
def setUp(self): self.logdir = self.get_temp_dir() self.multiplexer = event_multiplexer.EventMultiplexer() self.multiplexer.AddRunsFromDirectory(self.logdir) context = base_plugin.TBContext(logdir=self.logdir, multiplexer=self.multiplexer, flags=FakeFlags(self.logdir)) self.plugin = profile_plugin.ProfilePlugin(context) self.apps = self.plugin.get_plugin_apps()
def _SetupWSGIApp(self): multiplexer = event_multiplexer.EventMultiplexer( size_guidance=application.DEFAULT_SIZE_GUIDANCE, purge_orphaned_data=True) context = base_plugin.TBContext(logdir=self.log_dir, multiplexer=multiplexer) self.plugin = projector_plugin.ProjectorPlugin(context) wsgi_app = application.TensorBoardWSGI([self.plugin]) self.server = werkzeug_test.Client(wsgi_app, wrappers.BaseResponse)
def setUp(self): super().setUp() (logdir, multiplexer) = self._create_data() provider = data_provider.MultiplexerDataProvider(multiplexer, logdir) ctx = base_plugin.TBContext(logdir=logdir, data_provider=provider) plugin = images_plugin.ImagesPlugin(ctx) wsgi_app = application.TensorBoardWSGI([plugin]) self.server = werkzeug_test.Client(wsgi_app, wrappers.BaseResponse) self.routes = plugin.get_plugin_apps()
def load_plugin(self): self.generate_testdata() multiplexer = event_multiplexer.EventMultiplexer() multiplexer.AddRunsFromDirectory(self.logdir) multiplexer.Reload() provider = data_provider.MultiplexerDataProvider( multiplexer, self.logdir) ctx = base_plugin.TBContext(logdir=self.logdir, data_provider=provider) return text_plugin.TextPlugin(ctx)
def set_up_db(self): self.db_path = os.path.join(self.get_temp_dir(), "db.db") self.db_uri = "sqlite:" + self.db_path db_connection_provider = application.create_sqlite_connection_provider( self.db_uri) context = base_plugin.TBContext( db_connection_provider=db_connection_provider, db_uri=self.db_uri) self.core_plugin = core_plugin.CorePlugin(context) self.plugin = scalars_plugin.ScalarsPlugin(context)
def setUp(self): self.log_dir = tempfile.mkdtemp() # We use numpy.random to generate audio. We seed to avoid non-determinism # in this test. numpy.random.seed(42) # Create old-style audio summaries for run "foo". tf.reset_default_graph() sess = tf.Session() placeholder = tf.placeholder(tf.float32) tf.summary.audio(name="baz", tensor=placeholder, sample_rate=44100) merged_summary_op = tf.summary.merge_all() foo_directory = os.path.join(self.log_dir, "foo") writer = tf.summary.FileWriter(foo_directory) writer.add_graph(sess.graph) for step in xrange(2): # The floats (sample data) range from -1 to 1. writer.add_summary(sess.run(merged_summary_op, feed_dict={ placeholder: numpy.random.rand(42, 22050) * 2 - 1 }), global_step=step) writer.close() # Create new-style audio summaries for run "bar". tf.reset_default_graph() sess = tf.Session() audio_placeholder = tf.placeholder(tf.float32) labels_placeholder = tf.placeholder(tf.string) summary.op("quux", audio_placeholder, sample_rate=44100, labels=labels_placeholder, description="how do you pronounce that, anyway?") merged_summary_op = tf.summary.merge_all() bar_directory = os.path.join(self.log_dir, "bar") writer = tf.summary.FileWriter(bar_directory) writer.add_graph(sess.graph) for step in xrange(2): # The floats (sample data) range from -1 to 1. writer.add_summary(sess.run(merged_summary_op, feed_dict={ audio_placeholder: numpy.random.rand(42, 11025, 1) * 2 - 1, labels_placeholder: [ tf.compat.as_bytes('step **%s**, sample %s' % (step, sample)) for sample in xrange(42) ], }), global_step=step) writer.close() # Start a server with the plugin. multiplexer = event_multiplexer.EventMultiplexer({ "foo": foo_directory, "bar": bar_directory, }) context = base_plugin.TBContext( logdir=self.log_dir, multiplexer=multiplexer) self.plugin = audio_plugin.AudioPlugin(context) wsgi_app = application.TensorBoardWSGIApp( self.log_dir, [self.plugin], multiplexer, reload_interval=0) self.server = werkzeug_test.Client(wsgi_app, wrappers.BaseResponse)
def standard_tensorboard_wsgi( logdir, purge_orphaned_data, reload_interval, plugins, db_uri="", assets_zip_provider=None, path_prefix="", window_title="", flags=None): """Construct a TensorBoardWSGIApp with standard plugins and multiplexer. Args: logdir: The path to the directory containing events files. purge_orphaned_data: Whether to purge orphaned data. reload_interval: The interval at which the backend reloads more data in seconds. Zero means load once at startup; negative means never load. plugins: A list of constructor functions for TBPlugin subclasses. path_prefix: A prefix of the path when app isn't served from root. db_uri: A String containing the URI of the SQL database for persisting data, or empty for memory-only mode. assets_zip_provider: See TBContext documentation for more information. If this value is not specified, this function will attempt to load the `tensorboard.default` module to use the default. This behavior might be removed in the future. window_title: A string specifying the the window title. flags: A dict of the runtime flags provided to the application, or None. Returns: The new TensorBoard WSGI application. """ if assets_zip_provider is None: from tensorboard import default assets_zip_provider = default.get_assets_zip_provider() multiplexer = event_multiplexer.EventMultiplexer( size_guidance=DEFAULT_SIZE_GUIDANCE, tensor_size_guidance=DEFAULT_TENSOR_SIZE_GUIDANCE, purge_orphaned_data=purge_orphaned_data) db_module, db_connection_provider = get_database_info(db_uri) # In DB mode, always disable loading event files. if db_connection_provider: reload_interval = -1 plugin_name_to_instance = {} context = base_plugin.TBContext( db_module=db_module, db_connection_provider=db_connection_provider, db_uri=db_uri, flags=flags, logdir=logdir, multiplexer=multiplexer, assets_zip_provider=assets_zip_provider, plugin_name_to_instance=plugin_name_to_instance, window_title=window_title) plugin_instances = [constructor(context) for constructor in plugins] for plugin_instance in plugin_instances: plugin_name_to_instance[plugin_instance.plugin_name] = plugin_instance return TensorBoardWSGIApp( logdir, plugin_instances, multiplexer, reload_interval, path_prefix)
def set_up_with_runs(self, run_names): self.logdir = self.get_temp_dir() for run_name in run_names: self.generate_run(run_name) multiplexer = event_multiplexer.EventMultiplexer() multiplexer.AddRunsFromDirectory(self.logdir) multiplexer.Reload() context = base_plugin.TBContext(logdir=self.logdir, multiplexer=multiplexer) self.plugin = scalars_plugin.ScalarsPlugin(context)
def testPluginIsNotActive(self): """Tests that the plugin is inactive when no relevant data exists.""" empty_logdir = os.path.join(self.get_temp_dir(), "empty_logdir") multiplexer = event_multiplexer.EventMultiplexer() multiplexer.AddRunsFromDirectory(empty_logdir) multiplexer.Reload() context = base_plugin.TBContext(logdir=empty_logdir, multiplexer=multiplexer) plugin = pr_curves_plugin.PrCurvesPlugin(context) self.assertFalse(plugin.is_active())
def testPluginIsActiveWhenRunsButNoText(self): """The plugin should be inactive when there are runs but none has text.""" multiplexer = event_multiplexer.EventMultiplexer() context = base_plugin.TBContext(logdir=None, multiplexer=multiplexer) plugin = text_plugin.TextPlugin(context) logdir = os.path.join(self.get_temp_dir(), 'runs_with_no_text') self.generate_testdata(include_text=False, logdir=logdir) multiplexer.AddRunsFromDirectory(logdir) multiplexer.Reload() self.assertIsActive(plugin, False)