A quick guide to adding a new Colaboratory notebook to your project repo and configuring it for use with nbdev.

Add a new notebook

Create a new python 3 notebook in Gooogle Colaboratory (Colab) and name it according to the nbdev convention of incremental numbering (00, 01, 02 etc) followed by an underscore and a name describing its contents. For example, if this is the third notebook added to the project, and it contains tests, an appropriate name might be '03_tests.ipynb'. Note that the new notebook may not be created directly in the project repository on Google Drive. If not, locate it on your Google Drive (commonly the 'Colab Notebooks' folder in '/My Drive'), and move it to the project repo by right clicking and selecting 'move'.

Then add and run the following code snippets in separate cells.

  1. In the first cell add the following code where <module> is the name of the .py file that the notebook will create. In the case of the 03_tests.ipynb notebook, the module name should be 'tests'. Submodules can be specified with <module.submodule>.

    # default_exp <module>
  2. Then add the following code to connect your Colab instance to Google Drive. Alternatively, click on 'Mount Drive' in the Colab sidebar File tab and the above code is automatically inserted and run for you.

    #hide
    from google.colab import drive
    drive.mount('/content/drive')
  3. Add automatic reloading of modules when they change at source.

    %load_ext autoreload
    %autoreload 2
  4. Required installs. Fastcore is required for running tests from nbdev.

    #hide
    !pip install nbdev
    !pip install fastcore
  5. Add a code cell that changes directory to the project repo early in the notebook.

    #hide
    %cd /content/drive/My drive/<repo>
  6. Import modules:

    #hide
    #not deps but we need them to use nbdev and run tests
    from nbdev import * 
    from nbdev.showdoc import *
    from fastcore.test import *
  7. Add a text cell with the following code and replace the placeholder text with the name/title for your notebook that you want to appear in the documentation. The '>' creates an indented paragraph.

    # Notebook title
    > Add an explanation/details of the module here.
  8. Optionally add the in-notebook export cell. Running this cell exports modules directly from the notebook (without having to go to the command line). The nbdev docs suggest adding it as the final cell in the notebook.

    #hide
    from nbdev.export import notebook2script
    notebook2script()

You're ready to go.

Test flags

One more thing ... test_flags!

Certain cells, allthough containing legitimate code, cause problems with nbdev's integrated test system. For example, the code above to mount google drive (point 2) causes open unmounted notebooks to stall during test runs and the notebook to fail. To deal with this, Nbdev has test_flags.

Flags are denoted by #<flag_name> placed at the top of cells and signal to nbdev how that cell should be treated. Nbdev has a number of built in flags, for example, #exports and #hide are flags, but we can also create custom test_flags to signal to nbdev that we want the cell contents excluded from test runs with nbdev_test_nbs.

First, create one or more test_flags by editing the tst_flags setting of settings.ini with the desired flag, for example, tst_flags = <flag_name>. The name can be anything not already in use as a flag and multiple test flags can be separated by | . Next simply add the name of the flag preceeded by # to the top of notebook cells to be excluded from test runs. So, to exclude our troublesome drive.mount code above we can specify a test_flag in settings.ini with tst_flags = tst_flag_colab and them add #test_flag_colab to the top of the cell:

#hide
#test_flag_colab
from google.colab import drive
drive.mount('/content/drive')

If your using Colab you are also likely writing code for GPUs, and device code tested with nbdev_test_nbs in a Colab CPU instance will raise a cuda runtime error (100) exception. You might, therefore, consider setting up another test_flag for this circumstance. Use the built in #all_flag to exclude the entire notebook from tests.

Test_flags can be 'turned off' by passing it as an argument to the --flags attribute of nbdev_test_nbs, like this nbdev_test_nbs --flag test_flag_colab. In this case nbdev will ignore #test_flag_colab during test runs and include flagged cells for testing. You can create and use any number of test flags in this way and the end product is a low-overhead, flexible testing environment - thanks nbdev!