notebookjs icon indicating copy to clipboard operation
notebookjs copied to clipboard

Running with Thebelab

Open psychemedia opened this issue 6 years ago • 4 comments

Have you looked at providing additional support for ThebeLab within notebookjs so that a user could run the code in the page against a remote kernel of Binderhub launched kernel?

The following minor change seems to work.

In nb.Input.prototype.render, present the code as simply as possibly, in an appropriately configured <pre> tag (ThebeLab looks for code contained in a <pre data-executable="true" data-language="python"></pre> tag):

        var pre_el = makeElement("pre");
        pre_el.setAttribute("data-executable", "true");
        pre_el.setAttribute("data-language", lang); //lang is the desired kernel
        pre_el.innerHTML = joinText(this.raw);
        holder.appendChild(pre_el);

Add in some ThebeLab config information to the index.html page:

        <script type="text/x-thebe-config">
          {
            requestKernel: true,
            binderOptions: {
              repo: "binder-examples/requirements",
            },
          }
        </script>

Then crib from the ThebeLab docs to add a simple button to the top of the index.html page to enable the code for execution:

<script type="text/javascript" src="https://unpkg.com/thebelab@^0.4.0" ></script>
<div>
    <button id="activateButton"  style="width: 150px; height: 75px; font-size: 1.5em;">Activate</button>
    <script>
         var bootstrapThebe = function() {
            thebelab.bootstrap();
        }
        document.querySelector("#activateButton").addEventListener('click', bootstrapThebe)
    </script>
</div>

psychemedia avatar May 31 '19 13:05 psychemedia

Really interesting question @psychemedia, and thanks for raising it. I'm reluctant to add many third-party-specific features to notebook.js, for fear of long-term bloat and consequences. I would, however, like to make it as easy as possible for folks to customize and extend the core functionality. To that end:

  • The second two parts you mention seem to be straightforward for someone to customize, as they live outside the notebook element. No further action required, right? Or am I misunderstanding?

  • The first part would seem to require that notebookjs provide a sort of "hook" into the rendering process, whereby the developer could add a callback; in this case, the callback would allow the developer to execute those two "setAttribute" statements before the cell was rendered.

What do you think of this approach? Are there other approaches that would make extending notebookjs (for this purpose or others) easier / more intuitive?

jsvine avatar Jun 04 '19 12:06 jsvine

I've done a demo here that uses a modified notebook.js with a very simplistic approach to code rendering and a tweak to the nbpreview demo to add in a ThebeLab button.

The demo also has a minimal proof of concept for saving out the code from the uploaded page in case it is changed. (I figure if code cells are uniquely identified in the original notebook, we should be able to treat the original notebook as a template and update code cells with any modifications.) The inspiration for saving out was my wondering whether I could use nbpreview + thebelab as a UI for completing nbgrader assessments. (For more generality, the previewer would also have to support a text form for each 'submission' markdown cell which can be identified from notebook .ipynb cell metadata.)

I quite understand not wanting to overcomplicate notebookjs. I wonder if it could perhaps support some sort of really simple plugin or extension mechanism so that things like thebelab (or the use of other Binder support libraries such as juniper.js or nbinteract) could be easily added to an nbpreview page?

psychemedia avatar Jun 04 '19 12:06 psychemedia

Very neat, and many thanks for providing that demo/example. I think it does make sense to add some sort of plugin/extension mechanism. In your ideal world (not that I can promise to achieve it), what would the interaction/interface look like for a plugin-writer like yourself? What sort of API would you want exposed?

jsvine avatar Jun 07 '19 13:06 jsvine

I have no idea! (I'm an optimistic tinkerer rather than a developer who knows how to do things properly!) Will ponder it...

I'll also see if I can do another mockup using nbinteract and see if a natural way of supporting both nbinteract and Thebelab in a similar way falls out...

psychemedia avatar Jun 07 '19 15:06 psychemedia