PAIR-code / what-if-tool

Source code/webpage/demos for the What-If Tool
https://pair-code.github.io/what-if-tool
Apache License 2.0
907 stars 169 forks source link

CSP problems in private env when loading the what-if tool #141

Closed Nithanaroy closed 3 years ago

Nithanaroy commented 3 years ago

Thanks a lot for building such a feature rich tool with easy to follow documentation. However I'm having problems accessing it inside my office private env. Facets overview when launched using tfdv.visualize_statistics(stats) works fine as they use srcdoc with inline HTML. I'm wondering if it is possible to load the what-if tool dashboard also using srcdoc of the iframe instead of src inside a jupyter notebook to avoid CSP problems?

jameswex commented 3 years ago

WIT used to use srcdoc, but was changed to use src in https://github.com/PAIR-code/what-if-tool/pull/30 so as to remove the use of elements to avoid breakage in Chrome version M80 and to enable it to work correctly in Firefox/Safari.

I don't know much about CSP but I'm wondering if there is a way to allow usage in your environment without changes deep inside WIT's notebook logic that would effect its usage elsewhere.

A fallback option for you would be to clone the repo, and undo the changes in that pull request, and build/install your own custom build of the WIT pip package.

Nithanaroy commented 3 years ago

Thanks for sharing the pull request @jameswex. Yup, I agree that we should add the URL to CSP header for a more long term fix. It however, might take a while. In the meantime to unblock myself, I tried 2 things.

Attempt 1

As the CSP error is due to frame-ancestors violation, I opened the iframe's src URL in a new tab and the widget loads fine. However, it doesn't have any data. Is it possible to inject the data as an inline proto tag like tfdv.visualize_statistics(stats) does?

Attempt 2

I edited the iframe HTML directly using Chrome Dev tools once it is added to the Jupyter notebook DOM. I changed the iframe's srcdoc to

<link rel='import' href='<some_abs_path>/nbextensions/wit-widget/wit_jupyter.html'> 
<wit-dashboard local id='wit'></wit-dashboard>
<script>    
    const wit = document.getElementById('wit'); 
    wit.style.height = '100px'; 
    wit.style.display = 'block';    
</script>

and the browser successfully pulled the wit_jupyter.html without any CSP errors. However, I see a blank white widget. I think this is due to after the fact modification. Are there any methods in WitWidget class or its base class that return the HTML so that I can modify the srcdoc before displaying as a widget.

jameswex commented 3 years ago

For attempt 1: It isn't possible to inject the data as an inline proto as the wit-dashboard element does a lot of communication with the python backend to do its processing (sending examples to infer, then receiving back inference results, for example). It isn't a single static blob that the tool displays.

For attempt 2: in the jupyter implementation, there isn't a python WitWidget method to get the HTML, but you can see what HTML is loaded, and what JS are called after that, here: https://github.com/PAIR-code/what-if-tool/blob/master/witwidget/notebook/jupyter/js/lib/wit.js#L49

Nithanaroy commented 3 years ago

Using the link you provided I tried to create a new MyWitWidget class inheriting from WitWidget, to see if I can modify the HTML either in the constructor or in the render() method. But as I'm new to ipywidgets ecosystems finding it a little tricky to achieve this. I have a hunch though and would like to get it validated by you. Could we update the iframe's srcdoc by adding a tiny custom JS script and append it like it is done in colab's case here?

jameswex commented 3 years ago

I'm not sure about that approach, as the ipywidget concept makes dealing with the front-end logic more complex and opaque.

I think the simplest approaches would be either: a) Revert the witwidget logic to as it was before PR #30, and build your own version of the witwidget package with that update. b) Try using WIT in standalone TensorBoard (https://pair-code.github.io/what-if-tool/learn/tutorials/tensorboard/) instead of through the jupyter notebook widget.

Nithanaroy commented 3 years ago

Thanks James. I'll try either of these :)