{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# NbConvert, Python library" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this Notebook, I will introduce you to the programatic API of nbconvert to show you how to use it in various context. \n", "\n", "For this I will use one of [@jakevdp](https://github.com/jakevdp) great [blog post](http://jakevdp.github.io/blog/2013/04/15/code-golf-in-python-sudoku/).\n", "I've explicitely chosen a post with no javascript tricks as Jake seem to be found of right now, for the reason that the becommings of embeding javascript in nbviewer, which is based on nbconvert is not fully decided yet. \n", "\n", "\n", "This will not focus on using the command line tool to convert file. The attentive reader will point-out that no data are read from, or written to disk during the conversion process. Indeed, nbconvert as been though as much as\n", "possible to avoid IO operation and work as well in a database, or web-based environement." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Quick overview" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Credit, Jonathan Freder (@jdfreder on github)\n", "\n", "
\n", " ![nbca](images/nbconvert_arch.png)\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The main principle of nbconvert is to instanciate a `Exporter` that controle\n", "a pipeline through which each notebook you want to export with go through." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's start by importing what we need from the API, and download @jakevdp's notebook." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'{\\n \"metadata\": {\\n \"name\": \"XKCD_plots\"\\n },\\n \"nbformat\": 3,\\n...'" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import requests\n", "response = requests.get('http://jakevdp.github.com/downloads/notebooks/XKCD_plots.ipynb')\n", "response.text[0:60]+'...'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you do not have request install downlad by hand, and read the file as usual." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We read the response into a slightly more convenient format which represent IPython notebook. \n", "There are not real advantages for now, except some convenient methods, but with time this structure should be able to\n", "guarantee that the notebook structure is valid. Note also that the in-memory format and on disk format can be slightly different. In particual, on disk, multiline strings might be spitted into list of string to be more version control friendly." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "{'cell_type': 'markdown',\n", " 'metadata': {},\n", " 'source': '# XKCD plots in Matplotlib'}" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython import nbformat\n", "jake_notebook = nbformat.reads(response.text, as_version=4)\n", "jake_notebook.cells[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So we have here Jake's notebook in a convenient form, which is mainly a Super-Powered dict and list nested.\n", "You don't need to worry about the exact structure." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The nbconvert API exposes some basic exporter for common format and default options. We will start\n", "by using one of them. First we import it, instanciate an instance with most of the default parameters and fed it\n", "the downloaded notebook. " ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from IPython.config import Config\n", "from IPython.nbconvert import HTMLExporter\n", "\n", "## I use `basic` here to have less boilerplate and headers in the HTML.\n", "## we'll see later how to pass config to exporters.\n", "html_exporter = HTMLExporter(config=Config({'HTMLExporter':{'default_template':'basic'}}))" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [], "source": [ "(body, resources) = html_exporter.from_notebook_node(jake_notebook)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The exporter returns a tuple containing the body of the converted notebook, here raw HTML, as well as a resources dict.\n", "The resource dict contains (among many things) the extracted PNG, JPG [...etc] from the notebook when applicable.\n", "The basic HTML exporter does keep them as embeded base64 into the notebook, but one can do ask the figures to be extracted. Cf advance use. So for now the resource dict **should** be mostly empty, except for 1 key containing some css, and 2 others whose content will be obvious.\n", "\n", "Exporter are stateless, you won't be able to extract any usefull information (except their configuration) from them.\n", "You can directly re-use the instance to convert another notebook. Each exporter expose for convenience a `from_file` and `from_filename` methods if you need." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['raw_mimetypes', 'inlining', 'metadata', 'output_extension']\n", "defaultdict(None, {'name': 'Notebook'})\n", ".html\n" ] } ], "source": [ "print([key for key in resources ])\n", "print(resources['metadata'])\n", "print(resources['output_extension'])\n", "# print resources['inlining'] # too lng to be shown" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\n", "\n", "\n", "Notebook\n", "\n", "\n", "\n", "\n", "