Jupyter-book: Add a minimal "hello jupyter book" example

Created on 5 Oct 2020  路  17Comments  路  Source: executablebooks/jupyter-book

I love this project and I am grateful to the people working on it. But my experience getting started has been really frustrating.

I like that there is a command that creates a template, but it creates a lot of things I don't need, so the first thing I have to do is remove them.

What would help me more is a "hello world" example that contains the absolute minimum book structure. If I'm right, that would involve just _toc.yml, _config.yml and a content file.

It took me a lot of trial and error (and some incomprehensible error messages) to get a minimal book working.

documentation

Most helpful comment

I am gonna try updating the getting started docs a bit today, will ping back here when a PR is ready for feedback!

All 17 comments

Thanks for bringing this up - by any chance do you remember the specific things that were confusing and frustrating?

Also, would it be helpful to use the cookiecutter for the "hello book" example? I believe this is triggered with jupyter-book create mybook/ --cookiecutter.

If the current output of jupyter-book create has too many bells and whistles and is confusing folks, perhaps we should keep it very barebones (e.g. just a simple config + toc.yml + landing page) and refer people to the docs for examples of how to make it more complex

At the moment, here's the issue I'm stuck on. I have a successful build with one notebook. Now I want to go to two.

Here's what's in the directory:

$ ls AstronomicalData/
01_query.ipynb   _build 
02_coords.ipynb  _config.yml  _toc.yml

If I run jb toc AstronomicalData, I get the following:

file: 02_coords
sections:
- file: 01_query

I'm not sure why 02 seems to be the top-level document, and 01 is in a section.

So I tried this:

sections:
- file: 01_query
- file: 02_coords

But that gets me an error:

Extension error:
Handler <function add_toc_to_sphinx at 0x7fb481f27280> for event 'config-inited' threw an exception (exception: 'file')
Traceback (most recent call last):
  File "/home/downey/anaconda3/envs/AstronomicalData/lib/python3.8/site-packages/sphinx/events.py", line 110, in emit
    results.append(listener.handler(self.app, *args))
  File "/home/downey/anaconda3/envs/AstronomicalData/lib/python3.8/site-packages/jupyter_book/toc.py", line 192, in add_toc_to_sphinx
    app.config["master_doc"] = _posix_no_suffix(toc["file"])
