Spaces:
Sleeping
Sleeping
# Jupyter compatibility | |
<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! --> | |
``` python | |
from httpx import get, AsyncClient | |
``` | |
## Helper functions | |
------------------------------------------------------------------------ | |
<a | |
href="https://github.com/AnswerDotAI/fasthtml/blob/main/fasthtml/jupyter.py#L21" | |
target="_blank" style="float:right; font-size:smaller">source</a> | |
### nb_serve | |
> nb_serve (app, log_level='error', port=8000, host='0.0.0.0', **kwargs) | |
*Start a Jupyter compatible uvicorn server with ASGI `app` on `port` | |
with `log_level`* | |
------------------------------------------------------------------------ | |
<a | |
href="https://github.com/AnswerDotAI/fasthtml/blob/main/fasthtml/jupyter.py#L31" | |
target="_blank" style="float:right; font-size:smaller">source</a> | |
### nb_serve_async | |
> nb_serve_async (app, log_level='error', port=8000, host='0.0.0.0', | |
> **kwargs) | |
*Async version of | |
[`nb_serve`](https://www.fastht.ml/docs/api/jupyter.html#nb_serve)* | |
------------------------------------------------------------------------ | |
<a | |
href="https://github.com/AnswerDotAI/fasthtml/blob/main/fasthtml/jupyter.py#L39" | |
target="_blank" style="float:right; font-size:smaller">source</a> | |
### is_port_free | |
> is_port_free (port, host='localhost') | |
*Check if `port` is free on `host`* | |
------------------------------------------------------------------------ | |
<a | |
href="https://github.com/AnswerDotAI/fasthtml/blob/main/fasthtml/jupyter.py#L50" | |
target="_blank" style="float:right; font-size:smaller">source</a> | |
### wait_port_free | |
> wait_port_free (port, host='localhost', max_wait=3) | |
*Wait for `port` to be free on `host`* | |
## Using FastHTML in Jupyter | |
------------------------------------------------------------------------ | |
<a | |
href="https://github.com/AnswerDotAI/fasthtml/blob/main/fasthtml/components.py#L128" | |
target="_blank" style="float:right; font-size:smaller">source</a> | |
### show | |
> show (*s, iframe=False, height='auto', style=None) | |
*Same as fasthtml.components.show, but also adds `htmx.process()`* | |
------------------------------------------------------------------------ | |
<a | |
href="https://github.com/AnswerDotAI/fasthtml/blob/main/fasthtml/jupyter.py#L65" | |
target="_blank" style="float:right; font-size:smaller">source</a> | |
### render_ft | |
> render_ft () | |
------------------------------------------------------------------------ | |
<a | |
href="https://github.com/AnswerDotAI/fasthtml/blob/main/fasthtml/jupyter.py#L70" | |
target="_blank" style="float:right; font-size:smaller">source</a> | |
### htmx_config_port | |
> htmx_config_port (port=8000) | |
------------------------------------------------------------------------ | |
<a | |
href="https://github.com/AnswerDotAI/fasthtml/blob/main/fasthtml/jupyter.py#L81" | |
target="_blank" style="float:right; font-size:smaller">source</a> | |
### JupyUvi | |
> JupyUvi (app, log_level='error', host='0.0.0.0', port=8000, start=True, | |
> **kwargs) | |
*Start and stop a Jupyter compatible uvicorn server with ASGI `app` on | |
`port` with `log_level`* | |
Creating an object of this class also starts the Uvicorn server. It runs | |
in a separate thread, so you can use normal HTTP client functions in a | |
notebook. | |
``` python | |
app = FastHTML() | |
rt = app.route | |
@app.route | |
def index(): return 'hi' | |
port = 8000 | |
server = JupyUvi(app, port=port) | |
``` | |
<script> | |
document.body.addEventListener('htmx:configRequest', (event) => { | |
if(event.detail.path.includes('://')) return; | |
htmx.config.selfRequestsOnly=false; | |
event.detail.path = `${location.protocol}//${location.hostname}:8000${event.detail.path}`; | |
}); | |
</script> | |
``` python | |
get(f'http://localhost:{port}').text | |
``` | |
'hi' | |
You can stop the server, modify routes, and start the server again | |
without restarting the notebook or recreating the server or application. | |
``` python | |
server.stop() | |
``` | |
``` python | |
app = FastHTML() | |
rt = app.route | |
@app.route | |
async def index(): return 'hi' | |
server = JupyUvi(app, port=port, start=False) | |
await server.start_async() | |
``` | |
<script> | |
document.body.addEventListener('htmx:configRequest', (event) => { | |
if(event.detail.path.includes('://')) return; | |
htmx.config.selfRequestsOnly=false; | |
event.detail.path = `${location.protocol}//${location.hostname}:8000${event.detail.path}`; | |
}); | |
</script> | |
``` python | |
print((await AsyncClient().get(f'http://localhost:{port}')).text) | |
``` | |
hi | |
------------------------------------------------------------------------ | |
<a | |
href="https://github.com/AnswerDotAI/fasthtml/blob/main/fasthtml/jupyter.py#L101" | |
target="_blank" style="float:right; font-size:smaller">source</a> | |
### JupyUviAsync | |
> JupyUviAsync (app, log_level='error', host='0.0.0.0', port=8000, | |
> **kwargs) | |
*Start and stop an async Jupyter compatible uvicorn server with ASGI | |
`app` on `port` with `log_level`* | |
``` python | |
server = JupyUviAsync(app, port=port) | |
await server.start() | |
``` | |
<script> | |
document.body.addEventListener('htmx:configRequest', (event) => { | |
if(event.detail.path.includes('://')) return; | |
htmx.config.selfRequestsOnly=false; | |
event.detail.path = `${location.protocol}//${location.hostname}:8000${event.detail.path}`; | |
}); | |
</script> | |
``` python | |
async with AsyncClient() as client: | |
r = await client.get(f'http://localhost:{port}') | |
print(r.text) | |
``` | |
hi | |
``` python | |
server.stop() | |
``` | |
### Using a notebook as a web app | |
You can also run an HTMX web app directly in a notebook. To make this | |
work, you have to add the default FastHTML headers to the DOM of the | |
notebook with `show(*def_hdrs())`. Additionally, you might find it | |
convenient to use *auto_id* mode, in which the ID of an `FT` object is | |
automatically generated if not provided. | |
``` python | |
fh_cfg['auto_id' ]=True | |
``` | |
After importing `fasthtml.jupyter` and calling | |
[`render_ft()`](https://www.fastht.ml/docs/api/jupyter.html#render_ft), | |
FT components render directly in the notebook. | |
``` python | |
show(*def_hdrs()) | |
render_ft() | |
``` | |
</script><script src="https://cdn.jsdelivr.net/gh/answerdotai/[email protected]/fasthtml.js"></script><script src="https://cdn.jsdelivr.net/gh/answerdotai/surreal@main/surreal.js"></script><script src="https://cdn.jsdelivr.net/gh/gnat/css-scope-inline@main/script.js"></script><script id="_7KKmEIAnRE_-M4c4Lf5dJg">if (window.htmx) htmx.process(document.body)</script> | |
``` python | |
(c := Div('Cogito ergo sum')) | |
``` | |
<div id="_NNvXojeGS-eH1SZLG-pE4Q"> | |
<div id="_vzHRxQNEQiaSQnLdUFq2Mg"> | |
Cogito ergo sum | |
</div> | |
<script id="_SN7to4-bQ5O09J6vs2UvNA">if (window.htmx) htmx.process(document.body)</script> | |
</div> | |
Handlers are written just like a regular web app: | |
``` python | |
server = JupyUvi(app, port=port) | |
``` | |
<script> | |
document.body.addEventListener('htmx:configRequest', (event) => { | |
if(event.detail.path.includes('://')) return; | |
htmx.config.selfRequestsOnly=false; | |
event.detail.path = `${location.protocol}//${location.hostname}:8000${event.detail.path}`; | |
}); | |
</script> | |
``` python | |
@rt | |
def hoho(): return P('loaded!'), Div('hee hee', id=c, hx_swap_oob='true') | |
``` | |
All the usual `hx_*` attributes can be used: | |
``` python | |
P('not loaded', hx_get=hoho, hx_trigger='load') | |
``` | |
not loaded | |
if (window.htmx) htmx.process(document.body)</script> | |
</div> | |
FT components can be used directly both as `id` values and as | |
`hx_target` values. | |
``` python | |
(c := Div('')) | |
``` | |
<div id="_C4mtvDiLQPyjFBL_N9guOQ"> | |
<div id="_dazDkLiNRi_5IRjKxnDApQ"> | |
</div> | |
<script id="_wBaWxkrPTeyFjAjoTOAjaw">if (window.htmx) htmx.process(document.body)</script> | |
</div> | |
``` python | |
@rt | |
def foo(): return Div('foo bar') | |
P('hi', hx_get=foo, hx_trigger='load', hx_target=c) | |
``` | |
<div id="_mmZ8zN0IQRWcwaaJuPD17g"> | |
<p hx-get="/foo" hx-trigger="load" hx-target="#_dazDkLiNRi_5IRjKxnDApQ" id="_21sjPwFeSPKp3vncj4YJrQ"> | |
hi | |
</p> | |
<script id="_iy4Ov4wQRsuuB6ekh8semw">if (window.htmx) htmx.process(document.body)</script> | |
</div> | |
``` python | |
server.stop() | |
``` | |
### Running apps in an IFrame | |
Using an IFrame can be a good idea to get complete isolation of the | |
styles and scripts in an app. The | |
[`HTMX`](https://www.fastht.ml/docs/api/jupyter.html#htmx) function | |
creates an auto-sizing IFrame for a web app. | |
------------------------------------------------------------------------ | |
<a | |
href="https://github.com/AnswerDotAI/fasthtml/blob/main/fasthtml/jupyter.py#L114" | |
target="_blank" style="float:right; font-size:smaller">source</a> | |
### HTMX | |
> HTMX (path='', app=None, host='localhost', port=8000, height='auto', | |
> link=False, iframe=True) | |
*An iframe which displays the HTMX application in a notebook.* | |
``` python | |
@rt | |
def index(): | |
return Div( | |
P(A('Click me', hx_get=update, hx_target='#result')), | |
P(A('No me!', hx_get=update, hx_target='#result')), | |
Div(id='result')) | |
@rt | |
def update(): return Div(P('Hi!'),P('There!')) | |
``` | |
``` python | |
server.start() | |
``` | |
``` python | |
# Run the notebook locally to see the HTMX iframe in action | |
HTMX() | |
``` | |
<iframe src="http://localhost:8000" style="width: 100%; height: auto; border: none;" onload="{ | |
let frame = this; | |
window.addEventListener('message', function(e) { | |
if (e.source !== frame.contentWindow) return; // Only proceed if the message is from this iframe | |
if (e.data.height) frame.style.height = (e.data.height+1) + 'px'; | |
}, false); | |
}" allow="accelerometer; autoplay; camera; clipboard-read; clipboard-write; display-capture; encrypted-media; fullscreen; gamepad; geolocation; gyroscope; hid; identity-credentials-get; idle-detection; magnetometer; microphone; midi; payment; picture-in-picture; publickey-credentials-get; screen-wake-lock; serial; usb; web-share; xr-spatial-tracking"></iframe> | |
``` python | |
server.stop() | |
``` | |
------------------------------------------------------------------------ | |
<a | |
href="https://github.com/AnswerDotAI/fasthtml/blob/main/fasthtml/jupyter.py#L135" | |
target="_blank" style="float:right; font-size:smaller">source</a> | |
### ws_client | |
> ws_client (app, nm='', host='localhost', port=8000, ws_connect='/ws', | |
> frame=True, link=True, **kwargs) | |