{ "cells": [ { "cell_type": "raw", "metadata": {}, "source": [ "---\n", "pagetitle: nbdev – Create delightful software with Jupyter Notebooks\n", "page-layout: custom\n", "section-divs: false\n", "echo: false\n", "css: index.css\n", "toc: false\n", "image: https://nbdev.fast.ai/images/card.png\n", "description: |\n", " Write, test, document, and distribute software packages and technical articles — all in one place, your notebook.\n", "---" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from IPython.display import Markdown\n", "\n", "def add_meta(md, meta):\n", " if meta: meta = \"{\" + meta + \"}\"\n", " return md + meta\n", "\n", "def img(fname, style=\"\", height=None, relative=None, link=False):\n", " if height: height = f'height=\"{height}\"'\n", " if relative:\n", " pos,px = relative\n", " if style: style += \" \"\n", " style += f\"position:relative; {pos}: {px}px\"\n", " if style: style = f'style=\"{style}\"'\n", " if link:\n", " res = f''\n", " res = f'{res}'\n", " else: res = f''\n", " return res\n", "\n", "def btn(txt, link):\n", " return f'{txt}'\n", "\n", "def banner(txt, klass=\"\", style=\"\", md=True):\n", " if style: style = f'style=\"{style}\"'\n", " res = f'
\\n\\n{txt}\\n\\n
\\n'\n", " if md: return Markdown(res)\n", " print(res)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "
\n", "\n", "\n", "# Create delightful software
with Jupyter Notebooks\n", "\n", "### Write, test, document, and distribute software packages and technical articles — all in one place, your notebook.\n", "\n", "Get started\n", "\n", "\n", "\n", "\n", "
\n" ], "text/plain": [ "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "banner(f\"\"\"\n", "# Create delightful software
with Jupyter Notebooks\n", "\n", "### Write, test, document, and distribute software packages and technical articles — all in one place, your notebook.\n", "\n", "{btn('Get started', 'getting_started.html')}\n", "\n", "{img('card.png', style=\"margin-top: 40px; margin-bottom: 40px\", link=True)}\n", "\"\"\", \"content-block\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "
\n", "\n", "## Trusted in industry\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "\n", "
\n", "\n", "\n", "
\n" ], "text/plain": [ "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def industry(im): return f'
\\n{im}\\n
\\n'\n", "\n", "industries = '\\n'.join([\n", " industry(img('netflix.svg', height=26, relative=(\"top\",1))),\n", " industry(img('transform.svg', height=26, relative=(\"bottom\",1))),\n", " industry(img('outerbounds.svg', height=26, relative=(\"bottom\",1))),\n", " industry(img('novetta.svg', height=30, relative=(\"top\",1))),\n", " industry(img('amd.svg', height=22)),\n", " industry(img('overstory.png', height=26)),\n", " industry(img('bom.png', height=46, relative=(\"bottom\",12))),\n", " industry(img('lyft.svg', height=34)),\n", "])\n", "\n", "banner(f'''## Trusted in industry\n", "\n", "
\n", "\n", "{industries}\n", "\n", "
\n", "''', \"mid-content\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "::: {.content-block}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "
\n", "\n", "## Exploratory programming
without compromise\n", "\n", "### Traditional programming environments throw away the result of your exploration in REPLs or notebooks. nbdev makes exploration an integral part of your workflow, all while promoting software engineering best practices.\n", "\n", "\n", "
\n" ], "text/plain": [ "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "banner(f\"\"\"## Exploratory programming
without compromise\n", "\n", "### Traditional programming environments throw away the result of your exploration in REPLs or notebooks. nbdev makes exploration an integral part of your workflow, all while promoting software engineering best practices.\n", "\"\"\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def feature(im, desc):\n", " return f\"\"\"
\n", "{img(im+'.svg')}\n", "\n", "{desc}\n", "
\n", "\"\"\"\n", "\n", "features = '\\n'.join([\n", " feature('docs', 'Beautiful technical documentation and scientific articles with Quarto'),\n", " feature('testing', 'Out-of-the-box continuous integration with GitHub Actions'),\n", " feature('packaging', 'Publish code to PyPI and conda, and prose to GitHub Pages'),\n", " feature('vscode', 'Two-way sync with your favourite IDEs'),\n", " feature('jupyter', 'Write prose, code, and tests in notebooks — no context-switching'),\n", " feature('git', 'Git-friendly notebooks: human-readable merge conflicts; no unwanted metadata')\n", "])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "
\n", "\n", "
\n", "\n", "\n", "Beautiful technical documentation and scientific articles with Quarto\n", "
\n", "\n", "
\n", "\n", "\n", "Out-of-the-box continuous integration with GitHub Actions\n", "
\n", "\n", "
\n", "\n", "\n", "Publish code to PyPI and conda, and prose to GitHub Pages\n", "
\n", "\n", "
\n", "\n", "\n", "Two-way sync with your favourite IDEs\n", "
\n", "\n", "
\n", "\n", "\n", "Write prose, code, and tests in notebooks — no context-switching\n", "
\n", "\n", "
\n", "\n", "\n", "Git-friendly notebooks: human-readable merge conflicts; no unwanted metadata\n", "
\n", "\n", "\n", "
\n" ], "text/plain": [ "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Markdown(f\"\"\"
\n", "\n", "{features}\n", "\n", "
\n", "\"\"\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ":::" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "::: {.mid-content}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "
\n", "\n", "## Here's what experts are saying\n", "\n", "
\n" ], "text/plain": [ "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "banner(\"## Here's what experts are saying\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def testm(im, nm, detl, txt):\n", " return f\"\"\"
\n", "{img(im, link=True)}\n", "\n", "# {nm}\n", "\n", "## {detl}\n", "\n", "### {txt}\n", "
\n", "\"\"\"\n", "\n", "testms = '\\n'.join([\n", " testm('chris-lattner.png', 'Chris Lattner', 'Inventor of Swift and LLVM',\n", " 'I really do think [nbdev] is a huge step forward for programming environments.'),\n", " testm('fernando-pérez.jpeg', 'Fernando Pérez', 'Creator of Jupyter',\n", " '[nbdev] should be celebrated and used a lot more — I have kept a tab with your original nbdev blog post open for months in Chrome because of how often I refer to it and point others to this work.'),\n", " testm('david-berg.jpeg', 'David Berg', 'Software Engineer, Netflix',\n", " 'Prior to using nbdev, documentation was the most cumbersome aspect of our software development process… Using nbdev allows us to spend more time creating rich prose around the many code snippets guaranteeing the whole experience is robust.

nbdev has turned what was once a chore into a natural extension of the notebook-based testing we were already doing.'),\n", " testm('erik-gaasedelen.jpeg', 'Erik Gaasedelen', 'Software Engineer, Lyft',\n", " 'I use this in production at my company. It’s an awesome tool… nbdev streamlines everything so I can write docs, tests, and code all in one place… The packaging is also really well thought out.

From my point of view it is close to a Pareto improvement over traditional Python library development.'),\n", " testm('roxanna-pourzand.jpeg', 'Roxanna Pourzand', 'Product Manager, Transform',\n", " 'We’re so excited about using nbdev. Our product is technical so our resulting documentation includes a lot of code-based examples. Before nbdev, we had no way of maintaining our code examples and ensuring that it was up-to-date for both command inputs and outputs. It was all manual. With nbdev, we now have this under control in a sustainable way. Since we’ve deployed these docs, we also had a situation where we were able to identify a bug in one of our interfaces, which we found by seeing the error that was output in the documentation.'),\n", " testm('hugo-bowne-anderson.jpeg', 'Hugo Bowne-Anderson', 'Head of Developer Relations, Outerbounds',\n", " 'Nbdev has transformed the way we write documentation. Gone are the days of worrying about broken code examples when our API changes or due to human errors associated with copying & pasting code into markdown files. The authoring experience of nbdev is also powerful, allowing us to write prose and live code in a unified interface, which allows more experimentation with technical content. On top of this, nbdev allows us to include unit tests in our documentation which mitigates the burden of maintaining the docs over time.')\n", "])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "
\n", "\n", "
\n", "\n", "\n", "# Chris Lattner\n", "\n", "## Inventor of Swift and LLVM\n", "\n", "### I really do think [nbdev] is a huge step forward for programming environments.\n", "
\n", "\n", "
\n", "\n", "\n", "# Fernando Pérez\n", "\n", "## Creator of Jupyter\n", "\n", "### [nbdev] should be celebrated and used a lot more — I have kept a tab with your original nbdev blog post open for months in Chrome because of how often I refer to it and point others to this work.\n", "
\n", "\n", "
\n", "\n", "\n", "# David Berg\n", "\n", "## Software Engineer, Netflix\n", "\n", "### Prior to using nbdev, documentation was the most cumbersome aspect of our software development process… Using nbdev allows us to spend more time creating rich prose around the many code snippets guaranteeing the whole experience is robust.

nbdev has turned what was once a chore into a natural extension of the notebook-based testing we were already doing.\n", "
\n", "\n", "
\n", "\n", "\n", "# Erik Gaasedelen\n", "\n", "## Software Engineer, Lyft\n", "\n", "### I use this in production at my company. It’s an awesome tool… nbdev streamlines everything so I can write docs, tests, and code all in one place… The packaging is also really well thought out.

From my point of view it is close to a Pareto improvement over traditional Python library development.\n", "
\n", "\n", "
\n", "\n", "\n", "# Roxanna Pourzand\n", "\n", "## Product Manager, Transform\n", "\n", "### We’re so excited about using nbdev. Our product is technical so our resulting documentation includes a lot of code-based examples. Before nbdev, we had no way of maintaining our code examples and ensuring that it was up-to-date for both command inputs and outputs. It was all manual. With nbdev, we now have this under control in a sustainable way. Since we’ve deployed these docs, we also had a situation where we were able to identify a bug in one of our interfaces, which we found by seeing the error that was output in the documentation.\n", "
\n", "\n", "
\n", "\n", "\n", "# Hugo Bowne-Anderson\n", "\n", "## Head of Developer Relations, Outerbounds\n", "\n", "### Nbdev has transformed the way we write documentation. Gone are the days of worrying about broken code examples when our API changes or due to human errors associated with copying & pasting code into markdown files. The authoring experience of nbdev is also powerful, allowing us to write prose and live code in a unified interface, which allows more experimentation with technical content. On top of this, nbdev allows us to include unit tests in our documentation which mitigates the burden of maintaining the docs over time.\n", "
\n", "\n", "\n", "
\n" ], "text/plain": [ "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Markdown(f\"\"\"
\n", "\n", "{testms}\n", "\n", "
\n", "\"\"\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ":::" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "
\n", "\n", "\n", "## Get started in seconds\n", "\n", "Install nbdev\n", "\n", "\n", "
\n" ], "text/plain": [ "" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "banner(f\"\"\"\n", "## Get started in seconds\n", "\n", "{btn('Install nbdev', 'getting_started.ipynb')}\n", "\"\"\", 'content-block', style=\"margin-top: 40px\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Copyright © 2019 onward fast.ai, Inc. All rights reserved.\n", "
" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 4 }