Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Evaluate all script (grand)children of HTML output to render output of Bokeh and Plotly #138

Merged
merged 8 commits into from
Mar 8, 2024

Conversation

bartbroere
Copy link
Contributor

(As discussed on the Discord server) to render plotly in Starboard Notebook I was coming up with this kind of hack: manually evaluating Javascript that was added to the DOM:

document.querySelectorAll('div.cell-bottom * script[type|="text/javascript"]').forEach(function(e) { eval(e.innerText); })

This PR is intended to start the discussion on if and how we might want to address this in Starboard Notebook itself. Right now libraries, like Bokeh and Plotly will not work out of the box, which is unfortunate.

We should also consider security implications of a fix similar to this one. Of course it helps if CORS and friends are configured properly, but there might be more risks besides stealing (session) data from a user by having them execute malicious code.

Plotly example

import pandas  # to populate the entry in sys.modules and keep plotly happy
import micropip
await micropip.install('plotly')
import plotly.express as px
from js import document

x = [1, 2, 3]
y = [1, 2, 3]
fig = px.scatter(x=x, y=y)
html = fig.to_html(
    include_plotlyjs=True,
    full_html=False,
    default_height='350px',
)

div = document.createElement('div')
div.innerHTML = html
div
document.querySelectorAll('div.cell-bottom * script[type|="text/javascript"]').forEach(function(e) { eval(e.innerText); })

Bokeh example

from bokeh.plotting import figure, show, save
from bokeh.io import output_file
from js import document

p = figure()
p.line([1, 2, 3], [1, 2, 3])
output_file('/tmp/output.html', mode='inline')
save(p)

# TODO bokeh probably has a better way to get this HTML out
with open('/tmp/output.html', 'r') as f:
    contents = f.read()
div = document.createElement('div')
div.innerHTML = contents
div
document.querySelectorAll('div.cell-bottom * script[type|="text/javascript"]').forEach(function(e) { eval(e.innerText); })

@bartbroere bartbroere changed the title [WIP] Evaluate all script (grand)children of HTML output to render output of Bokeh and Plotly Evaluate all script (grand)children of HTML output to render output of Bokeh and Plotly Apr 11, 2023
Copy link
Owner

@gzuidhof gzuidhof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

I don't think it has security implications, the notebook should (always) be run in a sandbox (i.e. in an iframe), or one should trust the content if you want to embed it at the top level. Embedding at the top level (i.e. in the root page) is not really supported properly (and will require some cleanup/redesign, as now the CSS will surely clash, and perhaps some globals too).

@bartbroere
Copy link
Contributor Author

Looks good to me!

I don't think it has security implications, the notebook should (always) be run in a sandbox (i.e. in an iframe), or one should trust the content if you want to embed it at the top level. Embedding at the top level (i.e. in the root page) is not really supported properly (and will require some cleanup/redesign, as now the CSS will surely clash, and perhaps some globals too).

Good to hear!

@gzuidhof gzuidhof merged commit 327d7fa into gzuidhof:master Mar 8, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants