Skip to content

Instantly share code, notes, and snippets.

@WetHat
Last active October 4, 2023 17:44
Show Gist options
  • Save WetHat/b8189b30fa4b0ceec39a60241be6ff45 to your computer and use it in GitHub Desktop.
Save WetHat/b8189b30fa4b0ceec39a60241be6ff45 to your computer and use it in GitHub Desktop.
A Python Module Manifest for Jupyter Notebooks (Python Kernel)
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# A Python Package Manifest for Jupyter Notebooks (Python Kernel)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"_Jupyter Notebooks_ are a great way to publish research which can be easily reproduced and verified.\n",
"Typically a _Jupyter Notebook_ using the Python kernel imports a variety of modules. The success of running such\n",
"a notebook on a computer other than the author's may critically depend on availability and versions of the\n",
"Python packages available on that other computer. To address this it is good practice to state the\n",
"versions of all components used in a notebook, so that anybody interested in running the notebook can set up the appropriate environment.\n",
"\n",
"In this notebook we develop a simple _Python_ function which produces a Markdown table suitable for display in the notebook environment. The table contains the information for the packages needed to set up a\n",
"suitable Python environment and looks like so:\n",
"\n",
"| Component | Version | Description |\n",
"| --------------------------------- | -------- | -------------------------------- |\n",
"| [Python](https://www.python.org/) | 3.8.2 | Programming Language |\n",
"| [jupterlab](https://jupyter.org/) | 3.0.12 | The JupyterLab server extension. |\n",
"| ... | ... | ... |"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# The Manifest Function"
]
},
{
"cell_type": "markdown",
"metadata": {
"tags": []
},
"source": [
"## notebook_manifest(*modules: List[str] ) -> str\n",
"\n",
"Generate a Markdown table containing metadata of Python packages.\n",
"\n",
"The primary use of this function is to add module manifest information to a Jupyter notebook. In this \n",
"implementation the Python version is added at the top of the manifest table.\n",
"\n",
"**Args**\n",
"\n",
"**`*modules: List[str]`**\n",
": Names of modules to be included in the manifest table.\n",
" There is no checking if a given module is actually used by this notebook.\n",
" If the package has the appropriate metadata it will added to the manifest.\n",
"\n",
" **Notes:**\n",
" * `pip` installed packages typically have the required metadata.\n",
" * It is the responsibility of the caller of this function to supply\n",
" all relevant packages\n",
"\n",
"**Returns**:\n",
": A markdown table containing information about the specified Python modules.\n",
" The first entry in the table is the Python version, Modules are returned in\n",
" alphabetical order. The returned tables has 3 columns:\n",
"\n",
" | Component | Version | Description |\n",
" | --------------------------------- | ------- | -------------------------------- |\n",
" | [Python](https://www.python.org/) | 3.8.2 | Programming Language |\n",
" | [jupterlab](https://jupyter.org/) | 3.0.12 | The JupyterLab server extension. |\n",
" | ... | ... | ... |"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"tags": [
"CodeExport"
]
},
"outputs": [],
"source": [
"import sys\n",
"from typing import List\n",
"from importlib.metadata import metadata\n",
"import IPython.display as IPd"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"tags": [
"CodeExport"
]
},
"outputs": [],
"source": [
"def notebook_manifest(*packages: List[str] ) -> str:\n",
" manifest = [\n",
" '| Component | Version | Description |',\n",
" '| --------------------------------- | -------------------------- | -------------------- |',\n",
" f'| [Python](https://www.python.org/) | {sys.version.split()[0]} | Programming Language |'\n",
" ]\n",
" sorted_packages = [*packages]; # convert arguments to a list\n",
" sorted_packages.sort()\n",
" for p in sorted_packages: # build the markdown table of module metadata\n",
" try:\n",
" meta = {k: v for k, v in metadata(p).items()}\n",
" if 'Home-page' in meta:\n",
" home = meta[\"Home-page\"] \n",
" else:\n",
" home = f'https://pypi.org/project/{meta[\"Name\"]}/'\n",
" manifest.append(\n",
" f'| [{meta[\"Name\"]}]({home}) | {meta[\"Version\"]} | {meta[\"Summary\"]} |')\n",
" except:\n",
" manifest.append(\n",
" f'| {p} | ? | **Unrecognized module!** |')\n",
" return IPd.Markdown('\\n'.join(manifest))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Example"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this example we demonstrate a typical use of this function. We also include one non-existent Python\n",
"package to show how errors are handled."
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"tags": []
},
"outputs": [
{
"data": {
"text/markdown": [
"**Packages used in This Notebook**"
],
"text/plain": [
"<IPython.core.display.Markdown object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/markdown": [
"| Component | Version | Description |\n",
"| --------------------------------- | -------------------------- | -------------------- |\n",
"| [Python](https://www.python.org/) | 3.12.0 | Programming Language |\n",
"| [ipython](https://ipython.org) | 8.16.1 | IPython: Productive Interactive Computing |\n",
"| [jupyterlab](https://pypi.org/project/jupyterlab/) | 4.0.6 | JupyterLab computational environment |"
],
"text/plain": [
"<IPython.core.display.Markdown object>"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"display(IPd.Markdown('**Packages used in This Notebook**'))\n",
"notebook_manifest('jupyterlab','IPython')"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment