nbd

Extra command line utilities for nbdev
path = Path("../..")
Path.BASE_PATH = path

source

make_things_pretty

 make_things_pretty ()

source

nbd_new_fn

 nbd_new_fn (name:str, description:str, license:str='Apache-2.0',
             private:bool=False)

Create a new nbdev project and setup github repo for it


source

nbd_new

 nbd_new (name:str, description:str, license:str='Apache-2.0',
          private:bool=False)

Create a new nbdev project and setup github repo for it


source

new_notebook_template

 new_notebook_template (name, description)

FIXME: Cell below results in an error for some reason

template = new_notebook_template("foo", "Makes foo using bar")
print('\n---\n\n'.join(L(template['cells']).attrgot('source').map(''.join)))
# foo

> Makes foo using bar
---

#| default_exp foo
---

#| hide
from nbdev.showdoc import *
---

#| export
from fastcore.all import *
---

#| hide
import nbdev; nbdev.nbdev_export()
m = re.match(r'(\d+).*\.ipynb', '99ab_asd.ipynb')
m.group(1)
'99'

source

zero_pad

 zero_pad (num)
test_eq(zero_pad(9), '09')
test_eq(zero_pad(32), '32')

source

nbd_add

 nbd_add (name:str, description:str, at:Optional[int]=None)

Add new notebook to the project

Type Default Details
name str
description str
at Optional None If specified, insert new notebook at a specific position

nbd_watch

Adapted from https://github.com/ProCern/asyncinotify/blob/master/examples/recursivewatch.py


source

get_directories_recursive

 get_directories_recursive (path:pathlib.Path)
list(get_directories_recursive(Path('.')))
[Path('.'),
 Path('.ipynb_checkpoints'),
 Path('02_nbd'),
 Path('02_nbd/favicons'),
 Path('02_nbd/favicons/arlantr'),
 Path('02_nbd/favicons/food-ocal'),
 Path('02_nbd/favicons/food-ocal/vegetable'),
 Path('02_nbd/favicons/food-ocal/treat'),
 Path('02_nbd/favicons/food-ocal/pasta'),
 Path('02_nbd/favicons/food-ocal/fruit'),
 Path('02_nbd/favicons/food-ocal/drink'),
 Path('02_nbd/favicons/food-ocal/dairy'),
 Path('02_nbd/favicons/food-ocal/meat')]

Algorithm: 1. Watch forever until an event happens. 2. After that, watch for 1s. If no more events fire, yield an event. Go back to step 1. 3. If more events fire in that 1s, record those events and go back to step 2.

Extra features: 1. If new directories are added, mark them for watching. 2. Skip events we are not interested in


source

watch_new_directories

 watch_new_directories (inotify, event)

source

extract_exports

 extract_exports (file)

source

get_hash

 get_hash (s)
get_hash("hello, world!")
b'h\xe6V\xb2Q\xe6~\x83X\xbe\xf8H:\xb0\xd5\x1cf\x19\xf3\xe7\xa1\xa9\xf0\xe7X8\xd4\x1f\xf3h\xf7('

source

setup_tracking

 setup_tracking (path)
tracked_files = setup_tracking(Path('.'))
list(get_directories_recursive(Path('.')))[1].name
'.ipynb_checkpoints'
tracked_files.keys()
dict_keys([Path('00_core.ipynb'), Path('01_gh.ipynb'), Path('03_kgl.ipynb'), Path('02_nbd.ipynb'), Path('04_format.ipynb')])
s = "hello"
s.encode("utf-8")
b'hello'
re.match(r'^(?!\.\~).+\.ipynb$', '.~00_core.ipynb')
f = list(get_directories_recursive(Path('.')))[0].ls()[0]
print('\n'.join([''.join(x['source']) for x in f.read_json()['cells'] if x['cell_type'] == 'code' and 'export' in ''.join(x['source'])]))
#| export
from fastcore.all import *
#| export
def pad(s: str, pad_to: int):
    "Pad `s` with spaces to the right"
    return s + " " * max(0, (pad_to - len(s)))
#| export
def attrkey(attr):
    "Create a function that fetches `attr` of its input"
    return lambda x: getattr(x, attr)
#| export
def str_enumerate(lst: list,
                  start: int = 0 # enumerate from what number
                 ) -> Iterable[str]:
    "Create aligned sequence of numbered strings for strings in `lst`"
    return map(lambda x: f"  {pad(str(x[0]),2)}  {x[1]}", enumerate(lst, start))
#| export
def cz(*funcs):
    "Compose functions together"
    def fn(x):
        for fn in funcs:
            x = fn(x)
        return x
    return fn
#| hide
import nbdev; nbdev.nbdev_export()

source

inotify_watch

 inotify_watch (path, debounce_interval=0.5)
s = '.~04_core.ipynb'
s.startswith('.~')
True
Path('/user/home/.~04_core.ipynb').name
'.~04_core.ipynb'

Right now, it seems the best way to figure out when user actually saves is to count number of events: - Saving file manually results in at least 13 events, while autosave only produces 9 events (sometimes 10).

k = re.match(r'\.\~(.*.ipynb)', '.~04_core.ipynb')
k.group(1)
'04_core.ipynb'

source

get_files_updated

 get_files_updated (events)
p = Path('nbs/api/02_nbd.ipynb')
p.parent
Path('nbs/api')
p.relative_to(Path('nbs')).as_posix()
'api/02_nbd.ipynb'

source

anything_updated

 anything_updated (tracked_files, events)

source

nbd_watch

 nbd_watch ()

Watch nbs folder and automatically run nbdev_export on file change