24

As a part of a project, I need to embedd some javascripts inside an IPython module. This is what I want to do:

from IPython.display import display,Javascript
Javascript('echo("sdfds");',lib='/home/student/Gl.js')

My Gl.js looks like this

function echo(a){
alert(a);
}

Is there some way so that I can embed "Gl.js" and other such external scripts inside the notebook, such that I dont have to include them as 'lib' argument everytime I try to execute some Javascript code which requires to that library.

Tarun Gaba
  • 1,103
  • 1
  • 8
  • 16

7 Answers7

18

As a very short-term solution, you can make use of the IPython display() and HTML() functions to inject some JavaScript into the page.

from IPython.display import display, HTML
js = "<script>alert('Hello World!');</script>"
display(HTML(js))

Although I do not recommend this over the official custom.js method, I do sometimes find it useful to quickly test something or to dynamically generate a small JavaScript snippet.

Alex
  • 5,364
  • 9
  • 54
  • 69
10

Embedding D3 in an IPython Notebook

To summarize the code.

Import the script:

%%javascript
require.config({
  paths: {
      d3: '//cdnjs.cloudflare.com/ajax/libs/d3/3.4.8/d3.min'
  }
});

Add an element like this:

%%javascript
element.append("<div id='chart1'></div>");

Or this:

from IPython.display import Javascript
#runs arbitrary javascript, client-side
Javascript("""
           window.vizObj={};
           """.format(df.to_json()))

IPython Notebook: Javascript/Python Bi-directional Communication

A more extensive post explaining how to access Python variables in JavaScript and vice versa.

Anton Tarasenko
  • 8,099
  • 11
  • 66
  • 91
5

I've been fighting with this problem for several days now, here's something that looks like it works; buyer beware though, this is a minimal working solution and it's neither pretty nor optimal - a nicer solution would be very welcome!

First, in .ipython/<profile>/static/custom/myScript.js, we do some require.js magic:

define(function(){

    var foo = function(){
            console.log('bar');
        }

    return {
        foo : foo
    }
});

Copy this pattern for as many functions as you like. Then, in .ipython/<profile>/static/custom/custom.js, drag those out into something persistent:

$([IPython.events]).on('notebook_loaded.Notebook', function(){

    require(['custom/myScript'], function(custom){
        window.foo = custom.foo;
    } );

});

Yes, I am a horrible person for throwing stuff on the window object, namespace things as you deem appropriate. But now in the notebook, a cell like

%%javascript

foo();

should do exactly what it looks like it should, without the user having to explicitly import your JS. I would love to see a simpler solution for this (plz devs can we plz have $.getScript('/static/custom/util.js'); in custom.js to load up a bunch of global JS functions) - but this is the best I've got for now. This singing and dancing aside, HUGE ups to the IPython notebook team, this is an awesome platform!

Bill Mills
  • 411
  • 6
  • 16
4

Not out of the box by installing a package, at least for now. The way to do it is to use custom.js and jQuery getScript to inject the js into the notebook.

I explicitly stay vague on how to do it, as it is a dev feature changing from time to time.

What you should know is that the static folder in user profile is merged with webserver static assets allowing you to access any file that are in this folder by asking for the right url.

Also this question has been asked a few hours ago on IPython weekly video "lab meeting" broadcasted live and disponible on youtube (you might have a longer answer), I've opened discussion with the author of the question here

Matt
  • 27,170
  • 6
  • 80
  • 74
  • Where I need to store my script "Gl.js" for using getScript(). 'Javascript('''$.getScript("Gl.js");''')' It gives a 404 error – Tarun Gaba May 31 '13 at 09:36
  • Exact path and instruction depends on what version of IPython you are running. And that would be $.getScript("static/Gl.js") and `~/.ipython/profile_default/static/[custom]/GI.js`. I would suggest doing a search for `IPython custom.js`, ask/search on ml/hipchat, because I'm afraid stackoverflow will be a little too limiting to give you all the explanation necessary. – Matt May 31 '13 at 10:01
  • The problem is here that the explanation would be much too long, and subject to change, difficult to embed code...etc. We can discuss that on IPython ML or gihtub bugtracker, or on your repo if it is hosted anywhere with issue tracker. – Matt May 31 '13 at 11:54
  • Well I had a talk with my mentor on the same, and either he or myself would be posting on IPython ML ..small amount of research and itcomes out thatthis is one of the hot topics in the IPython dev – Tarun Gaba Jun 01 '13 at 14:41
  • @Matt has this changed? – Nick T Sep 26 '15 at 03:33
3

For some reason, I have problems with IPython.display.Javascript. Here is my alternative, which can handle both importing external .js files and running custom code:

from IPython.display import display, HTML

def javascript(*st,file=None):
    if len(st) == 1 and file is None:
        s = st[0]
    elif len(st) == 0 and file is not None:
        s = open(file).read()
    else:
        raise ValueError('Pass either a string or file=.')
    display(HTML("<script type='text/javascript'>" + s + "</script>"))

Usage is as follows:

javascript('alert("hi")')
javascript(file='Gl.js')
javascript('echo("sdfds")')
Ben Mares
  • 1,764
  • 1
  • 15
  • 26
0

You can use IJavascript (a Javascript kernel for Jupyter notebooks).

Saurabh Khanna
  • 531
  • 4
  • 4
0

I was interested in calling JavaScript from a Jupyter code (Python) cell to process strings, and have the processed string output in the (same) code cell output; thanks to Inject/execute JS code to IPython notebook and forbid its further execution on page reload and Why cannot python call Javascript() from within a python function? now I have this example:

from IPython.display import display, Javascript, Markdown as md, HTML

def js_convert_str_html(instring_str):
    js_convert = """
        <div id="_my_special_div"></div>
        <script>
        var myinputstring = '{0}';
        function do_convert_str_html(instr) {{
            return instr.toUpperCase();
        }}
        document.getElementById("_my_special_div").textContent = do_convert_str_html(myinputstring);
        </script>
    """.format(instring_str)
    return HTML(js_convert)

jsobj = js_convert_str_html("hello world")
display(jsobj)

Note that the JavaScript-processed string does not get returned to Python per se; rather, the JavaScript itself creates its own div, and adds the result of the string conversion to it.

sdbbs
  • 4,270
  • 5
  • 32
  • 87