Skip to content

Instantly share code, notes, and snippets.

@juhasch
Last active August 29, 2015 14:02
Show Gist options
  • Save juhasch/d8f73f5fd32a66ce7444 to your computer and use it in GitHub Desktop.
Save juhasch/d8f73f5fd32a66ce7444 to your computer and use it in GitHub Desktop.
First draft of a Notebook helping with Notebook Extensions
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"hide_input": true,
"hide_output": false,
"kernelspec": {
"codemirror_mode": {
"name": "python",
"version": 2
},
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"name": "",
"signature": "sha256:7f246adbb10ae65acc2792729de9fc092d5d5a1a4aaa87c9d56d8c20b77203ea"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "heading",
"level": 1,
"metadata": {
"run_control": {
"marked": false
}
},
"source": [
"Managing notebook extensions"
]
},
{
"cell_type": "markdown",
"metadata": {
"run_control": {
"marked": false
},
"variables": {}
},
"source": [
"This notebook tries to make the installation of IPython notebook extensions easier.\n",
"\n",
"Notebook extensions are typically installed in the `nbextension` subdirectory of the user's local IPython location. \n",
"\n",
"An extension can be loaded directly in the notebook like this:\n",
"```Javascript\n",
"%%Javascript\n",
"IPython.load_extensions('<extension name>')\n",
"```\n",
"To have an extension always loaded, it has to be loaded in the users local `custom.js`.<br>\n",
"This file can be seen in the browser here: [http://127.0.0.1:8888/static/custom/custom.js](http://127.0.0.1:8888/static/custom/custom.js)<br>\n",
"(assuming \"127.0.0.1:8888\" is the base url for the notebook server)."
]
},
{
"cell_type": "heading",
"level": 2,
"metadata": {
"run_control": {
"marked": false
}
},
"source": [
"Finding the `custom.js` file"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# first locate IPython\n",
"ip=get_ipython()\n",
"locate_dir = ip.ipython_dir\n",
"profile_dir = ip.config.ProfileDir.location\n",
"print(\"IPython location: %s\" % locate_dir)\n",
"print(\"IPython profile location: %s\" % profile_dir)"
],
"language": "python",
"metadata": {
"code_folding": [
0
],
"hide_input": true,
"run_control": {
"breakpoint": false,
"marked": true
}
},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"IPython location: C:\\Users\\hasch\\.ipython\n",
"IPython profile location: C:\\Users\\hasch\\.ipython\\profile_juhasch\n"
]
}
],
"prompt_number": 5
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# create list of paths that may contain a custom.js file\n",
"import os\n",
"extra_paths = ip.config.NotebookApp['extra_static_paths']\n",
"static_paths = [os.path.join(profile_dir,'static')]\n",
"if type( extra_paths ) is list:\n",
" static_paths = extra_paths + static_paths\n",
"print(\"The custom.js file will be searched in this list of directories: %s\" % static_paths)"
],
"language": "python",
"metadata": {
"code_folding": [
0
],
"run_control": {
"breakpoint": false,
"marked": false
}
},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"The custom.js file will be searched in this list of directories: [u'C:\\\\Users\\\\hasch\\\\.ipython\\\\profile_juhasch\\\\static']\n"
]
}
],
"prompt_number": 6
},
{
"cell_type": "code",
"collapsed": true,
"input": [
"# Try to find custom.js\n",
"import os\n",
"import re\n",
"for static_path in static_paths:\n",
" custom_js = os.path.join(static_path,'custom', 'custom.js')\n",
" if os.path.isfile(custom_js) is True:\n",
" print(\"custom.js found in %s\" % custom_js)\n",
" break"
],
"language": "python",
"metadata": {
"code_folding": [
0
],
"run_control": {
"breakpoint": false,
"marked": false
}
},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"custom.js file found in C:\\Users\\hasch\\.ipython\\profile_juhasch\\static\\custom\\custom.js\n"
]
}
],
"prompt_number": 7
},
{
"cell_type": "heading",
"level": 2,
"metadata": {
"run_control": {
"marked": false
}
},
"source": [
"Reading and Modifiying `custom.js`"
]
},
{
"cell_type": "markdown",
"metadata": {
"run_control": {
"marked": false
},
"variables": {}
},
"source": [
"The contents of the `custom.js` file will be read and all `IPython.load_extensions('')` calls will be displayed below.\n",
"\n",
"You can activate or deactivate a certain extension by checking or unchecking the checkbox. This will add or remove a `//` comment in front of the call when writing back the `custom.js` file.\n",
"\n",
"If you need to add new extensions or want to make more complex changes, you need to edit the `custom.js` file yourself."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# read custom.js and list extensions\n",
"match_active = \"IPython.load_extensions\\(['\\\"](.*)['\\\"]\"\n",
"match_inactive = \"//\\s*\" + match_active\n",
"f = open(custom_js,'r')\n",
"extension_list = []\n",
"extension_active = []\n",
"\n",
"for line in f.readlines():\n",
" m = re.search(match_active, line) \n",
" if m is not None:\n",
" extension_list.extend([m.group(1)])\n",
" extension_active.extend([True])\n",
" m = re.search(match_inactive, line)\n",
" if m is not None:\n",
" extension_active[-1] = False\n",
"f.close()\n",
"#print(\"Extensions: %s\" % extension_list)\n",
"#print(\"Active: %s\" % extension_active)"
],
"language": "python",
"metadata": {
"code_folding": [
0
],
"run_control": {
"breakpoint": false,
"marked": false
}
},
"outputs": [],
"prompt_number": 8
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# now make a GUI to select/deselect \n",
"from IPython.html import widgets # Widget definitions\n",
"from IPython.display import display # Used to display widgets in the notebook"
],
"language": "python",
"metadata": {
"code_folding": [],
"run_control": {
"breakpoint": false,
"marked": false
}
},
"outputs": [],
"prompt_number": 9
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Make container\n",
"child_style = {\n",
" 'padding': '5px',\n",
" 'margin': '5px',\n",
"}\n",
"\n",
"def make_container():\n",
" container = widgets.ContainerWidget()\n",
" container.set_css({\n",
" 'width': '100%',\n",
" })\n",
" display(container)\n",
" container.remove_class('vbox')\n",
" container.add_class('hbox')\n",
" container.add_class('start')\n",
"\n",
" return container\n"
],
"language": "python",
"metadata": {
"code_folding": [
0
],
"run_control": {
"breakpoint": false,
"marked": false
}
},
"outputs": [],
"prompt_number": 10
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Display list of extensions\n",
"container = make_container()\n",
"components = []\n",
"checkbox = widgets.LatexWidget(value=\"Active\")\n",
"name = widgets.LatexWidget(value=\"Name\")\n",
"comment = widgets.LatexWidget(value=\"Description\")\n",
"components.append(widgets.ContainerWidget())\n",
"components.append(widgets.ContainerWidget())\n",
"components.append(widgets.ContainerWidget())\n",
"\n",
"components[0].children = [checkbox]\n",
"components[1].children = [name]\n",
"components[2].children = [comment]\n",
"\n",
"container.children = components \n",
"components[0].add_class('box-flex1')\n",
"components[1].add_class('box-flex1')\n",
"components[2].add_class('box-flex2')\n",
"\n",
"containers = []\n",
"for i,e in enumerate(extension_list):\n",
" # read first line of extension\n",
" ext = e.split('/')\n",
" ext[-1] += '.js'\n",
" filename = os.path.join(locate_dir, 'nbextensions', *ext )\n",
" try:\n",
" f = open(filename,'r')\n",
" line = f.readline()\n",
" f.close\n",
" except:\n",
" line = \"**NOT FOUND**\"\n",
" containers.append(make_container())\n",
" containers[i].remove_class('vbox')\n",
" containers[i].add_class('hbox')\n",
"\n",
" components = []\n",
" checkbox = widgets.CheckboxWidget(value=extension_active[i])\n",
" name = widgets.TextWidget(value=e)\n",
" description = widgets.TextWidget(value=line.strip('//'))\n",
" components.append(widgets.ContainerWidget())\n",
" components.append(widgets.ContainerWidget())\n",
" components.append(widgets.ContainerWidget())\n",
" components[0].add_class('box-flex1')\n",
" components[1].add_class('box-flex1')\n",
" components[2].add_class('box-flex2')\n",
" components[0].children = [checkbox]\n",
" components[1].children = [name]\n",
" components[2].children = [description]\n",
" containers[i].children = components \n"
],
"language": "python",
"metadata": {
"code_folding": [
0
],
"run_control": {
"breakpoint": false,
"marked": false
}
},
"outputs": [],
"prompt_number": 11
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# write new custom.js\n",
" \n",
"def write_new_custom_js(b):\n",
" # Update changes\n",
" for i,container in enumerate(containers):\n",
" extension_active[i] = container.children[0].children[0].value \n",
"\n",
" match = \"IPython.load_extensions\\(['\\\"](.*)['\\\"]\"\n",
" bakfile = custom_js + '.bak'\n",
" os.remove(bakfile)\n",
" os.rename(custom_js, bakfile)\n",
" f = open(custom_js+'.bak','r')\n",
" fn = open(custom_js,'w+')\n",
"\n",
" for line in f.readlines():\n",
" m = re.search(match, line) \n",
" if m is not None:\n",
" name = m.group(1)\n",
" try:\n",
" # try to find extension name in file in our list\n",
" index = extension_list.index(name)\n",
" command = \" IPython.load_extensions('%s')\\n\" % name\n",
" comment = \"//\"\n",
" if extension_active[index] == False:\n",
" fn.write(comment)\n",
" fn.write(command)\n",
" except:\n",
" fn.write(line)\n",
" else:\n",
" fn.write(line)\n",
" f.close()\n",
" fn.close()\n",
" print \"custom.js was updated\"\n",
" \n",
"button_write = widgets.ButtonWidget(description=\"Update custom.js\")\n",
"display(button_write)\n",
"button_write.on_click(write_new_custom_js)"
],
"language": "python",
"metadata": {
"code_folding": [
0
],
"run_control": {
"marked": false
}
},
"outputs": [],
"prompt_number": 12
},
{
"cell_type": "heading",
"level": 1,
"metadata": {
"run_control": {
"marked": false
}
},
"source": [
"Download and Install IPython-contrib/notebook-extensions"
]
},
{
"cell_type": "markdown",
"metadata": {
"run_control": {
"marked": false
},
"variables": {}
},
"source": [
"In this section, you can download a copy of the complete IPython-contrib/notebook-extensions and install everything in the nbextensions subdirectory of your local IPython location.<br>\n",
"** Careful - this will overwrite existing files in your nbextensions directory **"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# unpack zip file to nbextensions directory\n",
"# remove base directory from GitHub\n",
"import urllib\n",
"import time\n",
"import zipfile\n",
"archiveurl_master = \"https://github.com/ipython-contrib/IPython-notebook-extensions/archive/master.zip\"\n",
"archiveurl_2x = \"https://github.com/ipython-contrib/IPython-notebook-extensions/archive/master.zip\"\n",
"\n",
"archive = \"github-ipython-contrib-notebook-extensions.zip\"\n",
"\n",
"global download_progress\n",
"\n",
"def dlProgress(count, blockSize, totalSize):\n",
" \"\"\" show download progress as percentage in the notebook \"\"\"\n",
" global download_progress\n",
" percent = int(count*blockSize*100/totalSize)\n",
" download_progress.value = percent\n",
"\n",
"def install_master(b):\n",
" install_ipython_nb_extensions(b, archiveurl_master)\n",
"\n",
"def install_2x(b):\n",
" install_ipython_nb_extensions(b, archiveurl_2x)\n",
" \n",
"def install_ipython_nb_extensions(b, archiveurl):\n",
" \"\"\" download zip archive and unpack in nbextensions directory\n",
" overwrites existing files\n",
" \"\"\"\n",
" global download_progress\n",
" download_progress = widgets.IntProgressWidget()\n",
" download_progress.description=\"Downloading\"\n",
" display(download_progress)\n",
" ext= urllib.urlretrieve(archiveurl, archive, reporthook=dlProgress)\n",
" fh = open(archive, 'rb')\n",
" z = zipfile.ZipFile(fh)\n",
" prog = 0\n",
" prog_max = len(z.namelist())\n",
" progress = widgets.IntProgressWidget()\n",
" display(progress)\n",
" progress.description=\"Copying\"\n",
" for name in z.namelist():\n",
" progress.value=(100*prog)/prog_max\n",
" prog +=1\n",
" zippath = name.split('/')\n",
" outpath = os.path.join(locate_dir, 'nbextensions', *zippath[1:] )\n",
" if zippath[-1] == '':\n",
" try:\n",
" os.stat(outpath)\n",
" except:\n",
" os.mkdir(outpath) \n",
" continue # skip directories\n",
" contents = z.read(name)\n",
" f = open(outpath,'wb+')\n",
" f.write(contents)\n",
" f.close\n",
" fh.close()\n",
" time.sleep(1)\n",
" os.remove(archive)\n",
" print(\"Notebook-Extensions from IPython-contrib installed in %s\" \n",
" % os.path.join(locate_dir, 'nbextensions'))"
],
"language": "python",
"metadata": {
"code_folding": [
0
],
"run_control": {
"breakpoint": false,
"marked": false
}
},
"outputs": [],
"prompt_number": 23
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"button_master = widgets.ButtonWidget(description=\"Install Extensions for bleeding edge IPython (Master)\")\n",
"button_2x = widgets.ButtonWidget(description=\"Install Extensions for IPython 2.x\")\n",
"button_master.on_click(install_master)\n",
"button_2x.on_click(install_2x)\n",
"display(button_master)\n",
"display(button_2x)"
],
"language": "python",
"metadata": {
"run_control": {
"marked": false
}
},
"outputs": [],
"prompt_number": 24
},
{
"cell_type": "heading",
"level": 2,
"metadata": {
"run_control": {
"marked": false
}
},
"source": [
"Installing a `custom.js` file for IPython-contrib"
]
},
{
"cell_type": "markdown",
"metadata": {
"run_control": {
"marked": false
},
"variables": {}
},
"source": [
"After installing the extensions, you can install a template `custom.js` file. This allows you to use section \"Reading and Modifiying `custom.js`\"."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# copy custom.js template\n",
"# make a backup...\n",
"import shutil\n",
"def install_custom(b):\n",
" inpath = os.path.join(locate_dir, 'nbextensions', 'custom.example.js' )\n",
" outpath = custom_js\n",
" outpath_bak = custom_js + '.bak'\n",
" print(\"Copying template file %s to %s\" % (inpath, outpath))\n",
" shutil.copy(outpath,outpath_bak)\n",
" shutil.copy(inpath,outpath)\n",
" "
],
"language": "python",
"metadata": {
"code_folding": [
0
],
"run_control": {
"marked": false
}
},
"outputs": [],
"prompt_number": 37
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"button_custom = widgets.ButtonWidget(description=\"Install custom.js template from nbextensions directory\")\n",
"button_custom.on_click(install_custom)\n",
"display(button_custom)"
],
"language": "python",
"metadata": {
"run_control": {
"marked": false
}
},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Copying template file C:\\Users\\hasch\\.ipython\\nbextensions\\custom.example.js to C:\\Users\\hasch\\.ipython\\profile_juhasch\\static\\custom\\custom.js\n"
]
}
],
"prompt_number": 38
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {
"run_control": {
"marked": false
}
},
"outputs": []
}
],
"metadata": {}
}
]
}
@PhenixXX
Copy link

PhenixXX commented Sep 3, 2014

I tried to install 2.x extensions by this Manager, and found some problems to discuss.
1> "archiveurl_master" and "archiveurl_2x" are using the same URL, so they are in fact the same files?
2> "Installing custom.js file" is only for 3.x version, so I have to edit it myself workable for 2.x.
3> My notebook cannot update Kernel status(got to refresh by F5 manually = =) after installing extensions and custom.js, I'm not sure if this is caused by your InstallManager.

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