[python] How to embed HTML into IPython output?

Is it possible to embed rendered HTML output into IPython output?

One way is to use

from IPython.core.display import HTML
HTML('<a href="http://example.com">link</a>')

or (IPython multiline cell alias)

%%html
<a href="http://example.com">link</a>

Which return a formatted link, but

  1. This link doesn't open a browser with the webpage itself from the console. IPython notebooks support honest rendering, though.
  2. I'm unaware of how to render HTML() object within, say, a list or pandas printed table. You can do df.to_html(), but without making links inside cells.
  3. This output isn't interactive in the PyCharm Python console (because it's not QT).

How can I overcome these shortcomings and make IPython output a bit more interactive?

This question is related to python html ipython jupyter-notebook

The answer is


This seems to work for me:

from IPython.core.display import display, HTML
display(HTML('<h1>Hello, world!</h1>'))

The trick is to wrap it in "display" as well.

Source: http://python.6.x6.nabble.com/Printing-HTML-within-IPython-Notebook-IPython-specific-prettyprint-tp5016624p5016631.html


to do this in a loop, you can do:

display(HTML("".join([f"<a href='{url}'>{url}</a></br>" for url in urls])))

This essentially creates the html text in a loop, and then uses the display(HTML()) construct to display the whole string as HTML


Related: While constructing a class, def _repr_html_(self): ... can be used to create a custom HTML representation of its instances:

class Foo:
    def _repr_html_(self):
        return "Hello <b>World</b>!"

o = Foo()
o

will render as:

Hello World!

For more info refer to IPython's docs.

An advanced example:

from html import escape # Python 3 only :-)

class Todo:
    def __init__(self):
        self.items = []

    def add(self, text, completed):
        self.items.append({'text': text, 'completed': completed})

    def _repr_html_(self):
        return "<ol>{}</ol>".format("".join("<li>{} {}</li>".format(
            "?" if item['completed'] else "?",
            escape(item['text'])
        ) for item in self.items))

my_todo = Todo()
my_todo.add("Buy milk", False)
my_todo.add("Do homework", False)
my_todo.add("Play video games", True)

my_todo

Will render:

  1. ? Buy milk
  2. ? Do homework
  3. ? Play video games

Expanding on @Harmon above, looks like you can combine the display and print statements together ... if you need. Or, maybe it's easier to just format your entire HTML as one string and then use display. Either way, nice feature.

display(HTML('<h1>Hello, world!</h1>'))
print("Here's a link:")
display(HTML("<a href='http://www.google.com' target='_blank'>www.google.com</a>"))
print("some more printed text ...")
display(HTML('<p>Paragraph text here ...</p>'))

Outputs something like this:


Hello, world!

Here's a link:

www.google.com

some more printed text ...

Paragraph text here ...



Some time ago Jupyter Notebooks started stripping JavaScript from HTML content [#3118]. Here are two solutions:

Serving Local HTML

If you want to embed an HTML page with JavaScript on your page now, the easiest thing to do is to save your HTML file to the directory with your notebook and then load the HTML as follows:

from IPython.display import IFrame

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

Serving Remote HTML

If you prefer a hosted solution, you can upload your HTML page to an Amazon Web Services "bucket" in S3, change the settings on that bucket so as to make the bucket host a static website, then use an Iframe component in your notebook:

from IPython.display import IFrame

IFrame(src='https://s3.amazonaws.com/duhaime/blog/visualizations/isolation-forests.html', width=700, height=600)

This will render your HTML content and JavaScript in an iframe, just like you can on any other web page:

_x000D_
_x000D_
<iframe src='https://s3.amazonaws.com/duhaime/blog/visualizations/isolation-forests.html', width=700, height=600></iframe>
_x000D_
_x000D_
_x000D_


First, the code:

from random import choices

def random_name(length=6):
    return "".join(choices("abcdefghijklmnopqrstuvwxyz", k=length))
# ---

from IPython.display import IFrame, display, HTML
import tempfile
from os import unlink

def display_html_to_frame(html, width=600, height=600):
    name = f"temp_{random_name()}.html"
    with open(name, "w") as f:
        print(html, file=f)
    display(IFrame(name, width, height), metadata=dict(isolated=True))
    # unlink(name)
    
def display_html_inline(html):
    display(HTML(html, metadata=dict(isolated=True)))

h="<html><b>Hello</b></html>"    
display_html_to_iframe(h)
display_html_inline(h)

Some quick notes:

  • You can generally just use inline HTML for simple items. If you are rendering a framework, like a large JavaScript visualization framework, you may need to use an IFrame. Its hard enough for Jupyter to run in a browser without random HTML embedded.
  • The strange parameter, metadata=dict(isolated=True) does not isolate the result in an IFrame, as older documentation suggests. It appears to prevent clear-fix from resetting everything. The flag is no longer documented: I just found using it allowed certain display: grid styles to correctly render.
  • This IFrame solution writes to a temporary file. You could use a data uri as described here but it makes debugging your output difficult. The Jupyter IFrame function does not take a data or srcdoc attribute.
  • The tempfile module creations are not sharable to another process, hence the random_name().
  • If you use the HTML class with an IFrame in it, you get a warning. This may be only once per session.
  • You can use HTML('Hello, <b>world</b>') at top level of cell and its return value will render. Within a function, use display(HTML(...)) as is done above. This also allows you to mix display and print calls freely.
  • Oddly, IFrames are indented slightly more than inline HTML.

Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to ipython

How to increase image size of pandas.DataFrame.plot in jupyter notebook? Importing .py files in Google Colab Selection with .loc in python IOPub data rate exceeded in Jupyter notebook (when viewing image) Purpose of "%matplotlib inline" Installing a pip package from within a Jupyter Notebook not working convert json ipython notebook(.ipynb) to .py file In which conda environment is Jupyter executing? How to make inline plots in Jupyter Notebook larger? %matplotlib line magic causes SyntaxError in Python script

Examples related to jupyter-notebook

How to prevent Google Colab from disconnecting? Jupyter Notebook not saving: '_xsrf' argument missing from post How do I install Python packages in Google's Colab? What is the difference between Jupyter Notebook and JupyterLab? Importing .py files in Google Colab Display all dataframe columns in a Jupyter Python Notebook How to open local file on Jupyter? how to open Jupyter notebook in chrome on windows Change the Theme in Jupyter Notebook? Jupyter notebook not running code. Stuck on In [*]