7

I am trying to serve some HTML from a Google Colab notebook using the following:

from IPython.display import IFrame

IFrame(src='./output/index.html', width=700, height=600)

However, this throws localhost refused to connect:

enter image description here

Does anyone know how I can serve the html in index.html (which must load javascript) inside the Colab notebook? Any pointers would be hugely appreciated!

duhaime
  • 25,611
  • 17
  • 169
  • 224

3 Answers3

1

You can serve content from the path /nbextensions/ which maps to /usr/local/share/jupyter/nbextensions.

So you can put content there.

!ln -s /usr/local/share/jupyter/nbextensions /nbextensions
%cd /nbextensions
!wget -q https://upload.wikimedia.org/wikipedia/commons/3/37/Youtube.svg

Then serve the image

%%html
<img src=/nbextensions/Youtube.svg>

I can't make it works with IFrame, thought. I don't know why.

Here's an example colab notebook.

korakot
  • 37,818
  • 16
  • 123
  • 144
0

This built-in example notebook gives a demo: https://colab.research.google.com/notebooks/snippets/advanced_outputs.ipynb#scrollTo=R8ZvCXC5A0wT

Reproducing the example here of serving content from the backend:

import portpicker
import threading
import socket
import IPython

from six.moves import socketserver
from six.moves import SimpleHTTPServer

class V6Server(socketserver.TCPServer):
  address_family = socket.AF_INET6

class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
  def do_GET(self):
    self.send_response(200)
    # If the response should not be cached in the notebook for
    # offline access:
    # self.send_header('x-colab-notebook-cache-control', 'no-cache')
    self.end_headers()
    self.wfile.write(b'''
      document.querySelector('#output-area').appendChild(document.createTextNode('Script result!'));
    ''')

port = portpicker.pick_unused_port()

def server_entry():
    httpd = V6Server(('::', port), Handler)
    # Handle a single request then exit the thread.
    httpd.serve_forever()

thread = threading.Thread(target=server_entry)
thread.start()

# Display some HTML referencing the resource.
display(IPython.display.HTML('<script src="https://localhost:{port}/"></script>'.format(port=port)))

enter image description here

Bob Smith
  • 36,107
  • 11
  • 98
  • 91
  • 2
    thanks for this. I confess I'm not sure how this is intended to be used to serve html that loads js resources--would I just read my html and pass it to the `IPython.display.HTML()` function? – duhaime Nov 29 '19 at 18:09
0

This works for me on Aug 2022:

First, as @korakot mentioned, if you have any javascript used in your html, please copy them into /usr/local/share/jupyter/nbextensions

e.g.

!cp -r ./output/ /usr/local/share/jupyter/nbextensions/google.colab/

use !ls /usr/local/share/jupyter/nbextensions/google.colab/ to check if file already exists

Then, instead of referring to html file by path, simple copy the html code in <body> into colab cell:

%%html
<!-- move your head part resources here -->
<script src="/nbextensions/google.colab/output/xxxx.js"></script>
<link type="text/css" href="/nbextensions/google.colab/outut/xxxx.css" rel="stylesheet" />

<!-- here is your body code -->
<div id="files"></div>
<div id="canvasArea" height="720px"></div>
...

<script>
   // set the cell height
   google.colab.output.setIframeHeight(document.documentElement.scrollHeight, true);
   // you can also log some testing code here, to check whether it works or not
   console.log("hello world");
   console.log(variables_in_your_js)
</script>

Run the cell to check whether works or not.

Howcanoe Wang
  • 133
  • 1
  • 8