Nbdev v2 launched

The data type of a function argument shows the entire module path in the documentation generated by nbdev, and it looks strange, like the screenshot below:

The code used in the case above looks like this:

from typing import Optional
from tensorflow.keras.layers import Normalization

def keras_lasso_linear_model(
    normalization_layer: Optional[Normalization]=None,
) -> tf.keras.Sequential:

Is it possible to make this data type column in the documentation cleaner?

Another question related to the documentation: It seems that nbdev inherits the base class documentation even when I explicitly add a docstring to my class. Example:

class LinearHyperModel(kt.HyperModel):
    def __init__(
        Define a KerasTuner search space for linear models
        # code here

leads to

where the text comes from the kt.HyperModel base class. Is this the expected behavior?

Does it change if you put the docstring on the class, instead of the init?

Yes, it works as expected when I place the docstring in the class. Should I always avoid placing it on the init?

I guess it has to be consistent across classes probably.

1 Like

Hi guys,
Can someone help me with this issue, please?

Thanks for your time!

Please don’t x-post (or x-link) like this.


Would you want it to only refer to the object e.g. Normalization? I suspect some users would prefer the full path. Perhaps it would need to be configurable?

I’ve been thinking that a different table UI might be better in general, and would also solve this issue specifically. For example, something like spacy’s docs where the type is on a separate row instead of being in its own column:

1 Like

Yes, showing the full path is desired. I agree this is a UI issue, and I like your suggestion based on spacy’s docs.

Another possibility would be to show Normalization but display the full path when the user hovers over the “link”.


Hi @Daniel I’m trying to use nbdev on paperspace. How did you get this to work? Do you have any resources or posts you’ve found helpful?

1 Like

Since your question is little general, the best I can offer right now is what I wrote down in my note after getting nbdev and paperspace to work

how to use paperspace with nbdev

  • make sure to specify all the libraries (including the latest version number) needed for my project in settings.init, as paperspace may only install the default version not necessarily the latest needed
  • then pip install -e . will install all of them
  • nbdev is only usable in paperspace if it is installed in this way
1 Like

Got the following “Please enable Github pages” error today:

It was working fine before, and there was no gh-pages changes from my side. Here is the GitHub Actions link: Merge pull request #17 from vespa-engine/tgm/time-query-operator · vespa-engine/learntorank@580448d · GitHub

Sorry for the late response. Had to use @staticmethod followed by @patch_to(ClassName) but it didn’t work even after fix exporting `patch_to` which is decorated with `staticmethod` by seeM · Pull Request #1100 · fastai/nbdev · GitHub.

hi @Daniel I find that I must re-save the .ssh file into the ~/ folder everytime I re-open a session in paperspace. Do you know of any alternatives to this? I have listed my steps for each new Paperspace session here in case it is useful to anyone.

@daveramseymusic in the live coding sessions associated with part 1 of the course I step through how to set this up. There’s a repo here to automate it: GitHub - fastai/paperspace-setup: Setup a paperspace instance for fastai


Aha! Thank you. For anyone else interested, the live coding answer to this:

Is right about HERE in video 3.
But even more specifically .ssh is added HERE in vid 3.


I posted this message as an issue since I got no reply here, so I am assuming it is a bug: https://github.com/fastai/nbdev/issues/1199

Based on @Daniel’s timestamps, I updated them for the sped-up version.

00:00 - Welcome

00:50 - Getting started and What are those super amazing things that can be done with nbdev?

02:30 - What does Jeremy think of nbdev? What’s Jeremy’s user experience of it?

03:20 - What’s the plan for today’s session?

Turn a GitHub repo into a nbdev repo

04:18 - What’s the first step? Creating a repo

05:00 - Make this repo into a nbdev repo: how to install nbdev, how lightweight is nbdev

05:50 - What are nbdev commands? type nbdev_ How to use them? type nbdev_help

06:22 - How nbdev makes writing docs super easy and lazy?

07:11 - How to find out the docs of a nbdev command like nbdev_new? type nbdev_new -h

07:25 - What does nbdev_new give us? What is settings.ini? Why it is so important to help you lazy?

08:30 - What is the stuff generated by nbdev_new on your cloned repo for you? Which ipynb is your home for docs? (index.ipynb) Which ipynb is your library? (00core.ipynb)

9:38 How should you name ipynbs for your library so that you and people understand how the lib is written? Jeremy showed us how he got started on nbdev with execnb 1 and showed the history of how he explored and invented nbdev

11:45 - Create two ipynbs as two modules card and deck

12:07 - How to name your module with #| as in quarto? How and when to hide your cell?

13:17 - What do the heading 1 and heading 2 do? Have a look at execnb as an example

Create a Card module

15:28 - How did Jeremy create a module Card from scratch in nbdev?

15:45 - Creating suits: How did Jeremy solve the card emoji in the python problem live?

17:19 - Creating ranks: based on the codes from the book author

17:36 - Creating a class by starting to create the __init__ function: what is fastai/Jeremy’s coding style?

20:47 - How Jeremy wrote docs of the explorative experiment before starting to build the Card class?

21:48 - How to overwrite the __str__ and __repr__ to display the class instance nicely? Also writing docs for the class along the way.

23:32 - How to write docs for input argument (to make docs for the class more clean and short) in the source and how to display docs with show_doc? Can you even show_doc other libraries not written in nbdev?

26:30 - Create tests for the class: How to import test from fastcore for testing with *? This way of wild card import requires __all__. nbdev takes care of it and makes it easy.

28:38 - run test_eq? and test_eq?? or test_eq or just test_eq( plus shift and tab can give you all the info you need for a class or function

29:23 - How did Jeremy build tests for the Card class live with different test functions?

29:46 - How to define equality __eq__ for the Class for the test functions to pass?

30:30 - How to give indication or set the types of the input arguments in the class? def __eq__(self, a: 'Card'):

31:09 - How to define a function outside of a class Card with @patch from fastcore.utils in an explorative and experimentative way? Now, you can just def __eq__(self:Card, a:Card): … Also the docs for this function is generated automatically too.

32:20 - Let’s create __lt__ and __gt__ with @patch and more tests with assert

33:00 - How to export your Card.py file with nbdev_export and try out your own single module library with pip install -e . and then import the lib inside index.ipynb to try out while writing your front page there.

34:42 - to copy the description of the library from setttings.ini to index.ipynb and write about the inspiration of this lib.

35:27 - Write about the how to install cell: Note that no code quote is used in the cell. The first middle tricky issue: the lib name can’t have a _ underscore, so it has to be nbdev-cards even though the py file name and its lib_path name is using nbdev_cards. Also, we need to make them clear in the settings.ini file. Jeremy also mentioned how to use the % in the settings.ini?

36:41 - How to preview your documentation? nbdev_preview which also installs the quarto web server for you. How Jeremy preview both the source file and documentation webpage at the same time to make an adjustment and see them in real-time.

38:32 - How Jeremy handles functions like __eq__ etc? Do we need to show_doc them? How to organize these functions?

39:20 - So, you decide which cell in the notebook to show to your readers with #| hide. For example, you can just show readers one test example and hide the rest without overwhelming them

40:35 - nbdev can also generate an advanced webpage like the homepage of nbdev.fast.ai in a single notebook.

41:05 - How to do the local test? Run nbdev_test in the terminal to see whether all your tests pass or not. How helpful can nbdev_test be when a test fails? You can also check out all the functionalities of nbdev_test by nbdev_test -h

42:25 - How to do debugging in real life in nbdev with a hotkey for reload and all run? in the source notebook, 00 to reload or restart kernel, edit the keyboard shortcut in the notebook for running all cells. Then you can put %debug below the failing cell to debug what’s wrong.

44:13 - Start writing up the next module to create a deck of cards. Thanks to pip install -e . your lib will update itself whenever you make changes to it

1:00:51 - Which codes should be exported with #|export? We can double-check the exported py file to see what is actually exported with __all__

Creating Deck module

46:17 - Write up the Deck class: use ctags -R and vim to search and jump through the source codes: /card to search, ctrl + ] to jump to the definition of the card in a different file if needed

47:25 - How did Jeremy figure out a problem of not exporting a line of import and test and fix it live?

48:20 - What is the golden rule of making a library? Don’t mix import with other things in a single cell.

49:19 - How to overwrite the __len__ and __contains__ and how to use them? len(deck) and Card(1,1) in deck

52:24 - Start creating a pop method: Who (R) likes and who (quarto) does not like a space between #| and export? How do create the function pop and write docs and the default value for arg idx:int=-1): # docs for this arg here? Then write a test for it right away. And nbdev_export, nbdev_test and nbdev_preview to check the site

53:50 - The card in the markdown cell will be automatically turned into a link to the class Card on the website. This feature (linkify) works for all kinds of libraries.

55:17 - Start writing the remove method for the Deck class: copy and write the code, write a test, run tests, and check with the preview to see whether exported properly

55:37 - Creating a function draw_n cards: also add another method shuffle inside the class source and we can show_doc(Deck.shuffle) at where the shuffle’s tests are.

57:20 - More techniques or features in written tutorials later

Pushing back to GitHub

57:29 - Sending to GitHub: first, nbdev_clean to clean unnecessary metadata; git status to see what will be going to GitHub; git add -A to add all the things seen above to be ready to send to GitHub; you can run export, clean and test in one go by nbdev_prepare; then git commit -am "..." and git push to the GitHub.

58:46 - What actions does nbdev ask GitHub to do for it? Check them in .github/workflows. Then Jeremy showed how to use GitHub Pages to display the website and how GitHub runs the two actions.

1:00:04 - Now enjoy your library website

1:00:24 - You should be absolutely amazed by what nbdev has done for you.

1:01:26 - run nbdev_docs to put the homepage inside README.md for you.

Release Your Library

1:02:29 - Use nbdev_pypi or nbdev_conda or nbdev_release to upload. How to deal with the two versions of the pypi library created? use git diff to see the differences between the two versions; then git commit -am bump and then git push

1:03:35 - How nbdev makes PR easier for all? and what’s more, you can do with nbdev, such as writing code with documentation, blogs, and any other technical content.


When I ran nbdev_prepare, it seems %matplotlib inline became get_ipython().run_line_magic('matplotlib', 'inline') which cased a TypeError.


As soon as I converted %matplotlib inline became a string. The TypeError message disappeared.

I use %matplotlib inline almost in every notebook. Please investigate.