nbdev 3.1.0__tar.gz → 3.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nbdev-3.1.0/nbdev.egg-info → nbdev-3.2.1}/PKG-INFO +37 -114
- nbdev-3.2.1/README.md +134 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/__init__.py +1 -1
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/_modidx.py +4 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/cli.py +10 -7
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/config.py +3 -2
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/export.py +9 -8
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/merge.py +7 -5
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/migrate.py +9 -7
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/processors.py +10 -4
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/qmd.py +34 -24
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/quarto.py +33 -13
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/release.py +7 -7
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/serve.py +10 -2
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/showdoc.py +6 -4
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/test.py +17 -13
- {nbdev-3.1.0 → nbdev-3.2.1/nbdev.egg-info}/PKG-INFO +37 -114
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev.egg-info/requires.txt +2 -2
- {nbdev-3.1.0 → nbdev-3.2.1}/pyproject.toml +2 -2
- nbdev-3.1.0/README.md +0 -211
- {nbdev-3.1.0 → nbdev-3.2.1}/CONTRIBUTING.md +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/LICENSE +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/MANIFEST.in +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/clean.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/diff.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/doclinks.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/extract_attachments.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/frontmatter.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/imports.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/maker.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/process.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/scrubmagics.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/serve_drv.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev/sync.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev.egg-info/SOURCES.txt +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev.egg-info/dependency_links.txt +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev.egg-info/entry_points.txt +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/nbdev.egg-info/top_level.txt +0 -0
- {nbdev-3.1.0 → nbdev-3.2.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nbdev
|
|
3
|
-
Version: 3.1
|
|
3
|
+
Version: 3.2.1
|
|
4
4
|
Summary: Create delightful software with Jupyter Notebooks
|
|
5
5
|
Author-email: "Jeremy Howard and the fast.ai community" <j@fast.ai>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -16,7 +16,7 @@ Classifier: License :: OSI Approved :: Apache Software License
|
|
|
16
16
|
Requires-Python: >=3.9
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
|
-
Requires-Dist: fastcore>=1.14.
|
|
19
|
+
Requires-Dist: fastcore>=1.14.6
|
|
20
20
|
Requires-Dist: execnb>=0.2.4
|
|
21
21
|
Requires-Dist: astunparse
|
|
22
22
|
Requires-Dist: ghapi>=2.0.0
|
|
@@ -36,7 +36,7 @@ Requires-Dist: matplotlib; extra == "dev"
|
|
|
36
36
|
Requires-Dist: black; extra == "dev"
|
|
37
37
|
Requires-Dist: svg.py; extra == "dev"
|
|
38
38
|
Requires-Dist: nbclassic; extra == "dev"
|
|
39
|
-
Requires-Dist:
|
|
39
|
+
Requires-Dist: pysym2md>=0.0.6; extra == "dev"
|
|
40
40
|
Requires-Dist: llms-txt; extra == "dev"
|
|
41
41
|
Requires-Dist: sphinx; extra == "dev"
|
|
42
42
|
Requires-Dist: plum-dispatch; extra == "dev"
|
|
@@ -51,55 +51,25 @@ Dynamic: license-file
|
|
|
51
51
|
|
|
52
52
|
## 🛑**Jan 2026 Major Version Update – Breaking Change**🛑
|
|
53
53
|
|
|
54
|
-
**nbdev3 is here!** As many of you have been requesting, configuration
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
and
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
notebooks with
|
|
68
|
-
tests, continuous integration, and packaging for free!
|
|
69
|
-
|
|
70
|
-
`nbdev` makes debugging and refactoring your code much easier than in
|
|
71
|
-
traditional programming environments since you always have live objects
|
|
72
|
-
at your fingertips. `nbdev` also promotes software engineering best
|
|
73
|
-
practices because tests and documentation are first class.
|
|
74
|
-
|
|
75
|
-
- **Documentation** is automatically generated using
|
|
76
|
-
[Quarto](https://quarto.org/) and hosted on [GitHub
|
|
77
|
-
Pages](https://pages.github.com/). Docs support LaTeX, are searchable,
|
|
78
|
-
and are automatically hyperlinked (including out-of-the-box support
|
|
79
|
-
for many packages via
|
|
80
|
-
[`nbdev-index`](https://github.com/fastai/nbdev-index))
|
|
81
|
-
- **Publish packages to PyPI and conda** as well as tools to simplify
|
|
82
|
-
package releases. Python best practices are automatically followed,
|
|
83
|
-
for example, only exported objects are included in `__all__`
|
|
84
|
-
- **Two-way sync between notebooks and plaintext source code** allowing
|
|
85
|
-
you to use your IDE for code navigation or quick edits. Sync is
|
|
86
|
-
robust: each exported cell is tagged with its unique notebook cell ID,
|
|
87
|
-
so `nbdev-update` always updates the correct cell
|
|
88
|
-
- **Tests** written as ordinary notebook cells are run in parallel with
|
|
89
|
-
a single command
|
|
90
|
-
- **Continuous integration** out-of-the-box with [GitHub
|
|
91
|
-
Actions](https://github.com/features/actions) that run your tests and
|
|
92
|
-
rebuild your docs
|
|
93
|
-
- **Git-friendly notebooks** with [Jupyter/Git
|
|
94
|
-
hooks](https://nbdev.fast.ai/tutorials/git_friendly_jupyter.html) that
|
|
95
|
-
clean unwanted metadata and render merge conflicts in a human-readable
|
|
96
|
-
format
|
|
54
|
+
**nbdev3 is here!** As many of you have been requesting, configuration has moved from `settings.ini` to `pyproject.toml`, following modern Python packaging standards ([PEP 621](https://peps.python.org/pep-0621/)). Your project metadata now lives in the standard `[project]` section, while nbdev-specific settings go in `[tool.nbdev]`.
|
|
55
|
+
|
|
56
|
+
**Migrating from nbdev2:** Run `nbdev-migrate-config` in your project root to automatically convert your `settings.ini` to `pyproject.toml` and update your GitHub Actions workflows to use nbdev3-compatible versions. Your existing notebooks and code don’t need any changes.
|
|
57
|
+
|
|
58
|
+
`nbdev` is a notebook-driven development platform. Simply write notebooks with lightweight markup and get high-quality documentation, tests, continuous integration, and packaging for free!
|
|
59
|
+
|
|
60
|
+
`nbdev` makes debugging and refactoring your code much easier than in traditional programming environments since you always have live objects at your fingertips. `nbdev` also promotes software engineering best practices because tests and documentation are first class.
|
|
61
|
+
|
|
62
|
+
- **Documentation** is automatically generated using [Quarto](https://quarto.org/) and hosted on [GitHub Pages](https://pages.github.com/). Docs support LaTeX, are searchable, and are automatically hyperlinked (including out-of-the-box support for many packages via [`nbdev-index`](https://github.com/fastai/nbdev-index))
|
|
63
|
+
- **Publish packages to PyPI and conda** as well as tools to simplify package releases. Python best practices are automatically followed, for example, only exported objects are included in `__all__`
|
|
64
|
+
- **Two-way sync between notebooks and plaintext source code** allowing you to use your IDE for code navigation or quick edits. Sync is robust: each exported cell is tagged with its unique notebook cell ID, so `nbdev-update` always updates the correct cell
|
|
65
|
+
- **Tests** written as ordinary notebook cells are run in parallel with a single command
|
|
66
|
+
- **Continuous integration** out-of-the-box with [GitHub Actions](https://github.com/features/actions) that run your tests and rebuild your docs
|
|
67
|
+
- **Git-friendly notebooks** with [Jupyter/Git hooks](https://nbdev.fast.ai/tutorials/git_friendly_jupyter.html) that clean unwanted metadata and render merge conflicts in a human-readable format
|
|
97
68
|
- … and much more!
|
|
98
69
|
|
|
99
70
|
## Install
|
|
100
71
|
|
|
101
|
-
nbdev works on macOS, Linux, and most Unix-style operating systems. It
|
|
102
|
-
works on Windows under WSL, but not under cmd or Powershell.
|
|
72
|
+
nbdev works on macOS, Linux, and most Unix-style operating systems. It works on Windows under WSL, but not under cmd or Powershell.
|
|
103
73
|
|
|
104
74
|
You can install nbdev with pip:
|
|
105
75
|
|
|
@@ -107,27 +77,17 @@ You can install nbdev with pip:
|
|
|
107
77
|
pip install nbdev
|
|
108
78
|
```
|
|
109
79
|
|
|
110
|
-
Note that `nbdev` must be installed into the same Python environment
|
|
111
|
-
that you use for both Jupyter and your project.
|
|
80
|
+
Note that `nbdev` must be installed into the same Python environment that you use for both Jupyter and your project.
|
|
112
81
|
|
|
113
82
|
## How to use nbdev
|
|
114
83
|
|
|
115
|
-
The best way to learn how to use nbdev is to complete either the
|
|
116
|
-
[written walkthrough](https://nbdev.fast.ai/tutorials/tutorial.html) or
|
|
117
|
-
video walkthrough:
|
|
84
|
+
The best way to learn how to use nbdev is to complete either the [written walkthrough](https://nbdev.fast.ai/tutorials/tutorial.html) or video walkthrough:
|
|
118
85
|
|
|
119
|
-
<a href="http://www.youtube.com/watch?v=l7zS8Ld4_iA" target="_blank"
|
|
120
|
-
title="nbdev walkthrough"><img
|
|
121
|
-
src="https://github.com/fastai/logos/raw/main/nbdev_walkthrough.png"
|
|
122
|
-
style="border-radius: 10px" width="560" height="315" /></a>
|
|
86
|
+
<a href="http://www.youtube.com/watch?v=l7zS8Ld4_iA" target="_blank" title="nbdev walkthrough"><img src="https://github.com/fastai/logos/raw/main/nbdev_walkthrough.png" style="border-radius: 10px" width="560" height="315" /></a>
|
|
123
87
|
|
|
124
|
-
Alternatively, there’s a [shortened version of the video
|
|
125
|
-
walkthrough](https://youtu.be/67FdzLSt4aA) with coding sections sped up
|
|
126
|
-
using the `unsilence` Python library – it’s 27 minutes faster, but a bit
|
|
127
|
-
harder to follow.
|
|
88
|
+
Alternatively, there’s a [shortened version of the video walkthrough](https://youtu.be/67FdzLSt4aA) with coding sections sped up using the `unsilence` Python library – it’s 27 minutes faster, but a bit harder to follow.
|
|
128
89
|
|
|
129
|
-
You can also run `nbdev-help` from the terminal to see the full list of
|
|
130
|
-
available commands:
|
|
90
|
+
You can also run `nbdev-help` from the terminal to see the full list of available commands:
|
|
131
91
|
|
|
132
92
|
``` python
|
|
133
93
|
!nbdev-help
|
|
@@ -158,7 +118,7 @@ available commands:
|
|
|
158
118
|
nbdev-pypi Create and upload Python package to PyPI
|
|
159
119
|
nbdev-readme Create README.md from readme_nb (index.ipynb by default)
|
|
160
120
|
nbdev-release-both Release both conda and PyPI packages
|
|
161
|
-
nbdev-release-gh Calls `
|
|
121
|
+
nbdev-release-gh Calls `nbdev-changelog`, lets you edit the result, then pushes to git and calls `nbdev-release-git`
|
|
162
122
|
nbdev-release-git Tag and create a release in GitHub for the current version
|
|
163
123
|
nbdev-requirements Writes a `requirements.txt` file to `directory` based on pyproject.toml.
|
|
164
124
|
nbdev-sidebar Create sidebar.yml
|
|
@@ -172,42 +132,26 @@ available commands:
|
|
|
172
132
|
|
|
173
133
|
### Q: What is the warning “Found a cell containing mix of imports and computations. Please use separate cells”?
|
|
174
134
|
|
|
175
|
-
A: You should not have cells that are not exported, *and* contain a mix
|
|
176
|
-
of `import` statements along with other code. For instance, don’t do
|
|
177
|
-
this in a single cell:
|
|
135
|
+
A: You should not have cells that are not exported, *and* contain a mix of `import` statements along with other code. For instance, don’t do this in a single cell:
|
|
178
136
|
|
|
179
137
|
``` python
|
|
180
138
|
import some_module
|
|
181
139
|
some_module.something()
|
|
182
140
|
```
|
|
183
141
|
|
|
184
|
-
Instead, split this into two cells, one which does `import some_module`,
|
|
185
|
-
|
|
142
|
+
Instead, split this into two cells, one which does `import some_module`, and the other which does `some_module.something()`.
|
|
143
|
+
|
|
144
|
+
Only top-level statements count: `try: import` blocks and imports inside function definitions are fine.
|
|
186
145
|
|
|
187
|
-
The reason for this is that when we create your documentation website,
|
|
188
|
-
we ensure that all of the signatures for functions you document are up
|
|
189
|
-
to date, by running the imports, exported cells, and
|
|
190
|
-
[`show_doc`](https://nbdev.fast.ai/api/showdoc.html#show_doc) functions
|
|
191
|
-
in your notebooks. When you mix imports with other code, that other code
|
|
192
|
-
will be run too, which can cause errors (or at least slowdowns) when
|
|
193
|
-
creating your website.
|
|
146
|
+
The reason for this is that when we create your documentation website, we ensure that all of the signatures for functions you document are up to date, by running the imports, exported cells, and [`show_doc`](https://nbdev.fast.ai/api/showdoc.html#show_doc) functions in your notebooks. When you mix imports with other code, that other code will be run too, which can cause errors (or at least slowdowns) when creating your website.
|
|
194
147
|
|
|
195
148
|
### Q: Why is nbdev asking for root access? How do I install Quarto without root access?
|
|
196
149
|
|
|
197
|
-
A: When you setup your first project, nbdev will attempt to
|
|
198
|
-
automatically download and install [Quarto](https://quarto.org/) for
|
|
199
|
-
you. This is the program that we use to create your documentation
|
|
200
|
-
website.
|
|
150
|
+
A: When you setup your first project, nbdev will attempt to automatically download and install [Quarto](https://quarto.org/) for you. This is the program that we use to create your documentation website.
|
|
201
151
|
|
|
202
|
-
Quarto’s standard installation process requires root access, and nbdev
|
|
203
|
-
will therefore ask for your root password during installation. For most
|
|
204
|
-
people, this will work fine and everything will be handled automatically
|
|
205
|
-
– if so, you can skip over the rest of this section, which talks about
|
|
206
|
-
installing without root access.
|
|
152
|
+
Quarto’s standard installation process requires root access, and nbdev will therefore ask for your root password during installation. For most people, this will work fine and everything will be handled automatically – if so, you can skip over the rest of this section, which talks about installing without root access.
|
|
207
153
|
|
|
208
|
-
If you need to install Quarto without root access on Linux, first `cd`
|
|
209
|
-
to wherever you want to store it, then [download
|
|
210
|
-
Quarto](https://quarto.org/docs/get-started/), and type:
|
|
154
|
+
If you need to install Quarto without root access on Linux, first `cd` to wherever you want to store it, then [download Quarto](https://quarto.org/docs/get-started/), and type:
|
|
211
155
|
|
|
212
156
|
``` bash
|
|
213
157
|
dpkg -x quarto*.deb .
|
|
@@ -217,39 +161,18 @@ mkdir -p ~/.local/bin
|
|
|
217
161
|
ln -s "$(pwd)"/quarto/bin/quarto ~/.local/bin
|
|
218
162
|
```
|
|
219
163
|
|
|
220
|
-
To use this non-root version of Quarto, you’ll need `~/.local/bin` in
|
|
221
|
-
your [`PATH` environment
|
|
222
|
-
variable](https://linuxize.com/post/how-to-add-directory-to-path-in-linux/).
|
|
223
|
-
(Alternatively, change the `ln -s` step to place the symlink somewhere
|
|
224
|
-
else in your path.)
|
|
164
|
+
To use this non-root version of Quarto, you’ll need `~/.local/bin` in your [`PATH` environment variable](https://linuxize.com/post/how-to-add-directory-to-path-in-linux/). (Alternatively, change the `ln -s` step to place the symlink somewhere else in your path.)
|
|
225
165
|
|
|
226
166
|
### Q: Someone told me not to use notebooks for “serious” software development!
|
|
227
167
|
|
|
228
|
-
A: [Watch this video](https://youtu.be/9Q6sLbz37gk). Don’t worry, we
|
|
229
|
-
still get this too, despite having used `nbdev` for a wide range of
|
|
230
|
-
“very serious” software projects over the last three years, including
|
|
231
|
-
[deep learning libraries](https://github.com/fastai/fastai), [API
|
|
232
|
-
clients](https://github.com/fastai/ghapi), [Python language
|
|
233
|
-
extensions](https://github.com/fastai/fastcore), [terminal user
|
|
234
|
-
interfaces](https://github.com/nat/ghtop), and more!
|
|
168
|
+
A: [Watch this video](https://youtu.be/9Q6sLbz37gk). Don’t worry, we still get this too, despite having used `nbdev` for a wide range of “very serious” software projects over the last three years, including [deep learning libraries](https://github.com/fastai/fastai), [API clients](https://github.com/fastai/ghapi), [Python language extensions](https://github.com/fastai/fastcore), [terminal user interfaces](https://github.com/nat/ghtop), and more!
|
|
235
169
|
|
|
236
170
|
## Contributing
|
|
237
171
|
|
|
238
|
-
If you want to contribute to `nbdev`, be sure to review the
|
|
239
|
-
[contributions
|
|
240
|
-
guidelines](https://github.com/fastai/nbdev/blob/master/CONTRIBUTING.md).
|
|
241
|
-
This project adheres to fastai’s [code of
|
|
242
|
-
conduct](https://github.com/fastai/nbdev/blob/master/CODE_OF_CONDUCT.md).
|
|
243
|
-
By participating, you are expected to uphold this code. In general, we
|
|
244
|
-
strive to abide by generally accepted best practices in open-source
|
|
245
|
-
software development.
|
|
172
|
+
If you want to contribute to `nbdev`, be sure to review the [contributions guidelines](https://github.com/fastai/nbdev/blob/master/CONTRIBUTING.md). This project adheres to fastai’s [code of conduct](https://github.com/fastai/nbdev/blob/master/CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. In general, we strive to abide by generally accepted best practices in open-source software development.
|
|
246
173
|
|
|
247
|
-
Make sure you have `nbdev`’s git hooks installed by running
|
|
248
|
-
`nbdev-install-hooks` in the cloned repository.
|
|
174
|
+
Make sure you have `nbdev`’s git hooks installed by running `nbdev-install-hooks` in the cloned repository.
|
|
249
175
|
|
|
250
176
|
## Copyright
|
|
251
177
|
|
|
252
|
-
Copyright © 2019 onward fast.ai, Inc. Licensed under the Apache License,
|
|
253
|
-
Version 2.0 (the “License”); you may not use this project’s files except
|
|
254
|
-
in compliance with the License. A copy of the License is provided in the
|
|
255
|
-
LICENSE file in this repository.
|
|
178
|
+
Copyright © 2019 onward fast.ai, Inc. Licensed under the Apache License, Version 2.0 (the “License”); you may not use this project’s files except in compliance with the License. A copy of the License is provided in the LICENSE file in this repository.
|
nbdev-3.2.1/README.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Getting Started
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->
|
|
5
|
+
|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
## 🛑**Jan 2026 Major Version Update – Breaking Change**🛑
|
|
9
|
+
|
|
10
|
+
**nbdev3 is here!** As many of you have been requesting, configuration has moved from `settings.ini` to `pyproject.toml`, following modern Python packaging standards ([PEP 621](https://peps.python.org/pep-0621/)). Your project metadata now lives in the standard `[project]` section, while nbdev-specific settings go in `[tool.nbdev]`.
|
|
11
|
+
|
|
12
|
+
**Migrating from nbdev2:** Run `nbdev-migrate-config` in your project root to automatically convert your `settings.ini` to `pyproject.toml` and update your GitHub Actions workflows to use nbdev3-compatible versions. Your existing notebooks and code don’t need any changes.
|
|
13
|
+
|
|
14
|
+
`nbdev` is a notebook-driven development platform. Simply write notebooks with lightweight markup and get high-quality documentation, tests, continuous integration, and packaging for free!
|
|
15
|
+
|
|
16
|
+
`nbdev` makes debugging and refactoring your code much easier than in traditional programming environments since you always have live objects at your fingertips. `nbdev` also promotes software engineering best practices because tests and documentation are first class.
|
|
17
|
+
|
|
18
|
+
- **Documentation** is automatically generated using [Quarto](https://quarto.org/) and hosted on [GitHub Pages](https://pages.github.com/). Docs support LaTeX, are searchable, and are automatically hyperlinked (including out-of-the-box support for many packages via [`nbdev-index`](https://github.com/fastai/nbdev-index))
|
|
19
|
+
- **Publish packages to PyPI and conda** as well as tools to simplify package releases. Python best practices are automatically followed, for example, only exported objects are included in `__all__`
|
|
20
|
+
- **Two-way sync between notebooks and plaintext source code** allowing you to use your IDE for code navigation or quick edits. Sync is robust: each exported cell is tagged with its unique notebook cell ID, so `nbdev-update` always updates the correct cell
|
|
21
|
+
- **Tests** written as ordinary notebook cells are run in parallel with a single command
|
|
22
|
+
- **Continuous integration** out-of-the-box with [GitHub Actions](https://github.com/features/actions) that run your tests and rebuild your docs
|
|
23
|
+
- **Git-friendly notebooks** with [Jupyter/Git hooks](https://nbdev.fast.ai/tutorials/git_friendly_jupyter.html) that clean unwanted metadata and render merge conflicts in a human-readable format
|
|
24
|
+
- … and much more!
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
nbdev works on macOS, Linux, and most Unix-style operating systems. It works on Windows under WSL, but not under cmd or Powershell.
|
|
29
|
+
|
|
30
|
+
You can install nbdev with pip:
|
|
31
|
+
|
|
32
|
+
``` sh
|
|
33
|
+
pip install nbdev
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Note that `nbdev` must be installed into the same Python environment that you use for both Jupyter and your project.
|
|
37
|
+
|
|
38
|
+
## How to use nbdev
|
|
39
|
+
|
|
40
|
+
The best way to learn how to use nbdev is to complete either the [written walkthrough](https://nbdev.fast.ai/tutorials/tutorial.html) or video walkthrough:
|
|
41
|
+
|
|
42
|
+
<a href="http://www.youtube.com/watch?v=l7zS8Ld4_iA" target="_blank" title="nbdev walkthrough"><img src="https://github.com/fastai/logos/raw/main/nbdev_walkthrough.png" style="border-radius: 10px" width="560" height="315" /></a>
|
|
43
|
+
|
|
44
|
+
Alternatively, there’s a [shortened version of the video walkthrough](https://youtu.be/67FdzLSt4aA) with coding sections sped up using the `unsilence` Python library – it’s 27 minutes faster, but a bit harder to follow.
|
|
45
|
+
|
|
46
|
+
You can also run `nbdev-help` from the terminal to see the full list of available commands:
|
|
47
|
+
|
|
48
|
+
``` python
|
|
49
|
+
!nbdev-help
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
nb-export Export a single nbdev notebook to a python script.
|
|
53
|
+
nbdev-bump-version Increment version in __init__.py by one
|
|
54
|
+
nbdev-changelog Create a CHANGELOG.md file from closed and labeled GitHub issues
|
|
55
|
+
nbdev-clean Clean all notebooks in `fname` to avoid merge conflicts
|
|
56
|
+
nbdev-conda Create a `meta.yaml` file ready to be built into a package, and optionally build and upload it
|
|
57
|
+
nbdev-contributing Create CONTRIBUTING.md from contributing_nb (defaults to 'contributing.ipynb' if present). Skips if the file doesn't exist.
|
|
58
|
+
nbdev-create-config Create a pyproject.toml config file.
|
|
59
|
+
nbdev-docs Create Quarto docs and README.md
|
|
60
|
+
nbdev-export Export notebooks in `path` to Python modules
|
|
61
|
+
nbdev-filter A notebook filter for Quarto
|
|
62
|
+
nbdev-fix Create working notebook from conflicted notebook `nbname`
|
|
63
|
+
nbdev-help Show help for all console scripts
|
|
64
|
+
nbdev-install Install Quarto and the current library
|
|
65
|
+
nbdev-install-hooks Install Jupyter and git hooks to automatically clean, trust, and fix merge conflicts in notebooks
|
|
66
|
+
nbdev-install-quarto Install latest Quarto on macOS or Linux, prints instructions for Windows
|
|
67
|
+
nbdev-merge Git merge driver for notebooks
|
|
68
|
+
nbdev-migrate Convert all markdown and notebook files in `path` from v1 to v2
|
|
69
|
+
nbdev-migrate-config Migrate settings.ini to pyproject.toml
|
|
70
|
+
nbdev-new Create an nbdev project.
|
|
71
|
+
nbdev-prepare Export, test, and clean notebooks, and render README if needed
|
|
72
|
+
nbdev-preview Preview docs locally
|
|
73
|
+
nbdev-proc-nbs Process notebooks in `path` for docs rendering
|
|
74
|
+
nbdev-pypi Create and upload Python package to PyPI
|
|
75
|
+
nbdev-readme Create README.md from readme_nb (index.ipynb by default)
|
|
76
|
+
nbdev-release-both Release both conda and PyPI packages
|
|
77
|
+
nbdev-release-gh Calls `nbdev-changelog`, lets you edit the result, then pushes to git and calls `nbdev-release-git`
|
|
78
|
+
nbdev-release-git Tag and create a release in GitHub for the current version
|
|
79
|
+
nbdev-requirements Writes a `requirements.txt` file to `directory` based on pyproject.toml.
|
|
80
|
+
nbdev-sidebar Create sidebar.yml
|
|
81
|
+
nbdev-test Test in parallel notebooks matching `path`, passing along `flags`
|
|
82
|
+
nbdev-trust Trust notebooks matching `fname`.
|
|
83
|
+
nbdev-update Propagate change in modules matching `fname` to notebooks that created them
|
|
84
|
+
nbdev-update-license Allows you to update the license of your project.
|
|
85
|
+
watch-export Use `nb_export` on ipynb files in `nbs` directory on changes using nbdev config if available
|
|
86
|
+
|
|
87
|
+
## FAQ
|
|
88
|
+
|
|
89
|
+
### Q: What is the warning “Found a cell containing mix of imports and computations. Please use separate cells”?
|
|
90
|
+
|
|
91
|
+
A: You should not have cells that are not exported, *and* contain a mix of `import` statements along with other code. For instance, don’t do this in a single cell:
|
|
92
|
+
|
|
93
|
+
``` python
|
|
94
|
+
import some_module
|
|
95
|
+
some_module.something()
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Instead, split this into two cells, one which does `import some_module`, and the other which does `some_module.something()`.
|
|
99
|
+
|
|
100
|
+
Only top-level statements count: `try: import` blocks and imports inside function definitions are fine.
|
|
101
|
+
|
|
102
|
+
The reason for this is that when we create your documentation website, we ensure that all of the signatures for functions you document are up to date, by running the imports, exported cells, and [`show_doc`](https://nbdev.fast.ai/api/showdoc.html#show_doc) functions in your notebooks. When you mix imports with other code, that other code will be run too, which can cause errors (or at least slowdowns) when creating your website.
|
|
103
|
+
|
|
104
|
+
### Q: Why is nbdev asking for root access? How do I install Quarto without root access?
|
|
105
|
+
|
|
106
|
+
A: When you setup your first project, nbdev will attempt to automatically download and install [Quarto](https://quarto.org/) for you. This is the program that we use to create your documentation website.
|
|
107
|
+
|
|
108
|
+
Quarto’s standard installation process requires root access, and nbdev will therefore ask for your root password during installation. For most people, this will work fine and everything will be handled automatically – if so, you can skip over the rest of this section, which talks about installing without root access.
|
|
109
|
+
|
|
110
|
+
If you need to install Quarto without root access on Linux, first `cd` to wherever you want to store it, then [download Quarto](https://quarto.org/docs/get-started/), and type:
|
|
111
|
+
|
|
112
|
+
``` bash
|
|
113
|
+
dpkg -x quarto*.deb .
|
|
114
|
+
mv opt/quarto ./
|
|
115
|
+
rmdir opt
|
|
116
|
+
mkdir -p ~/.local/bin
|
|
117
|
+
ln -s "$(pwd)"/quarto/bin/quarto ~/.local/bin
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
To use this non-root version of Quarto, you’ll need `~/.local/bin` in your [`PATH` environment variable](https://linuxize.com/post/how-to-add-directory-to-path-in-linux/). (Alternatively, change the `ln -s` step to place the symlink somewhere else in your path.)
|
|
121
|
+
|
|
122
|
+
### Q: Someone told me not to use notebooks for “serious” software development!
|
|
123
|
+
|
|
124
|
+
A: [Watch this video](https://youtu.be/9Q6sLbz37gk). Don’t worry, we still get this too, despite having used `nbdev` for a wide range of “very serious” software projects over the last three years, including [deep learning libraries](https://github.com/fastai/fastai), [API clients](https://github.com/fastai/ghapi), [Python language extensions](https://github.com/fastai/fastcore), [terminal user interfaces](https://github.com/nat/ghtop), and more!
|
|
125
|
+
|
|
126
|
+
## Contributing
|
|
127
|
+
|
|
128
|
+
If you want to contribute to `nbdev`, be sure to review the [contributions guidelines](https://github.com/fastai/nbdev/blob/master/CONTRIBUTING.md). This project adheres to fastai’s [code of conduct](https://github.com/fastai/nbdev/blob/master/CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. In general, we strive to abide by generally accepted best practices in open-source software development.
|
|
129
|
+
|
|
130
|
+
Make sure you have `nbdev`’s git hooks installed by running `nbdev-install-hooks` in the cloned repository.
|
|
131
|
+
|
|
132
|
+
## Copyright
|
|
133
|
+
|
|
134
|
+
Copyright © 2019 onward fast.ai, Inc. Licensed under the Apache License, Version 2.0 (the “License”); you may not use this project’s files except in compliance with the License. A copy of the License is provided in the LICENSE file in this repository.
|
|
@@ -225,6 +225,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
225
225
|
'nbdev.processors._is_showdoc': ('api/processors.html#_is_showdoc', 'nbdev/processors.py'),
|
|
226
226
|
'nbdev.processors._re_hideline': ('api/processors.html#_re_hideline', 'nbdev/processors.py'),
|
|
227
227
|
'nbdev.processors._show_docs': ('api/processors.html#_show_docs', 'nbdev/processors.py'),
|
|
228
|
+
'nbdev.processors._tl_contains': ('api/processors.html#_tl_contains', 'nbdev/processors.py'),
|
|
228
229
|
'nbdev.processors._want_doc': ('api/processors.html#_want_doc', 'nbdev/processors.py'),
|
|
229
230
|
'nbdev.processors.add_fold': ('api/processors.html#add_fold', 'nbdev/processors.py'),
|
|
230
231
|
'nbdev.processors.add_links': ('api/processors.html#add_links', 'nbdev/processors.py'),
|
|
@@ -282,11 +283,13 @@ d = { 'settings': { 'branch': 'main',
|
|
|
282
283
|
'nbdev.quarto._copytree': ('api/quarto.html#_copytree', 'nbdev/quarto.py'),
|
|
283
284
|
'nbdev.quarto._doc_mtime_not_older': ('api/quarto.html#_doc_mtime_not_older', 'nbdev/quarto.py'),
|
|
284
285
|
'nbdev.quarto._ensure_quarto': ('api/quarto.html#_ensure_quarto', 'nbdev/quarto.py'),
|
|
286
|
+
'nbdev.quarto._fix_quarto_nav': ('api/quarto.html#_fix_quarto_nav', 'nbdev/quarto.py'),
|
|
285
287
|
'nbdev.quarto._install_linux': ('api/quarto.html#_install_linux', 'nbdev/quarto.py'),
|
|
286
288
|
'nbdev.quarto._install_mac': ('api/quarto.html#_install_mac', 'nbdev/quarto.py'),
|
|
287
289
|
'nbdev.quarto._nbglob_docs': ('api/quarto.html#_nbglob_docs', 'nbdev/quarto.py'),
|
|
288
290
|
'nbdev.quarto._pre': ('api/quarto.html#_pre', 'nbdev/quarto.py'),
|
|
289
291
|
'nbdev.quarto._pre_docs': ('api/quarto.html#_pre_docs', 'nbdev/quarto.py'),
|
|
292
|
+
'nbdev.quarto._readme_cands': ('api/quarto.html#_readme_cands', 'nbdev/quarto.py'),
|
|
290
293
|
'nbdev.quarto._recursive_parser': ('api/quarto.html#_recursive_parser', 'nbdev/quarto.py'),
|
|
291
294
|
'nbdev.quarto._save_cached_contributing': ('api/quarto.html#_save_cached_contributing', 'nbdev/quarto.py'),
|
|
292
295
|
'nbdev.quarto._save_cached_readme': ('api/quarto.html#_save_cached_readme', 'nbdev/quarto.py'),
|
|
@@ -336,6 +339,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
336
339
|
'nbdev.release.write_requirements': ('api/release.html#write_requirements', 'nbdev/release.py')},
|
|
337
340
|
'nbdev.scrubmagics': {},
|
|
338
341
|
'nbdev.serve': { 'nbdev.serve._is_qpy': ('api/serve.html#_is_qpy', 'nbdev/serve.py'),
|
|
342
|
+
'nbdev.serve._keep_file': ('api/serve.html#_keep_file', 'nbdev/serve.py'),
|
|
339
343
|
'nbdev.serve._proc_file': ('api/serve.html#_proc_file', 'nbdev/serve.py'),
|
|
340
344
|
'nbdev.serve.proc_nbs': ('api/serve.html#proc_nbs', 'nbdev/serve.py')},
|
|
341
345
|
'nbdev.serve_drv': {},
|
|
@@ -169,18 +169,21 @@ async def nbdev_update_license(
|
|
|
169
169
|
# %% ../nbs/api/13_cli.ipynb #412b4cd2
|
|
170
170
|
@call_parse
|
|
171
171
|
@delegates(nb_export, but=['procs', 'mod_maker'])
|
|
172
|
-
def nb_export_cli(
|
|
173
|
-
|
|
174
|
-
|
|
172
|
+
def nb_export_cli(
|
|
173
|
+
nbname,
|
|
174
|
+
debug:store_true=False, # Debug flag
|
|
175
|
+
**kwargs
|
|
176
|
+
):
|
|
175
177
|
"Export a single nbdev notebook to a python script."
|
|
176
178
|
return nb_export(nbname=nbname, debug=debug, **kwargs)
|
|
177
179
|
|
|
178
180
|
# %% ../nbs/api/13_cli.ipynb #aaa472e7
|
|
179
181
|
@call_parse
|
|
180
|
-
def watch_export(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
def watch_export(
|
|
183
|
+
nbs:str=None, # Nb directory to watch for changes
|
|
184
|
+
lib:str=None, # Export directory to write py files to
|
|
185
|
+
force:bool=False # Ignore nbdev config if in nbdev project
|
|
186
|
+
):
|
|
184
187
|
'''Use `nb_export` on ipynb files in `nbs` directory on changes using nbdev config if available'''
|
|
185
188
|
cfg = get_config() if is_nbdev() else None
|
|
186
189
|
nbs = nbs or (cfg.nbs_path if cfg else '.')
|
|
@@ -236,7 +236,7 @@ def get_config(path=None, also_settings=False):
|
|
|
236
236
|
nbdev = {**user, **d.get('tool', {}).get('nbdev', {})}
|
|
237
237
|
return ConfigToml(nbdev, d.get('project', {}), cfg_file)
|
|
238
238
|
if also_settings:
|
|
239
|
-
from fastcore.
|
|
239
|
+
from fastcore.xtras import Config
|
|
240
240
|
cfg = Config.find('settings.ini', path)
|
|
241
241
|
if cfg: return cfg
|
|
242
242
|
cfg_path = Path(path or Path.cwd()).expanduser().absolute()
|
|
@@ -265,7 +265,8 @@ def nbpath2docurl(nb_path):
|
|
|
265
265
|
"Hosted docs URL (with `.md` suffix) for notebook `nb_path`, or '' if no `doc_host`"
|
|
266
266
|
cfg = get_config()
|
|
267
267
|
if not cfg.doc_host: return ''
|
|
268
|
-
p = Path(nb_path).resolve().relative_to(cfg.path('nbs_path'))
|
|
268
|
+
try: p = Path(nb_path).resolve().relative_to(cfg.path('nbs_path'))
|
|
269
|
+
except ValueError: return ""
|
|
269
270
|
return f"{cfg.doc_host.rstrip('/')}{cfg.doc_baseurl.rstrip('/')}/{nbpath2html(p).as_posix()}.md"
|
|
270
271
|
|
|
271
272
|
# %% ../nbs/api/01_config.ipynb #163177f2
|
|
@@ -36,14 +36,15 @@ class ExportModuleProc:
|
|
|
36
36
|
_exports_=_export_
|
|
37
37
|
|
|
38
38
|
# %% ../nbs/api/04_export.ipynb #76717e36
|
|
39
|
-
def nb_export(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
def nb_export(
|
|
40
|
+
nbname:str, # Filename of notebook
|
|
41
|
+
lib_path:str=None, # Path to destination library. If not in a nbdev project, defaults to current directory.
|
|
42
|
+
procs=None, # Processors to use
|
|
43
|
+
name:str=None, # Name of python script {name}.py to create.
|
|
44
|
+
mod_maker=ModuleMaker,
|
|
45
|
+
debug:bool=False, # Debug mode
|
|
46
|
+
solo_nb:bool=False # Export single notebook outside of an nbdev project.
|
|
47
|
+
):
|
|
47
48
|
"Create module(s) from notebook"
|
|
48
49
|
if lib_path is None: lib_path = get_config().lib_path if is_nbdev() else '.'
|
|
49
50
|
exp = ExportModuleProc()
|
|
@@ -60,11 +60,13 @@ def _merge_cells(a, b, brancha, branchb, theirs):
|
|
|
60
60
|
|
|
61
61
|
# %% ../nbs/api/07_merge.ipynb #cc492d30
|
|
62
62
|
@call_parse
|
|
63
|
-
def nbdev_fix(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
def nbdev_fix(
|
|
64
|
+
nbname:str, # Notebook filename to fix
|
|
65
|
+
outname:str=None, # Filename of output notebook (defaults to `nbname`)
|
|
66
|
+
nobackup:bool_arg=True, # Do not backup `nbname` to `nbname`.bak if `outname` not provided
|
|
67
|
+
theirs:bool=False, # Use their outputs and metadata instead of ours
|
|
68
|
+
noprint:bool=False # Do not print info about whether conflicts are found
|
|
69
|
+
):
|
|
68
70
|
"Create working notebook from conflicted notebook `nbname`"
|
|
69
71
|
nbname = Path(nbname)
|
|
70
72
|
if not nobackup and not outname: shutil.copy(nbname, nbname.with_suffix('.ipynb.bak'))
|
|
@@ -32,11 +32,12 @@ def _file_slug(fname):
|
|
|
32
32
|
return dt + p.stem[11:]
|
|
33
33
|
|
|
34
34
|
# %% ../nbs/api/16_migrate.ipynb #689bf354
|
|
35
|
-
def _replace_fm(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
def _replace_fm(
|
|
36
|
+
d:dict, # dictionary you wish to conditionally change
|
|
37
|
+
k:str, # key to check
|
|
38
|
+
val:str,# value to check if d[k] == v
|
|
39
|
+
repl_dict:dict #dictionary that will be used as a replacement
|
|
40
|
+
):
|
|
40
41
|
"replace key `k` in dict `d` if d[k] == val with `repl_dict`"
|
|
41
42
|
if str(d.get(k, '')).lower().strip() == str(val.lower()).strip():
|
|
42
43
|
d.pop(k)
|
|
@@ -191,8 +192,9 @@ def _migrate_workflows(path):
|
|
|
191
192
|
wf_path = Path(path) / '.github/workflows'
|
|
192
193
|
if not wf_path.exists(): return
|
|
193
194
|
replacements = [
|
|
194
|
-
('fastai/workflows/quarto-ghp@', '
|
|
195
|
-
('fastai/workflows/nbdev-ci@', '
|
|
195
|
+
('fastai/workflows/quarto-ghp@', 'AnswerDotAI/workflows/quarto-ghp3@'),
|
|
196
|
+
('fastai/workflows/nbdev-ci@', 'AnswerDotAI/workflows/nbdev3-ci@'),
|
|
197
|
+
('fastai/workflows/', 'AnswerDotAI/workflows/'),
|
|
196
198
|
]
|
|
197
199
|
for f in (*wf_path.glob('*.yml'), *wf_path.glob('*.yaml')):
|
|
198
200
|
txt = f.read_text()
|
|
@@ -182,11 +182,15 @@ def ai_magics(cell):
|
|
|
182
182
|
cell.source = '\n'.join(cell.source.splitlines()[1:])
|
|
183
183
|
|
|
184
184
|
# %% ../nbs/api/10_processors.ipynb #5a9c8fd4
|
|
185
|
-
|
|
185
|
+
_def_strip_magics = '%load_ext %autoreload %reload_ext %matplotlib %config'
|
|
186
186
|
|
|
187
187
|
def clean_magics(cell):
|
|
188
|
-
"
|
|
189
|
-
|
|
188
|
+
"Remove housekeeping magics: those named in the `strip_magics` config (space-separated, default `_def_strip_magics`)"
|
|
189
|
+
mm = str(get_config().get('strip_magics', _def_strip_magics)).split()
|
|
190
|
+
if not mm or cell.cell_type != 'code': return
|
|
191
|
+
pat = re.compile(rf"^\s*({'|'.join(re.escape(m) for m in mm)})\b.*", re.MULTILINE)
|
|
192
|
+
cell.source = pat.sub('', cell.source).strip()
|
|
193
|
+
|
|
190
194
|
|
|
191
195
|
# %% ../nbs/api/10_processors.ipynb #93e27a52
|
|
192
196
|
_re_hdr_dash = re.compile(r'^#+\s+.*\s+-\s*$', re.MULTILINE)
|
|
@@ -223,6 +227,8 @@ def _ast_contains(trees, types):
|
|
|
223
227
|
for node in ast.walk(tree):
|
|
224
228
|
if isinstance(node, types): return True
|
|
225
229
|
|
|
230
|
+
def _tl_contains(trees, types): return any(isinstance(t, types) for t in trees)
|
|
231
|
+
|
|
226
232
|
def _do_eval(cell):
|
|
227
233
|
if cell_lang(cell) != 'python': return
|
|
228
234
|
if not cell.source or 'nbdev_export'+'()' in cell.source: return
|
|
@@ -233,7 +239,7 @@ def _do_eval(cell):
|
|
|
233
239
|
_show_dirs = {'export','exports','exporti','exec_doc'}
|
|
234
240
|
if cell.directives_.keys() & _show_dirs: return True
|
|
235
241
|
if _ast_contains(trees, (ast.Import, ast.ImportFrom)):
|
|
236
|
-
if
|
|
242
|
+
if _tl_contains(trees, (ast.Import, ast.ImportFrom)) and _tl_contains(trees, (ast.Expr, ast.Assign)):
|
|
237
243
|
warn(f'Found cells containing imports and other code. See FAQ.\n---\n{cell.source}\n---\n')
|
|
238
244
|
return True
|
|
239
245
|
if _show_docs(trees): return True
|