Skip to content

Commit a565541

Browse files
authored
colab: use proxyPort for dynamic plugin (#2798)
proxyPort is a relatively new API that lets colab proxy a server from a port to url given by the method. It installs a ServiceWorker when invoked so a request is proxied to the correct kernel. This API an iframe to be nestable and, hence, enable dynamic plugin With this change, we now removed the colab not supported page.
1 parent 1563a42 commit a565541

File tree

3 files changed

+22
-112
lines changed

3 files changed

+22
-112
lines changed

tensorboard/components/tf_tensorboard/tf-tensorboard.html

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -428,21 +428,6 @@ <h3>
428428
}
429429
}
430430
</style>
431-
<template id="colabNotSupported" preserve-content>
432-
<div style="max-width: 540px; margin: 80px auto 0 auto;">
433-
<h3>Dynamic plugin isn’t supported in Colab yet.</h3>
434-
<p>
435-
Please see
436-
<a
437-
href="https://github.com/tensorflow/tensorboard/issues/1913"
438-
rel="noopener"
439-
target="_blank"
440-
>GitHub issue #1913</a
441-
>
442-
for more information.
443-
</p>
444-
</div>
445-
</template>
446431
</template>
447432
<script src="autoReloadBehavior.js"></script>
448433
<script>
@@ -659,11 +644,6 @@ <h3>Dynamic plugin isn’t supported in Colab yet.</h3>
659644
type: Boolean,
660645
value: false,
661646
},
662-
_inColab: {
663-
type: Boolean,
664-
value: () => !!(window.TENSORBOARD_ENV || {}).IN_COLAB,
665-
readOnly: true,
666-
},
667647
},
668648
observers: [
669649
'_updateSelectedDashboardFromActive(' +
@@ -877,14 +857,6 @@ <h3>Dynamic plugin isn’t supported in Colab yet.</h3>
877857
},
878858

