Warning: Functionality described in this post have been moved to a public personal repository. If this functionality is useful to you, check it out at this repository. Functionality for NB -> Module and Module -> NB are in the nbutils notebook/module.

I made a very minimal version of nbdev with the intent toward use in one-off projects rather than full featured library. I released to pip for my own use, though I'd take it down if it's something that fits within NBdev.

I often find myself wishing I could always use the #export tags when coding in notebooks and have any code cells that start with #export just auto-magically be in .py modules. It's a pain to copy code between multiple notebooks, but it's also a pain to copy and paste code between modules and notebooks.

NBDev offers an innovative solution and this small library was inspired by it. If you aren't familiar with NBDev, check it out. NBdev comes out of the box with lots of powerful features such as:

  • Automated Testing and CI
  • Automated creation and deployment of documentation site
  • Automated releases to both conda and pip
  • Too many more to name

So why just use NBDev if it's so awesome? Well sometimes I don't need all those powerful features listed above. Separate documentation, release to conda and pip, and automated CI means there's configuration that needs to be filled out. If I am just fiddling with something or working on a one-off project I don't need a documentation page for that and I am not making something that will ever be released to pip or conda. So that means I don't need the configuration items and can make something simpler.

Note: Follow me on twitter if you want updates on new blog posts.
Ok: Enough jibber-jabber - let's see how it works!

Minimal Example

Code to be Exported

I have a notebook with a half dozen cells. We will use nbdevminimum to convert the code cells with export flags to the py files but leave the others that I don't want sent over.

Export Code

Now run the command to convert all our notebooks in the folder to .py files. It will just skip any cells or notebooks with no export flags. The directory you are in is the default, which would probably be what you want most of the time. I'm using a different directory so it doesn't get tangled with my blog.

You can also use simple_export_one_nb instead to specify the export of only 1 notebook.

from nbdevminimum.core import *
simple_export_all_nb(nbs_path=Path('nbdevminimal_example'),lib_path=Path('nbdevminimal_example/src'))
Converted nbdevminimal_example/src/NbdevMinimalExample.py

Proof that it worked

To prove that is only put the export code cells lets look at the py file.

Note: Numbers, spaces, and understcores at the beginning of the file name, as well as dashes anywhere are automatically removed from the file name so you can import easily.
!ls nbdevminimal_example/src
NbdevMinimalExample.py
!head -10 nbdevminimal_example/src/NbdevMinimalExample.py
#export
def add(a,b): return a+b

#export
def subtract(a,b): return a-b

Great! So we have our module. Lets import one of the functions back in. We'll rename it on import to show that it's actually working and isn't just the function defined above

from nbdevminimal_example.src.NbdevMinimalExample import add as test_add
test_add(5,10)
15

As a final check, we can see that it is indeed from our src.NbdevMinimum script

test_add
<function nbdevminimal_example.src.NbdevMinimalExample.add(a, b)>

Conclusion

Thats's all there is too it. Just drop the two lines in any notebook cell and it'll export the folder for you. Check out the documentation for information about helpful arguments or exporting single notebooks.

from nbdevminimum.core import *
simple_export_all_nb()

Follow me on twitter if you want updates on new blog posts.