posit-dev / positron

Positron, a next-generation data science IDE
https://positron.posit.co
Other
2.85k stars 91 forks source link

Support script tags and events in static HTML returned from kernels #1217

Open jmcphers opened 1 year ago

jmcphers commented 1 year ago

To reproduce, run this Python code (originally from #970):

import pandas as pd
import numpy as np
from pathlib import Path
from fastai.tabular.all import add_datepart, cont_cat_split, Categorify, FillMissing, TabularPandas
from fastbook import draw_tree
from sklearn.tree import DecisionTreeRegressor

df = pd.read_csv("TrainAndValid.csv", low_memory=False)
sizes = ['Large', 'Large / Medium', 'Medium', 'Small', 'Mini', 'Compact']
df['ProductSize'] = df['ProductSize'].astype('category')
df['ProductSize'].cat.set_categories(sizes, ordered = True, inplace = True)
dep_var = 'SalePrice'
df[dep_var] = np.log(df[dep_var])
df = add_datepart(df, 'saledate')
df_test = pd.read_csv('Test.csv', low_memory=False)
df_test = add_datepart(df_test, 'saledate')

procs = [Categorify, FillMissing]
cond = (df.saleYear<2011) | (df.saleMonth<10)
train_idx = np.where(cond)[0]
valid_idx = np.where(~cond)[0]
splits = (list(train_idx),list(valid_idx))
cont, cat = cont_cat_split(df, 1, dep_var=dep_var)
to = TabularPandas(df, procs, cat, cont, y_names=dep_var, splits=splits)

xs,y = to.train.xs,to.train.y
valid_xs,valid_y = to.valid.xs,to.valid.y
m = DecisionTreeRegressor(max_leaf_nodes=4)
m.fit(xs, y)

The result is a widget that looks clickable but doesn't do anything when clicked.

image

The reason this happens is that the HTML returned from the kernel (as a text/html result) contains JavaScript to make the widget interactive. However, we intentionally strip script content from kernel results because we load it right into the root DOM, and it's unsafe to load arbitrary content there.

This is also a problem for Plotly, etc. Read a longer discussion of the issue here: https://github.com/posit-dev/positron/issues/928.

To address this, we need a way to safely load HTML output -- including output containing scripts -- from kernels into Positron. Some considerations:

Related: https://github.com/posit-dev/positron/issues/444 tracks the work to emit R HTML widgets. These, too, can bear scripted content and will likely be emitted as text/html results when that issue has been addressed.

jmcphers commented 10 months ago

the console would have to become its own webview.

Remarkably we've learned recently that this is not true! The console could keep on rendering with React and we could stick a webview behind it to render unsafe content. That's how VS Code's notebooks work.