Note: If no pyproject.toml with [tool.nbdev] is found, get_config() returns a minimal config with defaults based on the current directory. Use is_nbdev() to check if you’re in an nbdev project.
You can customize nbdev for all your projects by creating a ~/.config/nbdev/config.toml file (or following the XDG specification). Any [tool.nbdev] key can go there, with the project’s own setting winning: for example, jupyter_hooks = false globally disables nbdev’s Jupyter hooks, and cell_timeout = 60 gives nbdev-test a default cell timeout. nbdev-create-config also reads user, author, and author_email from it when neither the arguments nor the git remote supply them.
Add __init__.py in all subdirs of path containing python files if it’s not there already.
An LLM (or person) asking doc(pkg) should learn which modules to read next, like a good llms.txt. The curation signal is the docstring itself: a module saying more than the default summary plus Docs: link has had documentation deliberately written for it, so it’s meant to be independently useful. pkg_mdoc lists those modules, each with the first paragraph of its docstring, and update_init_mdoc writes the result as the package docstring in __init__.py (surgically: any code there is preserved). It runs as part of add_init, so plain nbdev-export keeps it current.
Tools understand the same signal: pyskills’ doc() treats a package with a substantive docstring as curated and elides its mechanical submodule listing, so the generated Modules: list is the whole answer rather than being repeated (e.g. doc('pyskills') itself).
Write pkg_mdoc as the docstring of path/__init__.py, replacing any existing docstring
The same parts also make a spec-compliant llms.txt: title, > summary, the index-notebook intro, and a ## Modules section linking each substantive module to its .html.md page (taken from the Docs: line of its docstring). update_llms_txt writes it to the notebooks folder, where Quarto copies it to the site root. A trailing HTML-comment marker identifies the file as generated: a hand-written llms.txt (no marker) is never overwritten.
llms.txt for the package at path, from the same sources as pkg_mdoc (’’ if no intro or modules)
with tempfile.TemporaryDirectory() as d: d = Path(d) cfg_text = (pyproj_tmpl.replace('name = "FILL_IN"', 'name = "testpkg"').replace('requires-python="FILL_IN"', 'requires-python=">=3.10"')) cfg_text +='\n[tool.nbdev]\n' (d/_pyproj).write_text(cfg_text) (d/'testpkg').mkdir()with working_directory(d): update_proj(d) result = (d/_pyproj).read_text()assert'name = "testpkg"'in result
Python modules require a __init.py__ file in all directories that are modules. We assume that all directories containing a python file (including in subdirectories of any depth) is a module, and therefore add a __init__.py to each.
with tempfile.TemporaryDirectory() as d: d = Path(d) (d/'a/b').mkdir(parents=True) (d/'a/b/f.py').touch() (d/'a/c').mkdir() add_init(d)assertnot (d/'a/c'/_init).exists(), "Should not add init to dir without py file"for e in [d, d/'a', d/'a/b']: assert (e/_init).exists(),f"Missing init in {e}"