Open Kludex opened 1 year ago
This prompted me to think about arel vs uvicorn-browser.
I never thought we could implement browser reload at the ASGI server level. That's pretty interesting. As I understand, uvicorn-reload
wraps the uvicorn
CLI and plugs onto the reload_dirs
etc options.
arel
uses a different approach. It does reload at the application level, rather than server level. My motivation was to make it work for any ASGI app -- and server. The counterpart is: users have to do a bit of setup themselves. 1/ Register the WebSocket endpoint on their app (eg add a WebSocketRoute(hot_reload)
on Starlette), 2/ register the reload JS script in their HTML pages (eg Jinja base template).
Arel has dedicated path reloading options, which allows reloading the page when something other than Python files changes (eg a Jinja template, a JS script, etc). But this also brings a problem. If I'm also running uvicorn <app> --reload
during development, and I change a Python file, then Uvicorn reloads itself first, which breaks any open WebSocket reload connection. And so the web page doesn't get reloaded. One has to refresh the page so the WebSocket connection is established again.
uvicorn-browser doesn't use WebSocket, instead it relies on selenium
to actually control the browser. Which is again pretty interesting. Is that something other reloaders do, e.g. in JavaScript frameworks? I always thought they mainly maintained a WebSocket connection.
So, arel has a problem (what to do when the ASGI server reloads, which closes any open connections? [right?*]), uvicorn-browser has another (it's an ASGI server-specific implementation, not agnostic)... Is there a way to solve both of these problems to have some sort of "ultimate ASGI browser reload" solution?
Edit: one solution might be to simply augment arel's JS script to retry upon WebSocket disconnects, after all...
Hold on Florimond, let me type, stop editing! hahaha
First, thanks for coming here. I'm always happy to read your messages. :pray:
Yesterday, I was playing with arel
, and yes, indeed the --reload
problem happened, and indeed, I solved it relying on a different JS script.
This is where I stopped:
Application:
from pathlib import Path
from fastapi import FastAPI
from fastapi_docs_reload import reload_docs_ui
app = FastAPI()
# @app.get("/")
# def home():
# ...
reload_docs_ui(app, [Path.cwd()])
Using uvicorn main:app --reload
is possible with the above.
It's kind of a draft, so if you try it, you see that I've hard coded the "/potato" endpoint.
Can we create a middleware to inject the script when more_body
is False
or something like that? :thinking:
Like, to use with another ASGI frameworks.
@Kludex Ah, well yes there's another limitation with arel
: what about the pages where we can't inject the {{ script }}
ourselves? FastAPI docs are a good example.
A middleware that injects the script
into the HTML might be a possibility, yes.
I've implemented
uvicorn-browser
some months ago, but the implementation is too naive. Should I improve it, and release it here as well?