KeyError: 'file'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/downey/anaconda3/envs/AstronomicalData/lib/python3.8/site-packages/jupyter_book/sphinx.py", line 110, in build_sphinx
    app = Sphinx(
  File "/home/downey/anaconda3/envs/AstronomicalData/lib/python3.8/site-packages/sphinx/application.py", line 268, in __init__
    self.events.emit('config-inited', self.config)
  File "/home/downey/anaconda3/envs/AstronomicalData/lib/python3.8/site-packages/sphinx/events.py", line 117, in emit
    raise ExtensionError(__("Handler %r for event %r threw an exception") %
sphinx.errors.ExtensionError: Handler <function add_toc_to_sphinx at 0x7fb481f27280> for event 'config-inited' threw an exception (exception: 'file')

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/downey/anaconda3/envs/AstronomicalData/bin/jb", line 8, in <module>
    sys.exit(main())
  File "/home/downey/anaconda3/envs/AstronomicalData/lib/python3.8/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/downey/anaconda3/envs/AstronomicalData/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/downey/anaconda3/envs/AstronomicalData/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/downey/anaconda3/envs/AstronomicalData/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/downey/anaconda3/envs/AstronomicalData/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/downey/anaconda3/envs/AstronomicalData/lib/python3.8/site-packages/jupyter_book/commands/__init__.py", line 259, in build
    builder_specific_actions(
  File "/home/downey/anaconda3/envs/AstronomicalData/lib/python3.8/site-packages/jupyter_book/commands/__init__.py", line 500, in builder_specific_actions
    raise RuntimeError(_message_box(msg, color="red", doprint=False)) from result
RuntimeError: 

So I take that to mean that a top-level document is required?

yep that's indeed the issue - the book needs a "landing page" defined as the first file. So basically:

- file: landing_page
  sections:
  - file: page1

however, there's a short-cut that is close to what you tried:

- file: landing_page
- file: page1

will be treated the same way.

I also opened up https://github.com/executablebooks/jupyter-book/issues/1020 to track improving that error message

Thanks, Chris! I really appreciate the quick replies, especially since you are on leave.

Maybe one other documentation note: it was not clear to me that building the book would run the notebooks. Since they have already run and contain the output, I expected JupyterBook to use the saved notebook, not run it.

My notebooks contact external servers and have side-effects, so I would have been good to know that they would be executed!

Having said that, it is possible to avoid running them and only use the outputs that are in the notebooks?

And maybe a related point: since I currently have the notebooks open and they are being autosaved, Jupyter book is running them every time I build, which is super slow.

CORRECTION: It looks like they are getting executed all the time, regardless of whether they have changed or not.

Sorry, I'm still confused about the table of contents. Here's my current version:

file: README
sections:
- file: 01_query
- file: 02_coords

I thought this would mean "Use README as the landing page and then have two sections, one for each notebook".

But if I open this url

file:///home/downey/AstronomicalData/AstronomicalData/_build/html/index.html

it takes me to 01_query, not README.

And the navigation bars are confusing. The left navigation contains:

  1. A link to the README
  2. A link to the first notebook
  3. Followed by all of the sections of the second notebook

All of this is telling me that something is wrong with my mental model of how the toc file maps to the structure of the document.

I see that I am getting a bunch of warnings about Non-consecutive header level increase, so that might explain the weirdness of the structure.

So I infer that the organization of the document is based on the header levels in the notebooks, not the structure of the toc. I'm confused about how these interact.

But it seems like I need to clean up the header levels in the notebooks for this to work. Yes?

since I currently have the notebooks open and they are being autosaved, Jupyter book is running them every time I build, which is super slow.

CORRECTION: It looks like they are getting executed all the time, regardless of whether they have changed or not.

On this point, you can update your execution option in _config.yml, see here

All of this is telling me that something is wrong with my mental model of how the toc file maps to the structure of the document.

Maybe an example would help, here. In the official Jupyter Book, if we look at the _toc.yml here, you can see how this section is built. Specifically, there's one general file on publishing and then each of the sections are unique files within the same folder. I wonder if since you have everything at the same level, it's not interpreting the nesting structure correctly.

I should edit to add that I completely understand the confusion ! I'm just wondering if this would directly fix your issues. If so, it might be useful to update the docs to mention this !

In addition - could you check out the docs here:

https://jupyterbook.org/customize/toc.html#how-headers-and-sections-map-onto-to-book-structure

And see if that clarifies anything about header levels and sections?

Also here:

https://jupyterbook.org/file-types/index.html#rules-for-all-content-types

for a note about header levels etc

also another tip is to run jupyter-book clean mybook/ if you reorganize your book etc. Sometimes there are old HTML files etc lying around.

re: execution, see the docs that @emdupre shared - perhaps that config option is something that we should have in the _config.yml file of the template

@emdupre @choldgraf Thank you both, this is very helpful.

I see now why I am confused about the relationship between the toc and the headers in the files. It's complicated. It would have helped me if this had come up sooner -- it's really important for the user to have the right mental model of this, and I think it has to be explicit. I was _not_ able to figure it out from examples.

For both of the problems I am stuck on, you have pointed me to documentation pages I haven't read yet. So that's good in the sense that the information is there, but it reiterates the fundamental problem I'm having, which is that the documentation is not presenting information in a sequence that aligns with my use case.

perhaps that config option is something that we should have in the _config.yml file of the template

I think that's a good idea. More generally, it might be good for the template files to contain more documentation, like

If you want to execute the notebooks every time, uncomment the following option.

Or in _toc.yml, something like:

Put your top-level file here -- it's required

And

Now put the other files in your document here.

Or

Note: By default, JupyterBook will ignore whatever you put here and just include every file in the folder. Surprise!

Well, maybe not that last one :)

Now that I think of it, adding configuration options to the template files could be a backward-compatible way to change the default behavior.

yeah I agree with you about adding more context, explanatory information, etc into the template files. I think that could certainly help provide more context (probably also including links to the docs where it explains more)

I guess the trick there is how to do it in a way that doesn't overload people. As you already mentioned, it's annoying to build a template and then have to immediately undo a bunch of config that's been chosen for you :-/

I am gonna try updating the getting started docs a bit today, will ping back here when a PR is ready for feedback!

@choldgraf Thanks so much taking this on. Please let me know if I can help.

your feedback so far has been super helpful! Usually when people try something and it doesn't work as expected they just get pissed off and go away instead of opening helpful issues like this one 馃槄

Hey all - would love feedback on this PR for the docs: https://github.com/executablebooks/jupyter-book/pull/1023

Was this page helpful?
0 / 5 - 0 ratings

Related issues

akhmerov picture akhmerov  路  5Comments

sidneymbell picture sidneymbell  路  5Comments

choldgraf picture choldgraf  路  4Comments

firasm picture firasm  路  5Comments

nozebacle picture nozebacle  路  3Comments