A Python module with JavaScript and related components

121 views
Skip to first unread message

Bruce Sherwood

unread,
Sep 11, 2016, 11:19:05 PM9/11/16
to Project Jupyter
I hope someone can provide guidance or point me to Jupyter documentation that I can't seem to find. For Jupyter VPython (vpython.org; github.com/BruceSherwood/vpython-jupyter), the Python module "vpython" includes a jquery library and the WebGL 3D graphics library from GlowScript VPython (glowscript.org).

There are "notebook.nbextensions.install_nbextension()" statements in the Python portion of the vpython module to load the JavaScript files, and the statement "display(Javascript("""require(["nbextensions/glowcomm"], function(){console.log("glowcomm loaded");})"""))", where glowcomm.js is a JavaScript program that calls the GlowScript graphics library. At the start of glowcomm.js is this:

define(["nbextensions/jquery-ui.custom.min","nbextensions/glow.2.1.min"], function() {
/*jslint plusplus: true */

I was unable to find any Jupyter documentation on this define operation -- perhaps it is related to requirejs?

As I described in a recent post, this structure has basically worked up till now, but I'm now unable to use the latest GlowScript library that has important new features, as the larger library often fails to load, as though size is an issue (the size limit seems to be about 500 MB, if that is indeed the problem). Moreover, I'm beginning to think that I'm not using the right architecture, and I've been unable to find any documentation that addresses my kind of application.

Specifically, nbextensions seem aimed at modifying the behavior of the notebook, and are apparently thought of as modules one installs that apply to all notebook operations. But in the vpython module the JavaScript files are an essential component of vpython, not an extension to alter notebook behavior. Moreover, the new GlowScript features I want to exploit include not only require a larger GlowScript library but also some data files used by this library, including font files used for producing 3D text, files that the GlowScript library expects to find in a neighboring folder, not the nbextensions folder.

Documentation on nbextensions seemed to imply that I could add a specfication of nbextensions_dir, so that I could make JavaScript file stay where it was rather than being copied to the standard nbextensions folder:

package_dir = os.path.dirname(__file__)
notebook.nbextensions.install_nbextension(path = package_dir+"/data/jquery-ui.custom.min.js",
            nbextensions_dir=package_dir+"/data/",
            overwrite = True,verbose = 0)

However, this gives the following error, despite the fact that the displayed file path and name is correct, and it removes the file (!), which I can't find anywhere (which is presumably due to it having been removed):

FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Anaconda3\\lib\\site-packages\\vpython/data/jquery-ui.custom.min.js'

I would be very grateful to be pointed to documentation I've missed, or to a project like mine in which JavaScript files and data files to be read by JavaScript can be used in place, in site-packages/vpython and its subfolders. Thanks.

Bruce Sherwood

unread,
Sep 12, 2016, 10:22:26 AM9/12/16
to Project Jupyter
I meant 500 KB, not 500 MB.

MinRK

unread,
Sep 13, 2016, 4:59:43 AM9/13/16
to Project Jupyter

On Mon, Sep 12, 2016 at 5:19 AM, Bruce Sherwood <bruce.s...@gmail.com> wrote:

I hope someone can provide guidance or point me to Jupyter documentation that I can't seem to find. For Jupyter VPython (vpython.org; github.com/BruceSherwood/vpython-jupyter), the Python module "vpython" includes a jquery library and the WebGL 3D graphics library from GlowScript VPython (glowscript.org).

There are "notebook.nbextensions.install_nbextension()" statements in the Python portion of the vpython module to load the JavaScript files, and the statement "display(Javascript("""require(["nbextensions/glowcomm"], function(){console.log("glowcomm loaded");})"""))", where glowcomm.js is a JavaScript program that calls the GlowScript graphics library. At the start of glowcomm.js is this:

define(["nbextensions/jquery-ui.custom.min","nbextensions/glow.2.1.min"], function() {
/*jslint plusplus: true */

I was unable to find any Jupyter documentation on this define operation -- perhaps it is related to requirejs?

Yes, define is part of AMD, and is a good way to define your extensions.


As I described in a recent post, this structure has basically worked up till now, but I'm now unable to use the latest GlowScript library that has important new features, as the larger library often fails to load, as though size is an issue (the size limit seems to be about 500 MB, if that is indeed the problem). Moreover, I'm beginning to think that I'm not using the right architecture, and I've been unable to find any documentation that addresses my kind of application.

If it’s failing to load sometimes, then it could be a race condition that your javascript is running before the extension has been loaded. The way to resolve things like this is to ensure that your javascript is in require blocks that load their dependencies before executing. That would mean that each of your Javascript displays include the require bit:

require(['nbextensions/glowcomm'], function (glowcomm) {
    do_something_with(glowcomm);
})


Specifically, nbextensions seem aimed at modifying the behavior of the notebook, and are apparently thought of as modules one installs that apply to all notebook operations. But in the vpython module the JavaScript files are an essential component of vpython, not an extension to alter notebook behavior. Moreover, the new GlowScript features I want to exploit include not only require a larger GlowScript library but also some data files used by this library, including font files used for producing 3D text, files that the GlowScript library expects to find in a neighboring folder, not the nbextensions folder.

If the browser should load the file directly, nbextensions is the right place for it. If it should be loaded by Python, putting it in the package makes sense. If it’s both, then perhaps a copy in each location is the right thing to do.


Documentation on nbextensions seemed to imply that I could add a specfication of nbextensions_dir, so that I could make JavaScript file stay where it was rather than being copied to the standard nbextensions folder:

package_dir = os.path.dirname(__file__)
notebook.nbextensions.install_nbextension(path = package_dir+"/data/jquery-ui.custom.min.js",
            nbextensions_dir=package_dir+"/data/",
            overwrite = True,verbose = 0)

nbextensions_dir is the destination for the files to be copied to (install_nbextension mainly amounts to a copy operation, like pip install or install). Installing to a custom location doesn’t mean that that custom location will be found for loading extensions. You can see the locations where Jupyter will look by checking jupyter --paths. The data-paths (+ nbextensions) are where nbextensions will be found. nbextensions_dir should be in one of these unless you are also relying on additional configuration to add a custom location to the server’s nbextension path.

-MinRK


However, this gives the following error, despite the fact that the displayed file path and name is correct, and it removes the file (!), which I can't find anywhere (which is presumably due to it having been removed):

FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Anaconda3\\lib\\site-packages\\vpython/data/jquery-ui.custom.min.js'

I would be very grateful to be pointed to documentation I've missed, or to a project like mine in which JavaScript files and data files to be read by JavaScript can be used in place, in site-packages/vpython and its subfolders. Thanks.

--
You received this message because you are subscribed to the Google Groups "Project Jupyter" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jupyter+unsubscribe@googlegroups.com.
To post to this group, send email to jup...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jupyter/891b5d00-721b-49dd-bde3-2ac25d877705%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Bruce Sherwood

unread,
Sep 13, 2016, 3:43:25 PM9/13/16
to Project Jupyter
That is helpful. Thanks.

I don't think I understand "The way to resolve things like this is to ensure that your javascript is in require blocks that load their dependencies before executing. That would mean that each of your Javascript displays include therequirebit:"  What is a "display" in this context? 

Bruce

Bruce Sherwood

unread,
Sep 13, 2016, 4:59:32 PM9/13/16
to Project Jupyter
Sorry. Now I realize that you were referring to the Jupyter "display" function.

Bruce Sherwood

unread,
Sep 16, 2016, 12:58:38 AM9/16/16
to Project Jupyter
It turned out that my problem was that two JavaScript libraries that I use, poly2tri.js and opentype.js, in their "built" form are somehow incompatible with the Jupyter requirejs environment. I made simpler versions of these libraries, based on the unbuilt source files, and they now work in the Jupyter notebook. So I was basically barking up the wrong tree. Sorry for inflicting the confusion on readers.

There remains a puzzle. My JavaScript code needs to read some data files (images and fonts). I've succeeded in copying them to nbextensions, but what is the path I need to use? The 404 missing file error message shows my attempt to read a data file that is a neighbor to the JavaScript file in nbextensions, using a relative address within nbextensions, indicates that it looked for


which is in the directory of my Python notebook,

instead of ../lib/FilesInAWS/Roboto-Medium.ttf

How should I reference a data file in nbextensions/lib?


Bruce Sherwood

unread,
Sep 16, 2016, 11:41:59 AM9/16/16
to Project Jupyter
I now realize that this is a more general issue, not really Jupyter-specific, about the complexities of reading files in JavaScript. Nevertheless, I would be interested to know how one addresses a location in nbextensions.

Bruce Sherwood

unread,
Sep 18, 2016, 12:44:10 AM9/18/16
to Project Jupyter
My colleague John Coady found a way to reference the location of nbextensions:

from IPython.display import Image
from jupyter_core.paths import jupyter_data_dir
Image(filename=jupyter_data_dir()+"/nbextensions/images.png")

Reply all
Reply to author
Forward
0 new messages