{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#default_exp notebook.showdoc" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# export\n", "from local.core.imports import *\n", "from local.notebook.core import *\n", "from local.notebook.export import *\n", "import inspect,enum,nbconvert\n", "from IPython.display import Markdown,display\n", "from IPython.core import page\n", "from nbconvert import HTMLExporter" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Show doc\n", "> Functions to show the doc cells in notebooks" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from local.core.foundation import add_docs, patch\n", "from local.core.utils import compose\n", "from local.core.transform import Pipeline\n", "from local.data.external import untar_data\n", "\n", "test_cases = [\n", " Pipeline, #Basic class\n", " compose, #Func with star args and type annotation\n", " untar_data, #Func with defaults\n", " add_docs, #Func with kwargs\n", " Path.ls #Monkey-patched\n", "]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Gather the information" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The inspect module lets us know quickly if an object is a function or a class but it doesn't distinguish classes and enums." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# export\n", "def is_enum(cls):\n", " \"Check if `cls` is an enum or another type of class\"\n", " return type(cls) in (enum.Enum, enum.EnumMeta)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "e = enum.Enum('e', 'a b')\n", "assert is_enum(e)\n", "assert not is_enum(Pipeline)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Links" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#hide\n", "#Tricking jupyter notebook to have a __file__ attribute. All _file_ will be replaced by __file__\n", "_file_ = Path('local').absolute()/'notebook'/'show_doc.py'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We don't link to all PyTorch functions, just the ones in an index we keep. We can easily add a reference with the following convenience function when writing the docs." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# export\n", "def _get_pytorch_index():\n", " if not (Path(_file_).parent/'index_pytorch.txt').exists(): return {}\n", " return json.load(open(Path(_file_).parent/'index_pytorch.txt', 'r'))\n", "\n", "def add_pytorch_index(func_name, url):\n", " \"Add `func_name` in the PyTorch index for automatic links.\"\n", " index = _get_pytorch_index()\n", " if not url.startswith(\"https://pytorch.org/docs/stable/\"):\n", " url = \"https://pytorch.org/docs/stable/\" + url\n", " index[func_name] = url\n", " json.dump(index, open(Path(_file_).parent/'index_pytorch.txt', 'w'), indent=2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`url` can be the full url or just the part after `https://pytorch.org/docs/stable/`, see the example below." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#hide\n", "ind,ind_bak = Path(_file_).parent/'index_pytorch.txt',Path(_file_).parent/'index_pytorch.bak'\n", "if ind.exists(): shutil.move(ind, ind_bak)\n", "assert _get_pytorch_index() == {}\n", "add_pytorch_index('Tensor', 'tensors.html#torch-tensor')\n", "assert _get_pytorch_index() == {'Tensor':'https://pytorch.org/docs/stable/tensors.html#torch-tensor'}\n", "if ind_bak.exists(): shutil.move(ind_bak, ind)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "add_pytorch_index('Tensor', 'tensors.html#torch-tensor')\n", "add_pytorch_index('device', 'tensor_attributes.html#torch-device')\n", "add_pytorch_index('DataLoader', 'data.html#torch.utils.data.DataLoader')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# export\n", "def is_fastai_module(name):\n", " \"Test if `name` is a fastai module.\"\n", " dir_name = os.path.sep.join(name.split('.'))\n", " return (Path(_file_).parent.parent/f\"{dir_name}.py\").exists()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "assert is_fastai_module('data.external')\n", "assert is_fastai_module('learner')\n", "assert not is_fastai_module('export')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# export\n", "#Might change once the library is renamed fastai.\n", "def _is_fastai_class(ft): return belongs_to_module(ft, 'fastai_source')\n", "def _strip_fastai(s): return re.sub(r'^local\\.', '', s)\n", "FASTAI_DOCS = ''" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# export\n", "def doc_link(name, include_bt:bool=True):\n", " \"Create link to documentation for `name`.\"\n", " cname = f'`{name}`' if include_bt else name\n", " #Link to modules\n", " if is_fastai_module(name): return f'[{cname}]({FASTAI_DOCS}/{name}.html)'\n", " #Link to fastai functions\n", " try_fastai = source_nb(name, is_name=True)\n", " if try_fastai:\n", " page = '.'.join(try_fastai.split('_')[1:]).replace('.ipynb', '.html')\n", " return f'[{cname}]({FASTAI_DOCS}/{page}#{name})'\n", " #Link to PyTorch\n", " try_pytorch = _get_pytorch_index().get(name, None)\n", " if try_pytorch: return f'[{cname}]({try_pytorch})'\n", " #Leave as is\n", " return cname" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "assert doc_link('core.transform') == f'[`core.transform`]({FASTAI_DOCS}/core.transform.html)'\n", "assert doc_link('Pipeline') == f'[`Pipeline`]({FASTAI_DOCS}/core.transform.html#Pipeline)'\n", "assert doc_link('Transform.create') == f'[`Transform.create`]({FASTAI_DOCS}/core.transform.html#Transform.create)'\n", "assert doc_link('Tensor') == '[`Tensor`](https://pytorch.org/docs/stable/tensors.html#torch-tensor)'\n", "assert doc_link('Tenso') == '`Tenso`'" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "_re_backticks = re.compile(r\"\"\"\n", "# Catches any link of the form \\[`obj`\\](old_link) or just `obj` to either update old links or add the link to the docs of obj\n", "\\[` # Opening [ and `\n", "([^`]*) # Catching group with anything but a `\n", "`\\] # ` then closing ]\n", "(?: # Beginning of non-catching group\n", "\\( # Opening (\n", "[^)]* # Anything but a closing )\n", "\\) # Closing )\n", ") # End of non-catching group\n", "| # OR\n", "` # Opening `\n", "([^`]*) # Antyhing but a `\n", "` # Closing `\n", "\"\"\", re.VERBOSE)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# export\n", "def add_doc_links(text):\n", " \"Search for doc links for any item between backticks in `text`.\"\n", " def _replace_link(m): return doc_link(m.group(1) or m.group(2))\n", " return _re_backticks.sub(_replace_link, text)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This function not only add links to backstick keywords, it also update the links that are already in the text." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tst = add_doc_links('This is an example of `Pipeline`')\n", "assert tst == \"This is an example of [`Pipeline`](/core.transform.html#Pipeline)\"\n", "tst = add_doc_links('Here we alread add a link in [`Tensor`](fake)')\n", "assert tst == \"Here we alread add a link in [`Tensor`](https://pytorch.org/docs/stable/tensors.html#torch-tensor)\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Links to source" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "def _is_type_dispatch(x): return type(x).__name__ == \"TypeDispatch\"\n", "def _unwrapped_type_dispatch_func(x): return x.first() if _is_type_dispatch(x) else x\n", "\n", "def _is_property(x): return type(x)==property\n", "def _has_property_getter(x): return _is_property(x) and hasattr(x, 'fget') and hasattr(x.fget, 'func')\n", "def _property_getter(x): return x.fget.func if _has_property_getter(x) else x\n", "\n", "def _unwrapped_func(x):\n", " x = _unwrapped_type_dispatch_func(x)\n", " x = _property_getter(x)\n", " return x" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "SOURCE_URL = \"https://github.com/fastai/fastai_dev/tree/master/dev/\"\n", "\n", "def get_source_link(func):\n", " \"Return link to `func` in source code\"\n", " func = _unwrapped_func(func)\n", " try: line = inspect.getsourcelines(func)[1]\n", " except Exception: return ''\n", " module = inspect.getmodule(func).__name__.replace('.', '/') + '.py'\n", " return f\"{SOURCE_URL}{module}#L{line}\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#hide\n", "from local.data.transforms import Categorize, DataBunch\n", "assert get_source_link(Categorize.encodes).startswith(SOURCE_URL + 'local/data/transforms.py')\n", "assert get_source_link(DataBunch.train_dl).startswith(SOURCE_URL + 'local/data/core.py')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#hide\n", "assert get_source_link(Pipeline).startswith(SOURCE_URL + 'local/core/transform.py')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As important as the source code, we want to quickly jump to where the function is defined in a dev notebook." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "_re_header = re.compile(r\"\"\"\n", "# Catches any header in markdown with the title in group 1\n", "^\\s* # Beginning of text followed by any number of whitespace\n", "\\#+ # One # or more\n", "\\s* # Any number of whitespace\n", "(.*) # Catching group with anything\n", "$ # End of text\n", "\"\"\", re.VERBOSE)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "FASTAI_NB_DEV = 'https://nbviewer.jupyter.org/github/fastai/fastai_docs/blob/master/dev/'\n", "\n", "def get_nb_source_link(func, local=False, is_name=None):\n", " \"Return a link to the notebook where `func` is defined.\"\n", " func = _unwrapped_type_dispatch_func(func)\n", " pref = '' if local else FASTAI_NB_DEV\n", " is_name = is_name or isinstance(func, str)\n", " src = source_nb(func, is_name=is_name, return_all=True)\n", " if src is None: return '' if is_name else get_source_link(func)\n", " find_name,nb_name = src\n", " nb = read_nb(nb_name)\n", " pat = re.compile(f'^{find_name}\\s+=|^(def|class)\\s+{find_name}\\s*\\(', re.MULTILINE)\n", " if len(find_name.split('.')) == 2:\n", " clas,func = find_name.split('.')\n", " pat2 = re.compile(f'@patch\\s*\\ndef\\s+{func}\\s*\\([^:]*:\\s*{clas}\\s*(?:,|\\))')\n", " else: pat2 = None\n", " for i,cell in enumerate(nb['cells']):\n", " if cell['cell_type'] == 'code':\n", " if re.search(pat, cell['source']): break\n", " if pat2 is not None and re.search(pat2, cell['source']): break\n", " if re.search(pat, cell['source']) is None and (pat2 is not None and re.search(pat2, cell['source']) is None):\n", " return '' if is_name else get_function_source(func)\n", " header_pat = re.compile(r'^\\s*#+\\s*(.*)$')\n", " while i >= 0:\n", " cell = nb['cells'][i]\n", " if cell['cell_type'] == 'markdown' and _re_header.search(cell['source']):\n", " title = _re_header.search(cell['source']).groups()[0]\n", " anchor = '-'.join([s for s in title.split(' ') if len(s) > 0])\n", " return f'{pref}{nb_name}#{anchor}'\n", " i -= 1\n", " return f'{pref}{nb_name}'" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "assert get_nb_source_link(Pipeline.decode) == get_nb_source_link(Pipeline)\n", "assert get_nb_source_link('Pipeline') == get_nb_source_link(Pipeline)\n", "assert get_nb_source_link(patch) == f'{FASTAI_NB_DEV}01_core_foundation.ipynb#Foundational-functions'\n", "assert get_nb_source_link(patch, local=True) == f'01_core_foundation.ipynb#Foundational-functions'\n", "assert get_nb_source_link('Path.ls') == f'{FASTAI_NB_DEV}01a_core_utils.ipynb#File-and-network-functions'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can either pass an object or its name (by default `is_name` will look if `func` is a string or not, but you can override if there is some inconsistent behavior). `local` will return a local link." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# export\n", "def nb_source_link(func, is_name=None, disp=True):\n", " \"Show a relative link to the notebook where `func` is defined\"\n", " is_name = is_name or isinstance(func, str)\n", " func_name = func if is_name else qual_name(func)\n", " link = get_nb_source_link(func, local=True, is_name=is_name)\n", " if disp: display(Markdown(f'[{func_name}]({link})'))\n", " else: return link" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This function assumes you are in one notebook in the dev folder, otherwise you use `disp=False` to get the relative link. You can either pass an object or its name (by default `is_name` will look if `func` is a string or not, but you can override if there is some inconsistent behavior)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "[Pipeline](01c_core_transform.ipynb#Export--)" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "nb_source_link(Pipeline)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "assert nb_source_link(patch, disp=False) == f'01_core_foundation.ipynb#Foundational-functions'\n", "assert nb_source_link('patch', disp=False) == f'01_core_foundation.ipynb#Foundational-functions'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Show documentation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# export\n", "def type_repr(t):\n", " \"Representation of type `t` (in a type annotation)\"\n", " if getattr(t, '__args__', None):\n", " args = t.__args__\n", " if len(args)==2 and args[1] == type(None):\n", " return f'`Optional`\\[{type_repr(args[0])}\\]'\n", " reprs = ', '.join([type_repr(o) for o in args])\n", " return f'{doc_link(get_name(t))}\\[{reprs}\\]'\n", " else: return doc_link(get_name(t))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The representation tries to find doc links if possible." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from torch import Tensor" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tst = type_repr(Optional[Tensor])\n", "assert tst == '`Optional`\\\\[[`Tensor`](https://pytorch.org/docs/stable/tensors.html#torch-tensor)\\\\]'\n", "tst = type_repr(Union[Tensor, float])\n", "assert tst == '`Union`\\\\[[`Tensor`](https://pytorch.org/docs/stable/tensors.html#torch-tensor), `float`\\\\]'" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# export\n", "_arg_prefixes = {inspect._VAR_POSITIONAL: '\\*', inspect._VAR_KEYWORD:'\\*\\*'}\n", "\n", "def format_param(p):\n", " \"Formats function param to `param1:Type=val`. Font weights: param1=bold, val=italic\"\n", " arg_prefix = _arg_prefixes.get(p.kind, '') # asterisk prefix for *args and **kwargs\n", " res = f\"**{arg_prefix}`{p.name}`**\"\n", " if hasattr(p, 'annotation') and p.annotation != p.empty: res += f':{type_repr(p.annotation)}'\n", " if p.default != p.empty:\n", " default = getattr(p.default, 'func', p.default) #For partials\n", " default = getattr(default, '__name__', default) #Tries to find a name\n", " if is_enum(default.__class__): #Enum have a crappy repr\n", " res += f'=*`{default.__class__.__name__}.{default.name}`*'\n", " else: res += f'=*`{repr(default)}`*'\n", " return res" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sig = inspect.signature(untar_data)\n", "params = [format_param(p) for _,p in sig.parameters.items()]\n", "assert params == [\n", " '**`url`**',\n", " '**`fname`**=*`None`*',\n", " '**`dest`**=*`None`*',\n", " \"**`c_key`**=*`'data'`*\",\n", " '**`force_download`**=*`False`*',\n", " \"**`extract_func`**=*`'tar_extract'`*\"]\n", "\n", "sig = inspect.signature(compose)\n", "params = [format_param(p) for _,p in sig.parameters.items()]\n", "assert params[0] == '**\\\\*`funcs`**'" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['**\\\\*`funcs`**', '**`order`**=*`None`*']" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "params" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# export\n", "def _format_enum_doc(enum, full_name):\n", " \"Formatted `enum` definition to show in documentation\"\n", " vals = ', '.join(enum.__members__.keys())\n", " return f'{full_name}',f'Enum = [{vals}]'" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tst = _format_enum_doc(e, 'e')\n", "assert tst == ('e', 'Enum = [a, b]'),tst" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# export\n", "def _escape_chars(s):\n", " return s.replace('_', '\\_')\n", "\n", "def _format_func_doc(func, full_name=None):\n", " \"Formatted `func` definition to show in documentation\"\n", " try:\n", " sig = inspect.signature(func)\n", " fmt_params = [format_param(param) for name,param\n", " in sig.parameters.items() if name not in ('self','cls')]\n", " except: fmt_params = []\n", " name = f'{full_name or func.__name__}'\n", " arg_str = f\"({', '.join(fmt_params)})\"\n", " f_name = f\"class {name}\" if inspect.isclass(func) else name\n", " return f'{f_name}',f'{name}{arg_str}'" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "assert _format_func_doc(compose) == ('compose', \n", " 'compose(**\\\\*`funcs`**, **`order`**=*`None`*)')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# export\n", "def _format_cls_doc(cls, full_name):\n", " \"Formatted `cls` definition to show in documentation\"\n", " parent_class = inspect.getclasstree([cls])[-1][0][1][0]\n", " name,args = _format_func_doc(cls, full_name)\n", " if parent_class != object: args += f' :: {doc_link(get_name(parent_class))}'\n", " return name,args" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "assert _format_cls_doc(Pipeline, 'Pipeline') == ('class Pipeline',\n", " 'Pipeline(**`funcs`**=*`None`*, **`as_item`**=*`False`*, **`split_idx`**=*`None`*)')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# export\n", "def show_doc(elt, doc_string=True, name=None, title_level=None, disp=True, default_cls_level=2):\n", " \"Show documentation for element `elt`. Supported types: class, function, and enum.\"\n", " elt = getattr(elt, '__func__', elt)\n", " qname = name or qual_name(elt)\n", " if inspect.isclass(elt):\n", " if is_enum(elt.__class__): name,args = _format_enum_doc(elt, qname)\n", " else: name,args = _format_cls_doc (elt, qname)\n", " elif callable(elt): name,args = _format_func_doc(elt, qname)\n", " else: name,args = f\"{qname}\", ''\n", " link = get_source_link(elt) #TODO: use get_source_link when it works\n", " source_link = f'[source]'\n", " title_level = title_level or (default_cls_level if inspect.isclass(elt) else 4)\n", " doc = f'{name}{source_link}'\n", " doc += f'\\n\\n> {args}\\n\\n' if len(args) > 0 else '\\n\\n'\n", " if doc_string and inspect.getdoc(elt): doc += add_doc_links(inspect.getdoc(elt))\n", " if disp: display(Markdown(doc))\n", " else: return doc" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`doc_string` determines if we show the docstring of the function or not. `name` can be used to provide an alternative to the name automatically found. `title_level` determines the level of the anchor (default 3 for classes and 4 for functions). If `disp` is `False`, the function returns the markdown code instead of displaying it." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For instance\n", "\n", "```python\n", "show_doc(untar_data)\n", "```\n", "will display\n", "

untar_data[source]

\n", "\n", "> untar_data(**`url`**, **`fname`**=*`None`*, **`dest`**=*`None`*, **`c_key`**=*`ConfigKey.Data`*, **`force_download`**=*`False`*, **`extract_func`**=*`\\'tar_extract\\'`*)\n", "\n", "Download `url` to `fname` if `dest` doesn\\'t exist, and un-tgz to folder `dest`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Integration test -" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

class Pipeline[source]

\n", "\n", "> Pipeline(**`funcs`**=*`None`*, **`as_item`**=*`False`*, **`split_idx`**=*`None`*)\n", "\n", "A pipeline of composed (for encode/decode) transforms, setup with types" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#hide\n", "show_doc(Pipeline)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

Pipeline.decode[source]

\n", "\n", "> Pipeline.decode(**`o`**, **`full`**=*`True`*)\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#hide\n", "show_doc(Pipeline.decode)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

compose[source]

\n", "\n", "> compose(**\\*`funcs`**, **`order`**=*`None`*)\n", "\n", "Create a function that composes all functions in `funcs`, passing along remaining `*args` and `**kwargs` to all" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#hide\n", "show_doc(compose)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

untar_data[source]

\n", "\n", "> untar_data(**`url`**, **`fname`**=*`None`*, **`dest`**=*`None`*, **`c_key`**=*`'data'`*, **`force_download`**=*`False`*, **`extract_func`**=*`'tar_extract'`*)\n", "\n", "Download `url` to `fname` if `dest` doesn't exist, and un-tgz to folder `dest`." ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#hide\n", "show_doc(untar_data)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

add_docs[source]

\n", "\n", "> add_docs(**`cls_doc`**=*`None`*, **\\*\\*`docs`**)\n", "\n", "Copy values from [`docs`](/core.foundation.html#docs) to `cls` docstrings, and confirm all public methods are documented" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#hide\n", "show_doc(add_docs)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

Pipeline.__call__[source]

\n", "\n", "> Pipeline.__call__(**`o`**)\n", "\n", "Call self as a function." ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#hide\n", "show_doc(Pipeline.__call__)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

DataBunch.train_dl[source]

\n", "\n", "Training [`DataLoader`](/data.load.html#DataLoader)" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#hide\n", "from local.data.core import DataBunch\n", "show_doc(DataBunch.train_dl, name='DataBunch.train_dl')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

Path.ls[source]

\n", "\n", "> Path.ls(**`n_max`**=*`None`*, **`file_type`**=*`None`*, **`file_exts`**=*`None`*)\n", "\n", "Contents of path as a list" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# hide\n", "show_doc(Path.ls)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### The doc command" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "def md2html(md):\n", " \"Convert markdown `md` to HTML code\"\n", " if nbconvert.__version__ < '5.5.0': return HTMLExporter().markdown2html(md)\n", " else: return HTMLExporter().markdown2html(defaultdict(lambda: defaultdict(dict)), md)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "def doc(elt):\n", " \"Show `show_doc` info in preview window\"\n", " md = show_doc(elt, disp=False)\n", " output = md2html(md)\n", " if IN_COLAB: get_ipython().run_cell_magic(u'html', u'', output)\n", " else:\n", " try: page.page({'text/html': output})\n", " except: display(Markdown(md))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Export -" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Converted 00_test.ipynb.\n", "Converted 01_core_foundation.ipynb.\n", "Converted 01a_core_utils.ipynb.\n", "Converted 01b_core_dispatch.ipynb.\n", "Converted 01c_core_transform.ipynb.\n", "Converted 02_core_script.ipynb.\n", "Converted 03_torchcore.ipynb.\n", "Converted 03a_layers.ipynb.\n", "Converted 04_data_load.ipynb.\n", "Converted 05_data_core.ipynb.\n", "Converted 06_data_transforms.ipynb.\n", "Converted 07_data_block.ipynb.\n", "Converted 08_vision_core.ipynb.\n", "Converted 09_vision_augment.ipynb.\n", "Converted 09a_vision_data.ipynb.\n", "Converted 10_pets_tutorial.ipynb.\n", "Converted 11_vision_models_xresnet.ipynb.\n", "Converted 12_optimizer.ipynb.\n", "Converted 13_learner.ipynb.\n", "Converted 13a_metrics.ipynb.\n", "Converted 14_callback_schedule.ipynb.\n", "Converted 14a_callback_data.ipynb.\n", "Converted 15_callback_hook.ipynb.\n", "Converted 15a_vision_models_unet.ipynb.\n", "Converted 16_callback_progress.ipynb.\n", "Converted 17_callback_tracker.ipynb.\n", "Converted 18_callback_fp16.ipynb.\n", "Converted 19_callback_mixup.ipynb.\n", "Converted 20_interpret.ipynb.\n", "Converted 20a_distributed.ipynb.\n", "Converted 21_vision_learner.ipynb.\n", "Converted 22_tutorial_imagenette.ipynb.\n", "Converted 23_tutorial_transfer_learning.ipynb.\n", "Converted 30_text_core.ipynb.\n", "Converted 31_text_data.ipynb.\n", "Converted 32_text_models_awdlstm.ipynb.\n", "Converted 33_text_models_core.ipynb.\n", "Converted 34_callback_rnn.ipynb.\n", "Converted 35_tutorial_wikitext.ipynb.\n", "Converted 36_text_models_qrnn.ipynb.\n", "Converted 37_text_learner.ipynb.\n", "Converted 38_tutorial_ulmfit.ipynb.\n", "Converted 40_tabular_core.ipynb.\n", "Converted 41_tabular_model.ipynb.\n", "Converted 42_tabular_rapids.ipynb.\n", "Converted 50_data_block_examples.ipynb.\n", "Converted 60_medical_imaging.ipynb.\n", "Converted 65_medical_text.ipynb.\n", "Converted 70_callback_wandb.ipynb.\n", "Converted 90_notebook_core.ipynb.\n", "Converted 91_notebook_export.ipynb.\n", "Converted 92_notebook_showdoc.ipynb.\n", "Converted 93_notebook_export2html.ipynb.\n", "Converted 94_notebook_test.ipynb.\n", "Converted 95_index.ipynb.\n", "Converted 96_data_external.ipynb.\n", "Converted 97_utils_test.ipynb.\n", "Converted notebook2jekyll.ipynb.\n" ] } ], "source": [ "#hide\n", "notebook2script(all_fs=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 2 }