{
"cells": [
{
"metadata": {},
"id": "dcb7a6c1",
"cell_type": "markdown",
"source": "# Websockets in Jupyter"
},
{
"metadata": {},
"id": "1e4f42f0",
"cell_type": "markdown",
"source": "Use at least FastHTML 0.6.5. \n\nThis code is heavily inspired by this [code](https://docs.fastht.ml/tutorials/by_example.html#websockets) written by Jeremy Howard."
},
{
"metadata": {
"trusted": true
},
"id": "ccc69a8c",
"cell_type": "code",
"source": "# import necessary pieces\nfrom fasthtml.common import *\nfrom asyncio import sleep\n\n# Might be merged into fasthtml.common\nfrom fasthtml.jupyter import *",
"execution_count": 1,
"outputs": []
},
{
"metadata": {
"trusted": true
},
"id": "257f7974",
"cell_type": "code",
"source": "def mk_inp(): return Input(id='msg')",
"execution_count": 2,
"outputs": []
},
{
"metadata": {
"trusted": true
},
"id": "d18faba3",
"cell_type": "code",
"source": "# FastJupy() is a wrapper around the FastHTML() class\n# ws_hdr brings in the websocket headers\napp = FastJupy(ws_hdr=True)\nrt = app.route",
"execution_count": 3,
"outputs": []
},
{
"metadata": {
"trusted": true
},
"id": "604e2c0b",
"cell_type": "code",
"source": "@rt('/')\nasync def get(request):\n cts = Div(\n Div(id='notifications'),\n Form(mk_inp(), id='form', ws_send=True),\n hx_ext='ws', ws_connect='/ws')\n return Titled('Websocket Test', cts)",
"execution_count": 9,
"outputs": []
},
{
"metadata": {
"trusted": true
},
"id": "4c54f144",
"cell_type": "code",
"source": "async def on_connect(send):\n print('Connected!')\n await send(Div('Hello, you have connected', id=\"notifications\"))\n\nasync def on_disconnect(ws):\n print('Disconnected!')",
"execution_count": 5,
"outputs": []
},
{
"metadata": {
"trusted": true
},
"id": "0affff9a",
"cell_type": "code",
"source": "@app.ws('/ws', conn=on_connect, disconn=on_disconnect)\nasync def ws(msg:str, send):\n await send(Div('Hello ' + msg, id=\"notifications\"))\n await sleep(2)\n return Div('Goodbye ' + msg, id=\"notifications\"), mk_inp()",
"execution_count": 6,
"outputs": []
},
{
"metadata": {
"trusted": true
},
"id": "99142b38",
"cell_type": "code",
"source": "port = 8000\nserver = JupyUvi(app, port=port)",
"execution_count": 7,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": "Connected!\n"
}
]
},
{
"metadata": {
"trusted": true
},
"id": "4e8621e5",
"cell_type": "code",
"source": "HTMX()",
"execution_count": 8,
"outputs": [
{
"data": {
"text/html": " ",
"text/plain": ""
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
]
},
{
"metadata": {
"trusted": true
},
"id": "bda7bea5",
"cell_type": "code",
"source": "# Run me if you want to gracefully stop the HTTP server\n# without restarting Jupyter\nserver.stop()",
"execution_count": null,
"outputs": []
},
{
"metadata": {
"trusted": true
},
"id": "02ce0e9c",
"cell_type": "code",
"source": "",
"execution_count": null,
"outputs": []
}
],
"metadata": {
"_draft": {
"nbviewer_url": "https://gist.github.com/pydanny/1eee38ceec17a915a67f1c382d3387ea"
},
"gist": {
"id": "1eee38ceec17a915a67f1c382d3387ea",
"data": {
"description": "FastHTML plus Jupyter plus websockets",
"public": true
}
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3 (ipykernel)",
"language": "python"
},
"language_info": {
"name": "python",
"version": "3.10.6",
"mimetype": "text/x-python",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"pygments_lexer": "ipython3",
"nbconvert_exporter": "python",
"file_extension": ".py"
}
},
"nbformat": 4,
"nbformat_minor": 5
}