Last active
April 12, 2023 16:00
-
-
Save hamelin/f21bd05c3216439f9089c6a05441c8a3 to your computer and use it in GitHub Desktop.
Example of usage of Jupyter Proxy Server to host local content for an in-notebook GUI.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"id": "2cf1c77f-6601-424d-a86f-4faaeb6a4683", | |
"metadata": {}, | |
"source": [ | |
"# Accessing static local content in support of an in-notebook web service\n", | |
"\n", | |
"Whenever one is developing a notebook-embedded GUI using [Jupyter widgets](https://ipywidgets.readthedocs.io/en/stable/)\n", | |
"or [Panel](https://panel.holoviz.org/index.html), there may arise a need to access some content present on the local filesystem within the client-side code.\n", | |
"This is surprisingly tricky: file URLs are a big security hole, and most browsers won't allow them from a notebook.\n", | |
"\n", | |
"A simple solution consists in proxying a static web server through the Jupyter web server.\n", | |
"This is made possible by the [Jupyter Server Proxy](https://jupyter-server-proxy.readthedocs.io/en/latest/) extension." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "065efb53-771d-41a0-b5cc-fc7a48c13389", | |
"metadata": {}, | |
"source": [ | |
"## Setup" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "195df846-f916-4439-9c6a-7fb96c6f0a12", | |
"metadata": {}, | |
"source": [ | |
"1. Create a virtual environment that includes packages `jupyterlab` and `jupyter-server-proxy`.\n", | |
"1. Start Jupyter Lab or Jupyter notebook as you would regularly:\n", | |
" ```\n", | |
" \n", | |
" jupyter lab\n", | |
" \n", | |
" \n", | |
" ```\n", | |
"1. Open and run this notebook in that Jupyter instance." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "26b73cde-7ea9-4421-bc9e-93fed50527b0", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from http.server import HTTPServer, SimpleHTTPRequestHandler\n", | |
"import threading as thr" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "cd2f4581-6c75-4091-829e-9135740a317d", | |
"metadata": {}, | |
"source": [ | |
"Let's instantiate a new web server.\n", | |
"As it stands, it will simply serve content from the current directory." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "45466bf3-9e5a-4e55-86df-a88f2fa3397e", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"server = HTTPServer((\"\", 0), SimpleHTTPRequestHandler)\n", | |
"server.server_address" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "46dfc0ce-65d1-4b15-b60a-cd0248ef3241", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"service = thr.Thread(target=server.serve_forever)\n", | |
"service.start()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "b437fd8f-f95b-45a4-b965-353d1c9ebedf", | |
"metadata": {}, | |
"source": [ | |
"Let's have an image to serve off of our newly minted server." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "b23169ac-d7fb-4188-bf04-07a672b0c574", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import base64\n", | |
"import os\n", | |
"import requests as rq\n", | |
"\n", | |
"with open(\"freya-luna.jpg\", \"wb\") as file_image:\n", | |
" file_image.write(\n", | |
" base64.b64decode(\n", | |
" rq.get(\"https://gist.github.com/hamelin/c02285b00636705b7941b1157bf19f85/raw/f142a25a8442feaba135829d55f25cd3549f992e/freya-luna.jpg.b64\").content\n", | |
" )\n", | |
" )\n", | |
"os.stat(\"freya-luna.jpg\")" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"id": "3f900f59-7c0a-4628-8945-383bab0c93ae", | |
"metadata": {}, | |
"source": [ | |
"The following cell will generate a HTML cell that will use the browser to access an image through our proxied web server.\n", | |
"Run it, then run the new cell that will appear underneath." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "42d7b183-9381-41f6-b6bf-ab59d4d4c606", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"name_image = \"freya-luna.jpg\"\n", | |
"get_ipython().set_next_input(f\"\"\"\n", | |
"%%html\n", | |
"<img src=\"/proxy/{server.server_address[1]}/{name_image}\">\n", | |
"\"\"\".strip())" | |
] | |
}, | |
{ | |
"cell_type": "raw", | |
"id": "c60149d8-f69c-484f-88b4-1e690aaf3a77", | |
"metadata": {}, | |
"source": [ | |
"%%html\n", | |
"<img src=\"/proxy/33743/freya-luna.jpg\">" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "b92f064e-65df-4a66-9eec-64a110448867", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"server.shutdown()" | |
] | |
} | |
], | |
"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.10.10" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 5 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment