Skip to content

Latest commit

 

History

History

stitch

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

stitch

Build Status codecov

Widget that handles bi-directional communication between user-defined JavaScript and the Jupyter kernel via a sandboxed iframe and postMessage.

It is very difficult to get kernel comms directly working across local and cloud environments without pushing users to install custom Jupyter widgets or extensions for each project. For restricted environments (corporate / medical) this isn't always achievable. stitch alleviates that by acting as general-purpose library where user-defined JavaScript can be rendered in Jupyter without the boilerplate.

Usage

Below is an example of a message being rendered in Jupyter passed from JavaScript and relayed back.

import stitch

w = stitch.StitchWidget()
w.srcdoc = """
<html>
<script>
// Ping 'kernelmsg' back to kernel as 'clientmsg'
window.addEventListener("message", function(event) {
  if (event.source === window.parent && event.data.type === "kernelmsg") {
    document.getElementById("msgview").innerHTML = event.data.content;
    window.parent.postMessage({type: "clientmsg", content: event.data.content}, "*");
  }
});

// Handle iframe resizing to fit content
window.addEventListener("load", function(){
  var prevHeight = 0;
  var prevWidth = 0;
  setInterval(function() {
    var body = document.body, html = document.documentElement;
    var height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
    var width = Math.max(body.scrollWidth, body.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth);
    if (height !== prevHeight || prevWidth !== width) {
      msg = {type: 'resize', content: {height: height + 'px', width: width + 'px'}};
      window.parent.postMessage(msg, "*");
      prevHeight = height;
      prevWidth = width;
    }
  }, 100);
});
</script>
<body>
<div style="white-space:nowrap">
MESSAGE: <span id="msgview"></span>
</div>
</body>
</html>
"""
w

Widget output

Send a kernel message to the client

# This will update all rendered widgets within Jupyter (including above)
w.kernelmsg = "Houston, we have a problem."
w

Widget output

Our example sends pings the kernel message back to client.

assert w.clientmsg == "Houston, we have a problem."

stitch uses a custom DOMWidget, so you can monitor changes too.

w.observe(lambda x: print(x['new']), 'kernelmsg')
w.kernelmsg = "Wow, a change!"

The StitchWidget used throughout has the following state:

  • srcdoc - HTML to be rendered (in a sandboxed iframe) as the frontend
  • kernelmsg - Message sent via Jupyter kernel
  • clientmsg - Message sent from frontend
  • initial_height - Initial height of the sandboxed iframe
  • initial_width - Initial width of the sandboxed iframe
  • initial_border - Initial border of the sandboxed iframe

Installation

You can install using pip:

pip install stitch

If you are using Jupyter Notebook 5.2 or earlier, you may also need to enable the nbextension:

jupyter nbextension enable --py [--sys-prefix|--user|--system] stitch