879859
_renderPluginIframe(container, selectedDashboard, loadingMechanism) {
880-
if (this._inColab) {
881-
const templateContent = this.$.colabNotSupported.content;
882-
const node = document.importNode(templateContent, true);
883-
node.id = 'dashboard'; // used in `_selectedDashboardComponent`
884-
this.scopeSubtree(node);
885-
container.appendChild(node);
886-
return;
887-
}
888860
const iframe = document.createElement('iframe');
889861
iframe.id = 'dashboard'; // used in `_selectedDashboardComponent`
890862
const srcUrl = new URL('data/plugin_entry.html', window.location.href);

tensorboard/notebook.py

Lines changed: 20 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -339,61 +339,28 @@ def _display_colab(port, height, display_handle):
339339
"""
340340
import IPython.display
341341
shell = """
342-
<div id="root"></div>
343-
<script>
344-
(function() {
345-
window.TENSORBOARD_ENV = window.TENSORBOARD_ENV || {};
346-
window.TENSORBOARD_ENV["IN_COLAB"] = true;
347-
document.querySelector("base").href = "https://localhost:%PORT%";
348-
function fixUpTensorboard(root) {
349-
const tftb = root.querySelector("tf-tensorboard");
350-
// Disable the fragment manipulation behavior in Colab. Not
351-
// only is the behavior not useful (as the iframe's location
352-
// is not visible to the user), it causes TensorBoard's usage
353-
// of `window.replace` to navigate away from the page and to
354-
// the `localhost:<port>` URL specified by the base URI, which
355-
// in turn causes the frame to (likely) crash.
356-
tftb.removeAttribute("use-hash");
357-
}
358-
function executeAllScripts(root) {
359-
// When `script` elements are inserted into the DOM by
360-
// assigning to an element's `innerHTML`, the scripts are not
361-
// executed. Thus, we manually re-insert these scripts so that
362-
// TensorBoard can initialize itself.
363-
for (const script of root.querySelectorAll("script")) {
364-
const newScript = document.createElement("script");
365-
newScript.type = script.type;
366-
newScript.textContent = script.textContent;
367-
root.appendChild(newScript);
368-
script.remove();
369-
}
370-
}
371-
function setHeight(root, height) {
372-
// We set the height dynamically after the TensorBoard UI has
373-
// been initialized. This avoids an intermediate state in
374-
// which the container plus the UI become taller than the
375-
// final width and cause the Colab output frame to be
376-
// permanently resized, eventually leading to an empty
377-
// vertical gap below the TensorBoard UI. It's not clear
378-
// exactly what causes this problematic intermediate state,
379-
// but setting the height late seems to fix it.
380-
root.style.height = `${height}px`;
381-
}
382-
const root = document.getElementById("root");
383-
fetch(".")
384-
.then((x) => x.text())
385-
.then((html) => void (root.innerHTML = html))
386-
.then(() => fixUpTensorboard(root))
387-
.then(() => executeAllScripts(root))
388-
.then(() => setHeight(root, %HEIGHT%));
389-
})();
390-
</script>
391-
""".replace("%PORT%", "%d" % port).replace("%HEIGHT%", "%d" % height)
392-
html = IPython.display.HTML(shell)
342+
(async () => {
343+
const url = await google.colab.kernel.proxyPort(%PORT%, {"cache": true});
344+
const iframe = document.createElement('iframe');
345+
iframe.src = url;
346+
iframe.setAttribute('width', '100%');
347+
iframe.setAttribute('height', '%HEIGHT%');
348+
iframe.setAttribute('frameborder', 0);
349+
document.body.appendChild(iframe);
350+
})();
351+
"""
352+
replacements = [
353+
("%PORT%", "%d" % port),
354+
("%HEIGHT%", "%d" % height),
355+
]
356+
for (k, v) in replacements:
357+
shell = shell.replace(k, v)
358+
script = IPython.display.Javascript(shell)
359+
393360
if display_handle:
394-
display_handle.update(html)
361+
display_handle.update(script)
395362
else:
396-
IPython.display.display(html)
363+
IPython.display.display(script)
397364

398365

399366
def _display_ipython(port, height, display_handle):

tensorboard/plugins/profile/tf_profile_dashboard/tf-profile-dashboard.html

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -49,21 +49,6 @@
4949

5050
<dom-module id="tf-profile-dashboard">
5151
<template>
52-
<template is="dom-if" if="[[_isState(_topLevelState, 'IN_COLAB')]]">
53-
<div style="max-width: 540px; margin: 80px auto 0 auto;">
54-
<h3>Profiling isn’t supported in Colab yet.</h3>
55-
<p>
56-
Please see
57-
<a
58-
href="https://github.com/tensorflow/tensorboard/issues/1913"
59-
rel="noopener"
60-
target="_blank"
61-
>GitHub issue #1913</a
62-
>
63-
for more information.
64-
</p>
65-
</div>
66-
</template>
6752
<paper-toast id="toast" duration="0" text="" always-on-top>
6853
<paper-button onclick="toast.toggle()" class="yellow-button"
6954
>Close now!</paper-button
@@ -462,13 +447,6 @@ <h3>No profile data was found.</h3>
462447
* @enum {string}
463448
*/
464449
const TopLevelState = {
465-
/**
466-
* Indicates that we are in a Colab notebook environment. The
467-
* profile dashboard does not work well in Colab; the trace viewer
468-
* does not work at all. If in Colab, we'll show only an explanatory
469-
* message.
470-
*/
471-
IN_COLAB: 'IN_COLAB',
472450
/**
473451
* Indicates that there are no runs with profile data.
474452
*/
@@ -514,16 +492,10 @@ <h3>No profile data was found.</h3>
514492
type: Array,
515493
observer: '_activeHostsChanged',
516494
},
517-
_inColab: {
518-
type: Boolean,
519-
value: () => !!(window.TENSORBOARD_ENV || {}).IN_COLAB,
520-
readOnly: true,
521-
},
522495
/** @type {TopLevelState} */
523496
_topLevelState: {
524497
type: String,
525-
computed:
526-
'_computeTopLevelState(_inColab, _dataNotFound, progress)',
498+
computed: '_computeTopLevelState(_dataNotFound, progress)',
527499
readOnly: true,
528500
},
529501
/**
@@ -950,8 +922,7 @@ <h3>No profile data was found.</h3>
950922
// Otherwise, remove the seperator, e.g. "host1_" => "host1".
951923
return host.slice(0, -1);
952924
},
953-
_computeTopLevelState: function(inColab, dataNotFound, progress) {
954-
if (inColab) return 'IN_COLAB';
925+
_computeTopLevelState: function(dataNotFound, progress) {
955926
if (dataNotFound) return 'DATA_NOT_FOUND';
956927
if (!progress || progress.value < 100) return 'LOADING';
957928
return 'ACTIVE';

0 commit comments

Comments
 (0)