Notebook: Jupyter start with initialization cell ready as the first cell

Created on 13 May 2016  路  8Comments  路  Source: jupyter/notebook

What I'm looking forward to is this function:

Every time I start a new jupyter notebook (just Python 2/3 for me), I wish Jupyter / IPython could just insert some lines in the first cell such as:
import cufflinks as cf

The tricky part is I can put such import into my ipython default startup file, but it wouldn't bind the js output (in this case plotly's) to the notebook, so I have to type that line at the beginning all the time. It would also be good to put all the other imports from the ipython default startup file to the first cell of the notebook, so I am aware of the namespaces.

I googled around and found 4 possible places to add this line:
c.InteractiveShellApp.exec_lines.append('import cufflinks as cf') (I'm not sure this line is the correct one, I saw in #640 @Carreau suggested Jupyter.notebook.insert_cell_below(cell_type).set_text('import cufflinks as cf'), but where to put it in escapes me)
The four places I think it may work but turns out didn't are:
ipython_config.py, ipython_kernel_config.py, ipython_notebook_config.py, jupyter_notebook_config.py

Appreciate your help!

Most helpful comment

You can probably create an extension that add a list of "template" cells, that should not be too hard to do. I'll mark as sprint friendly, but it will likely not be in the core.

All 8 comments

You can probably create an extension that add a list of "template" cells, that should not be too hard to do. I'll mark as sprint friendly, but it will likely not be in the core.

Many thanks @Carreau for pointing the way. I hacked together a script to implement the utility. Based on community [book](), I made a script under the C:Usersxxx.xxxAppDataRoamingjupyternbextensions in a subfolder named main.js:

define(function(){
  return {
    load_ipython_extension: function(){
        Jupyter.notebook.insert_cell_above('code', 0).set_text('import cufflinks as cf\n')
    }
  };
})

and config jupyter to load it when it starts. But how can I tell if the notebook loaded is an existing or new one, ideally the script should only insert cell if it is a new notebook. If possible, could this be something that is easily achieved or not possible? just point me to the direction of the documentation, I'm happy to code more. Thanks!

This is a good idea! Any progress on this @Paul-Yuchao-Dong ?

and config jupyter to load it when it starts. But how can I tell if the notebook loaded is an existing or new one, ideally the script should only insert cell if it is a new notebook. If possible, could this be something that is easily achieved or not possible? just point me to the direction of the documentation, I'm happy to code more. Thanks!

Sorry missed that.

You can probably look at the number of cells. There is no way to differentiate otherwise.
something like :

if (Jupyter.notebook.get_cells().lenght==1 && Jupyter.noteboko.get_cell(0).editor.text === '' ){
   //do your thing
}

@Carreau No worries, thanks for pointing out the way. I've read some of the helpful documentation and realized that this part of the API probably would be changed anyway.

here's my revised script, I know it's monstrous, but I couldn't figure out how to pass the python code in a more elegant way, so here it is, it does the importing as well as a bit of number formatting:

/*
https://jupyter-notebook.readthedocs.io/en/latest/extending/frontend_extensions.html
*/

define([
    'base/js/namespace'
], function(
    Jupyter
) {
    function load_ipython_extension() {
      if (Jupyter.notebook.get_cells().length===1){
   //do your thing
        Jupyter.notebook.insert_cell_above('code', 0).set_text("from __future__ import division, print_function\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport matplotlib as mpl\nimport seaborn as sns\nimport re\nfrom calendar import monthrange\nfrom pandas_datareader import data as web\nfrom pandas.tseries.offsets import DateOffset, Second, Minute, Hour, Day\n\nimport xlwings as xw\nfrom xlwings import Workbook, Range, Sheet\n\nimport plotly.graph_objs as pgo\nfrom plotly.offline import plot, init_notebook_mode, iplot, iplot_mpl\nimport pdb\nimport cufflinks as cf\n\npd.options.display.max_rows = 10\npd.set_option('max_columns', 50)\nsns.set(style='ticks', context='talk')");
        Jupyter.notebook.insert_cell_above('code', 1).set_text("import IPython\nthousand_c = lambda x: '{:,}'.format(x)\nthousands = lambda arg, p, cycle: p.text('{:,}'.format(arg))\nnp.set_printoptions(formatter={'float_kind': thousand_c, 'int_kind': thousand_c})\nclass IntFormatter(pd.core.format.GenericArrayFormatter):\n    pd.set_option('display.float_format', thousand_c)\n    def _format_strings(self):\n        formatter = self.formatter or thousand_c\n        fmt_values = [formatter(x) for x in self.values]\n        return fmt_values\npd.core.format.IntArrayFormatter = IntFormatter\nfrm = get_ipython().display_formatter.formatters['text/plain']\nfrm.for_type(int, thousands)\nfrm.for_type(float, thousands);");
      }
    }
    return {
        load_ipython_extension: load_ipython_extension
    };
});

You could also set a custom metadata attribute on either the cell or the notebook as a whole, to keep track of whether it's already been done. Might also be nice to add different configurable init cells for different kernels.

@Paul-Yuchao-Dong, thanks for the script! I used it to add a welcome banner to a custom kernel. And now I wanted to just put the result here for others to find.

These are the contents of kernel.js which is installed in the kernelspec (that means into the same folder as the kernel's kernel.json):

define([
    'base/js/namespace'
], function(
    Jupyter
) {
    function onload() {
      if (Jupyter.notebook.get_cells().length===1){
        Jupyter.notebook.insert_cell_above('markdown', 0).set_text("Welcome to my kernel");
      }
      console.log("custom kernel.js loaded")
    }
    return {
        onload: onload
    };
});

Please note that the API is still subject to change in future releases.

This issue has been mentioned on Jupyter Community Forum. There might be relevant details there:

https://discourse.jupyter.org/t/opening-a-notebook-with-parameters-to-be-set-in-the-first-code-snippet/5389/4

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fonnesbeck picture fonnesbeck  路  3Comments

arbaazsama picture arbaazsama  路  3Comments

arilwan picture arilwan  路  3Comments

uolter picture uolter  路  3Comments

Foadsf picture Foadsf  路  3Comments