Skip to content

Instantly share code, notes, and snippets.

@jeremyschlatter
Created July 25, 2017 02:36
Show Gist options
  • Save jeremyschlatter/c35c6bfa568e5a40440cb2fefcc7fd4e to your computer and use it in GitHub Desktop.
Save jeremyschlatter/c35c6bfa568e5a40440cb2fefcc7fd4e to your computer and use it in GitHub Desktop.
Render React inline from a Jupyter notebook cell
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Render React from a Jupyter notebook cell, and access Python as needed at runtime.\n",
"\n",
"The `%jsx` magic:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"\n",
"// Load our libraries from a CDN instead of wherever this notebook is hosted.\n",
"require.config({\n",
" paths: {\n",
" babel: 'https://unpkg.com/babel-standalone@6/babel.min',\n",
" react: 'https://unpkg.com/react@15.3.1/dist/react',\n",
" 'react-dom': 'https://unpkg.com/react-dom@15.3.1/dist/react-dom'\n",
" }\n",
"})\n",
"\n",
"// Hook to call into Python.\n",
"// Credit to disarticulate for documenting the usage of iopub: \n",
"// https://gist.github.com/disarticulate/d06069ff3e71cf828e5329beab8cb084\n",
"window.python = code => new Promise((resolve, reject) => {\n",
" IPython.notebook.kernel.execute(\n",
" code,\n",
" {iopub: {output: data => resolve(data.content.text)}},\n",
" ) \n",
"})\n"
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import json\n",
"from string import Template\n",
"\n",
"from IPython.display import Javascript, display\n",
"from IPython.core.magic import register_cell_magic\n",
"\n",
"\n",
"display(Javascript('''\n",
"// Load our libraries from a CDN instead of wherever this notebook is hosted.\n",
"require.config({\n",
" paths: {\n",
" babel: 'https://unpkg.com/babel-standalone@6/babel.min',\n",
" react: 'https://unpkg.com/react@15.3.1/dist/react',\n",
" 'react-dom': 'https://unpkg.com/react-dom@15.3.1/dist/react-dom'\n",
" }\n",
"})\n",
"\n",
"// Hook to call into Python.\n",
"// Credit to disarticulate for documenting the usage of iopub: \n",
"// https://gist.github.com/disarticulate/d06069ff3e71cf828e5329beab8cb084\n",
"window.python = code => new Promise((resolve, reject) => {\n",
" IPython.notebook.kernel.execute(\n",
" code,\n",
" {iopub: {output: data => resolve(data.content.text)}},\n",
" ) \n",
"})\n",
"'''))\n",
"\n",
"\n",
"@register_cell_magic\n",
"def jsx(line, cell):\n",
" display(Javascript((Template('''\n",
" require(['babel', 'react', 'react-dom'], (Babel, React, ReactDOM) => {\n",
" eval(Babel.transform($quoted_script, {presets: ['react']}).code)\n",
" })\n",
" ''').substitute(quoted_script=json.dumps(cell)))))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Some Python state to access from React:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"greeting = 'Hello from Python and React!'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The punchline:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"\n",
" require(['babel', 'react', 'react-dom'], (Babel, React, ReactDOM) => {\n",
" eval(Babel.transform(\"python('print(greeting)').then(greeting => {\\n ReactDOM.render(\\n <h1>{greeting}</h1>,\\n element[0],\\n )\\n})\", {presets: ['react']}).code)\n",
" })\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%jsx\n",
"python('print(greeting)').then(greeting => {\n",
" ReactDOM.render(\n",
" <h1>{greeting}</h1>,\n",
" element[0],\n",
" )\n",
"})"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
@jeremyschlatter
Copy link
Author

JavaScript is disabled for gists, so you can't see the rendered output above. If you run the notebook yourself, you will see this as the final output:

Hello from Python and React!

@tvogels
Copy link

tvogels commented Jun 18, 2019

Thanks for sharing this!

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