Skip to content

Instantly share code, notes, and snippets.

@iandanforth
Last active February 15, 2024 17:23
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save iandanforth/1c6d0153d03e0caa771d5c92f2f7ec7e to your computer and use it in GitHub Desktop.
Save iandanforth/1c6d0153d03e0caa771d5c92f2f7ec7e to your computer and use it in GitHub Desktop.
How to serve local JavaScript to a hosted Jupyter notebook

Local JavaScript -> Hosted Jupyter notebook

Description

If you have:

  • A hosted Jupyter notebook (e.g. on Google Colaboratory)
  • A local JavaScript development environment you prefer to use

You can:

  • Serve the scripts from your local filesystem using SimpleHTTPServer + Ngrok
  • See updated behavior immediately after saving locally and re-running the cell
  • Re-use scripts across cells safely

Example script sun.js is served from localhost through ngrok to Google Colaboratory notebook

Steps

1. Create a directory to test this process

mkdir servejs; cd servejs

2. Write a script you want to serve

// Save to a file called main.js

// This is an IIFE
// See https://stackoverflow.com/q/8228281
(function() {
    console.log("Hello world!");
})();

3. Run a file server in servejs/ with cacheing disabled

Save this to a file named serve.py in servejs/

#!/usr/bin/env python
# From https://stackoverflow.com/a/25708957
import SimpleHTTPServer

class MyHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    def end_headers(self):
        self.send_my_headers()
        SimpleHTTPServer.SimpleHTTPRequestHandler.end_headers(self)

    def send_my_headers(self):
        self.send_header("Cache-Control", "no-cache, no-store, must-revalidate")
        self.send_header("Pragma", "no-cache")
        self.send_header("Expires", "0")


if __name__ == '__main__':
    SimpleHTTPServer.test(HandlerClass=MyHTTPRequestHandler)

then run

python serve.py

This will run a python SimpleHTTPServer with cacheing disabled. By default it will be running at localhost:8000. If you want to run the server on a different port, say 8080, you can do so like this

python serve.py 8080

NOTE: There are many alternatives for running a local webserver. Some come bundled with JS build tools.

4. Install and run ngrok

This cross-platform tool-and-service makes your locally run web server accessible from the public internet. It is safer than opening your computer directly to the internet but can still be a security risk so don't leave it running forever. Also, as it's a free service, you shouldn't abuse it!

Ngrok Download Page (Follow download and install instructions for your system)

Open a new terminal tab and, assuming you used the default port (8000) for the serve.py script, run:

ngrok http 8000

This will display the status of the running service. You care about the line that looks like this:

Forwarding                    https://da621616.ngrok.io -> localhost:8000       

Copy this ngrok url. The https part is important so copy that URL, not the one which starts http.

NOTE: You'll need to keep this tab open and ngrok running for as long as you need the file to be accessible. If you stop ngrok and restart it you will be issued a new url and will will have to update the src in your Jupyter cell or cells.

5. Verify all is working to this point

In a browser navigate to

https://<ngrok-url>/main.js

You should see the contents of your main.js

6. Tie this in with your Jupyter notebook

import IPython
display(IPython.core.display.HTML('''
<script src="https://<ngrok-url>/main.js"></script>
'''))

When you run this cell you should see "Hello world!" in the JavaScript console.

On Ubuntu/Chrome this can be opened through the Tools -> JavaScript Console menu option. (Shortcut shift+ctrl+j)

7. Continue development!

You should be able to save your local script and re-run the cell to have it update. If you're familiar with web build tools such as Brunch or Webpack you can serve the bundled output file and have access to the full range of increadible JS libraries like leftpad.

More Permanent Solutions

As you solidify the scripts you want to include in your notebook you probably don't want to have to serve them from localhost and keep ngrok running. There are a lot options for making script files available on the web, here are two that I've used for quick and dirty projects.

Happy Coding!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment