Skip to content

Instantly share code, notes, and snippets.

@psychemedia
Created August 17, 2021 12:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save psychemedia/09945691d3a6881a95dbb72366195b45 to your computer and use it in GitHub Desktop.
Save psychemedia/09945691d3a6881a95dbb72366195b45 to your computer and use it in GitHub Desktop.
Hack for local Jupyter book
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "607ef0e0",
"metadata": {},
"source": [
"1. Download _toc.yml and _config.yml\n",
"2. Build book\n",
"3. Get git repo (https://github.com/ouseful-testing/jupyter-book-server-proxy/zipball/main/) and rename\n",
"4. copy build files\n",
"5. install package\n",
"6. restart container\n",
"7. Launch book from menu"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8822d071",
"metadata": {},
"outputs": [],
"source": [
"%pip install jupyter-book"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9670a4e0",
"metadata": {},
"outputs": [],
"source": [
"!rm -rf ./jb && wget -q -O jb.zip https://github.com/ouseful-testing/jupyter-book-server-proxy/zipball/main/ && unzip -d ./jb jb.zip && rm jb.zip\n",
"!pip install ./jb/ouseful-testing-jupyter-book-server-proxy-a84754a/"
]
},
{
"cell_type": "markdown",
"id": "3b9406de",
"metadata": {},
"source": [
"__NOW RESTART THE DOCKER CONTAINER__"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "48210e1e",
"metadata": {},
"outputs": [],
"source": [
"%%writefile _config.yml\n",
"title: TM351 Notebooks\n",
"auther: TM351 Module Team, The Open University\n",
"only_build_toc_files : true\n",
"exclude_patterns : [_build, Thumbs.db, .DS_Store, \"**.ipynb_checkpoints\", \"**.md\", \"**jupyter_book_server_proxy\"]\n",
"execute:\n",
" execute_notebooks : off\n",
"launch_buttons:\n",
" jupyterhub_url : http://localhost:8351/notebooks/notebooks # The URL of the JupyterHub (e.g., https://datahub.berkeley.edu)\n",
" thebe : true # Add a thebe button to pages (requires the repository to run on Binder)\n",
" "
]
},
{
"cell_type": "markdown",
"id": "2a8529cd",
"metadata": {},
"source": [
"You can [create a table of contents](https://jupyterbook.org/basics/create.html?highlight=create%20contents) (`_toc.yml`) file from the `.ipynb` file contents of the current directory (and subdirectories) therefrom using a command such as `jupyter-book toc from-project . -e .ipynb -f jb-book > _toc.yml`.\n",
"\n",
"The file may need fettling to get the structure you require ([about](https://jupyterbook.org/customize/toc.html)).\n",
"\n",
"The following example is not ideal (generated from TM351 notebooks)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "46f0d659",
"metadata": {},
"outputs": [],
"source": [
"%%writefile _toc.yml\n",
"format: jb-book\n",
"root: Using Jupyter Notebooks - READ ME FIRST\n",
"chapters:\n",
"- file: Part 01 Notebooks/01.1 Getting started with IPython and Jupyter Notebooks\n",
" - Bootcamp\n",
" sections:\n",
" - file: Part 01 Notebooks/01.2 Python recap\n",
" - file: Part 01 Notebooks/01.3 Basic python data structures\n",
" - file: Part 01 Notebooks/01.4 Defining new functions in python\n",
" - file: Part 01 Notebooks/01.5 Python file handling\n",
" - file: Part 01 Notebooks/01.X Customising the Notebook Environment\n",
"- file: Part 02 Notebooks/02.1 Pandas Dataframes\n",
" sections:\n",
" - file: Part 02 Notebooks/02.2 Data file formats\n",
" - file: Part 02 Notebooks/02.2.0 Data file formats - file encodings\n",
" - file: Part 02 Notebooks/02.2.1 Data file formats - CSV\n",
" - file: Part 02 Notebooks/02.2.2 Data file formats - JSON\n",
" - file: Part 02 Notebooks/02.2.3 Data file formats - other\n",
"- file: Part 03 Notebooks/03.1 Cleaning data\n",
" sections:\n",
" - file: Part 03 Notebooks/03.2 Selecting and projecting, sorting and limiting\n",
" - file: Part 03 Notebooks/03.3 Combining data from multiple datasets\n",
" - file: Part 03 Notebooks/03.4 Handling missing data\n",
"- file: Part 04 Notebooks/04.1 Crosstabs and pivot tables\n",
" sections:\n",
" - file: Part 04 Notebooks/04.2 Descriptive statistics in pandas\n",
" - file: Part 04 Notebooks/04.3 Simple visualisations in pandas\n",
" - file: Part 04 Notebooks/04.4 Activity 4.4 Walkthrough\n",
" - file: Part 04 Notebooks/04.5 Split-apply-combine with SQL and pandas\n",
" - file: Part 04 Notebooks/04.5.soln SalesTeamExploration\n",
" - file: Part 04 Notebooks/04.6 Introducing regular expressions\n",
" - file: Part 04 Notebooks/04.7 Reshaping data with pandas\n",
"- file: Part 05 Notebooks/05.1 Anscombe's Quartet - visualising data\n",
" sections:\n",
" - file: Part 05 Notebooks/05.2 Getting started with maps - folium\n",
" - file: Part 05 Notebooks/05.3 Getting started with matplotlib\n",
"- file: Part 07 Notebooks/07.1 Spreadsheet basics\n",
" sections:\n",
" - file: Part 07 Notebooks/07.2 Problems in spreadsheet construction\n",
"- file: Part 08 Notebooks/08.1 Data Definition Language in SQL\n",
" sections:\n",
" - file: Part 08 Notebooks/08.2 Data Manipulation Language in SQL\n",
" - file: Part 08 Notebooks/08.3 Adding column constraints to tables\n",
" - file: Part 08 Notebooks/reset_databases\n",
" - file: Part 08 Notebooks/sql_init\n",
"- file: Part 09 Notebooks/09.1 Defining Foreign Keys in SQL\n",
" sections:\n",
" - file: Part 09 Notebooks/09.2 Using foreign keys in SQL\n",
" - file: Part 09 Notebooks/09.3 Working With FOREIGN KEY Constraints\n",
" - file: Part 09 Notebooks/reset_databases\n",
" - file: Part 09 Notebooks/sql_init\n",
"- file: Part 10 Notebooks/10.1 problems with unnormalised data\n",
" sections:\n",
" - file: Part 10 Notebooks/10.2 Normalisation - Antique opticals\n",
" - file: Part 10 Notebooks/10.3 Normalisation - the Hospital scenario\n",
" - file: Part 10 Notebooks/10.4 Our solution to Normalisation - the Hospital scenario\n",
" - file: Part 10 Notebooks/10.5 Improvements with normalised data\n",
" - file: Part 10 Notebooks/reset_databases\n",
" - file: Part 10 Notebooks/sql_init\n",
"- file: Part 11 Notebooks/11.0 Setting up the Movie database\n",
" sections:\n",
" - file: Part 11 Notebooks/11.1 Movie analysis\n",
" - file: Part 11 Notebooks/11.2 subqueries as value and set\n",
" - file: Part 11 Notebooks/11.3 Subqueries as tables\n",
" - file: Part 11 Notebooks/11.4 Views\n",
" - file: Part 11 Notebooks/11.5 Six degrees of Bacon\n",
" - file: Part 11 Notebooks/reset_databases\n",
" - file: Part 11 Notebooks/SQL_cheatsheet\n",
" - file: Part 11 Notebooks/sql_init\n",
"- file: Part 12 Notebooks/12.1 Concurrent Transactions\n",
" sections:\n",
" - file: Part 12 Notebooks/12.2 Transaction anomalies\n",
" - file: Part 12 Notebooks/reset_databases\n",
" - file: Part 12 Notebooks/sql_init\n",
" - file: Part 12 Notebooks/optional_part_12/12.3 Optional- Concurrent Transactions\n",
" and Multiple Threads\n",
" sections:\n",
" - file: Part 12 Notebooks/optional_part_12/12.3a Gibson\n",
" - file: Part 12 Notebooks/optional_part_12/12.3a Paxton\n",
" - file: Part 12 Notebooks/optional_part_12/reset_databases\n",
" - file: Part 12 Notebooks/optional_part_12/sql_init\n",
"- file: Part 14 Notebooks/14.1 Basic CRUD\n",
" sections:\n",
" - file: Part 14 Notebooks/14.2 Working With Embedded Documents\n",
" - file: Part 14 Notebooks/14.3 Importing Data into MongoDB\n",
" - file: Part 14 Notebooks/14.4 Introduction to the accidents database\n",
" - file: Part 14 Notebooks/14.5 Investigating the accident data\n",
" - file: Part 14 Notebooks/14.A Optional- Using statistical tests - correlation\n",
" - file: Part 14 Notebooks/14.B Optional- Using statistical tests - regression\n",
"- file: Part 15 Notebooks/15.1 Mapping accidents\n",
" sections:\n",
" - file: Part 15 Notebooks/15.2 Searching within a geographical area\n",
" - file: Part 15 Notebooks/15.3 Introducing aggregation pipelines\n",
" - file: Part 15 Notebooks/15.4 Grouping and summarising operations in aggregation\n",
" pipelines\n",
" - file: Part 15 Notebooks/15.5 Introducing the Roads collection\n",
" - file: Part 15 Notebooks/15.6 Working with roads location data\n",
"- file: Part 16 Notebooks/16.1 Accidents over time\n",
" sections:\n",
" - file: Part 16 Notebooks/16.2 Python map-reduce\n",
" - file: Part 16 Notebooks/16.3 Introducing map-reduce in MongoDB Database Queries\n",
"- file: Part 20 Notebooks/20.1 The k-nearest neighbours classifier\n",
" sections:\n",
" - file: Part 20 Notebooks/20.2 The leave-one-out algorithm\n",
"- file: Part 21 Notebooks/21.1 The k-means algorithm\n",
" sections:\n",
" - file: Part 21 Notebooks/21.2 k-means clustering - choosing initial values\n",
" - file: Part 21 Notebooks/21.3 Visualising clusters with silhouette coefficients\n",
"- file: Part 22 Notebooks/22.1 Case study preliminaries - the vector space model\n",
" sections:\n",
" - file: Part 22 Notebooks/22.2 Preliminaries - building the classifier\n",
" - file: Part 22 Notebooks/22.3 Applying the classifier to a real dataset\n",
" - file: Part 22 Notebooks/22.4 Term frequency and inverse document frequency\n",
"- file: Part 23 Notebooks/23.1 SQL injection hacks\n",
" sections:\n",
" - file: Part 23 Notebooks/form_server\n",
" - file: Part 23 Notebooks/form_server_safe\n",
" - file: Part 23 Notebooks/part_23_authentication_notebook\n",
" - file: Part 23 Notebooks/reset_form_server\n",
"- file: Part 25 Notebooks/25.1 Exploring the RDFLib package\n",
" sections:\n",
" - file: Part 25 Notebooks/25.2 Querying using SPARQL\n",
" - file: Part 25 Notebooks/25.3 Endpoints - accessing real data\n",
"- file: Part 26 Notebooks/26.1 Using multiple endpoints\n",
" sections:\n",
" - file: Part 26 Notebooks/26.2 The SPARQL CONSTRUCT query and inferencing\n",
" - file: Part 26 Notebooks/26.3 Visualisation\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "075ae0d7",
"metadata": {},
"outputs": [],
"source": [
"replace_jh_from = 'hub/user-redirect/git-pull?repo=https://github.com/executablebooks/jupyter-book&urlpath=tree/jupyter-book/'\n",
"replace_jh_with = ''\n",
"\n",
"replace_jh_from2 = '&branch=master\"><button type=\"button\"'\n",
"replace_jh_with2 = '\"><button type=\"button\"'\n",
"\n",
"replace_jh_from3 = 'alt=\"Interact on JupyterHub\">JupyterHub</button>'\n",
"replace_jh_with3 = 'alt=\"Interact on local notebook server\">localhost</button></a>'"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e2a33809",
"metadata": {},
"outputs": [],
"source": [
"replace_thebe_from = '''<script type=\"text/x-thebe-config\">'''\n",
"replace_thebe_with='''<script type=\"text/x-thebe-config\">\n",
" {\n",
" requestKernel: true,\n",
" kernelOptions: {\n",
" name: \"python3\",\n",
" serverSettings: {\n",
" \"baseUrl\": \"http://localhost:8351\",\n",
" \"token\": \"letmein\"\n",
" }\n",
" },\n",
" }\n",
" </script>\n",
" <!--\n",
"'''\n",
"\n",
"replace_thebe_from2 = '''<script>kernelName = 'python3'</script>'''\n",
"replace_thebe_with2 = '''-->\n",
"<script>kernelName = 'python3'</script>'''"
]
},
{
"cell_type": "markdown",
"id": "80f96f1f",
"metadata": {},
"source": [
"The Thebe update actually wipes out the start directory that appears in the orignal as eg:\n",
" \n",
"```\n",
" kernelOptions: {\n",
" kernelName: \"python3\",\n",
" path: \"./Part 16 Notebooks\"\n",
" },\n",
"```\n",
"\n",
"I'm not sure if the path can be set for the local usage (not tried). It would be really handy if it could..."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7781df12",
"metadata": {},
"outputs": [],
"source": [
"# Generate book\n",
"!jupyter book build --path-output . .\n",
"# Files in _build/html"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "eb5ffc5a",
"metadata": {},
"outputs": [],
"source": [
"# Update files \n",
"from pathlib import Path\n",
"\n",
"html_dir = Path('./_build/html')\n",
"for p in html_dir.rglob(\"*\"):\n",
" if p.is_file() and p.suffix == '.html':\n",
" # Read file\n",
" #print(p)\n",
" with p.open('r', encoding =\"utf-8\") as f:\n",
" html = f.read()\n",
" html = html.replace(replace_jh_from, replace_jh_with)\n",
" html = html.replace(replace_jh_from2, replace_jh_with2)\n",
" html = html.replace(replace_jh_from3, replace_jh_with3)\n",
" html = html.replace(replace_thebe_from, replace_thebe_with)\n",
" html = html.replace(replace_thebe_from2, replace_thebe_with2)\n",
" with p.open(\"w\", encoding =\"utf-8\") as f:\n",
" f.write(html)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c6f29706",
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"!rm -rf ./jb/ouseful-testing-jupyter-book-server-proxy-a84754a/jupyter_book_server_proxy/static/\n",
"!mkdir -p ./jb/ouseful-testing-jupyter-book-server-proxy-a84754a/jupyter_book_server_proxy/static/\n",
"!cp -r _build/html/* ./jb/ouseful-testing-jupyter-book-server-proxy-a84754a/jupyter_book_server_proxy/static/\n",
"!pip install ./jb/ouseful-testing-jupyter-book-server-proxy-a84754a/"
]
},
{
"cell_type": "markdown",
"id": "ae55178c",
"metadata": {},
"source": [
"__FROM THE NOTEBOOK HOMEPAGE, REFRESH THE PAGE, THEN SELECT `New > Jupyter Book`__\n",
"\n",
"*If the menu item is not there, restart the container then reload the home page.*"
]
},
{
"cell_type": "markdown",
"id": "e2795f9f",
"metadata": {},
"source": [
"Have a play...\n",
"From the rocket menu you should be able to navigate to the notebooks as well as enabling code execution in page (*Live Code*).\n",
"\n",
"Note that at the moment the file paths to load files are broken. The kernel is in running from `/home/jovyan` so you need to make paths relative to that. There is a way to set the kernel start directory when running using MyBinder, but I'm not sure offhand if that works at the moment with using ThebeLab to run locally (I will explore this when I get back from hols)."
]
}
],
"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.8.5"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment