--- lib/python3.10/site-packages/tensorboard/notebook.py.orig 2022-04-04 15:13:24.242666542 +0200 +++ lib/python3.10/site-packages/tensorboard/notebook.py 2022-04-04 15:22:16.791830780 +0200 @@ -34,6 +34,7 @@ # details). _CONTEXT_COLAB = "_CONTEXT_COLAB" _CONTEXT_IPYTHON = "_CONTEXT_IPYTHON" +_CONTEXT_JUPYTERHUB = "_CONTEXT_JUPYTERHUB" _CONTEXT_NONE = "_CONTEXT_NONE" @@ -70,11 +71,27 @@ else: ipython = IPython.get_ipython() if ipython is not None and ipython.has_trait("kernel"): + if os.environ.get("JUPYTERHUB_SERVICE_PREFIX") is not None: + return _CONTEXT_JUPYTERHUB return _CONTEXT_IPYTHON # Otherwise, we're not in a known notebook context. return _CONTEXT_NONE +def _prefix_jupyterhub(port): + prefix = os.path.join(os.environ["JUPYTERHUB_SERVICE_PREFIX"], 'proxy/absolute') + return "%s/%d/" % (prefix, port) + + +def _patch_args_jupyterhub(parsed_args): + if "--port" in parsed_args: + arg_idx = parsed_args.index("--port") + port = int(parsed_args[arg_idx+1]) + else: + port = 6006 + parsed_args += ["--port", str(port)] + return parsed_args + ["--path_prefix", _prefix_jupyterhub(port)] + def load_ipython_extension(ipython): """Deprecated: use `%load_ext tensorboard` instead. @@ -149,6 +166,9 @@ handle.update(IPython.display.Pretty(message)) parsed_args = shlex.split(args_string, comments=True, posix=True) + if context == _CONTEXT_JUPYTERHUB: + parsed_args = _patch_args_jupyterhub(parsed_args) + start_result = manager.start(parsed_args) if isinstance(start_result, manager.StartLaunched): @@ -305,6 +325,7 @@ fn = { _CONTEXT_COLAB: _display_colab, _CONTEXT_IPYTHON: _display_ipython, + _CONTEXT_JUPYTERHUB: _display_jupyterhub, _CONTEXT_NONE: _display_cli, }[_get_context()] return fn(port=port, height=height, display_handle=display_handle) @@ -401,6 +422,36 @@ for (k, v) in replacements: shell = shell.replace(k, v) iframe = IPython.display.HTML(shell) + if display_handle: + display_handle.update(iframe) + else: + IPython.display.display(iframe) + + +def _display_jupyterhub(port, height, display_handle): + import IPython.display + + frame_id = "tensorboard-frame-{:08x}".format(random.getrandbits(64)) + shell = """ + <iframe id="%HTML_ID%" width="100%" height="%HEIGHT%" frameborder="0"> + </iframe> + <script> + (function() { + const frame = document.getElementById(%JSON_ID%); + const url = new URL("%PREFIX%", window.location); + frame.src = url; + })(); + </script> + """ + replacements = [ + ("%HTML_ID%", html.escape(frame_id, quote=True)), + ("%JSON_ID%", json.dumps(frame_id)), + ("%PREFIX%", _prefix_jupyterhub(port)), + ("%HEIGHT%", "%d" % height), + ] + for (k, v) in replacements: + shell = shell.replace(k, v) + iframe = IPython.display.HTML(shell) if display_handle: display_handle.update(iframe) else: