florimondmanca / arel Goto Github PK
View Code? Open in Web Editor NEWLightweight browser hot reload for Python ASGI web apps
Home Page: https://pypi.org/project/arel
License: MIT License
Lightweight browser hot reload for Python ASGI web apps
Home Page: https://pypi.org/project/arel
License: MIT License
The example doesn't work out-of-the-box, as changes aren't reloaded. IMO, this line in examples/server/settings.py
should default to True
:
DEBUG = config("DEBUG", cast=bool, default=False)
As background, I was working very slowly on writing just this very thing: a reloader more sophisticated/performant than livereload
, based on the watchgod
changeset approach, in Starlette. But learning asyncio was really slowing me down. Thanks!
looks good
Assuming I have two arel.HotReload
instances registered (one for a "content" directory, one for the "templates" directory):
{% if settings.DEBUG %}
{{ content_reload.script(url_for('content-reload')) | safe }}
{{ templates_reload.script(url_for('templates-reload')) | safe }}
{% endif %}
This triggers the following error once the page loads in the browser:
SyntaxError: redeclaration of const ws
Ideally we should only have to register a single script anyway โ but this requires addressing the "watch multiple dirs and maybe do different on_reload
actions for each" use case a bit more.
Anyway, logging this here for visibility.
Currently when arel triggers a page reload, the page scrolls back to the top. In tight edit loops where we're comparing changes in the middle of the page, this can become tiresome.
Let's store the client Y scroll position before reloading and restore it after reload. We can probably use localStorage
to achieve this.
We get a warning when running tests:
tests/test_example.py::test_example
/Users/florimond/Developer/florimondmanca-projects/arel/venv/lib/python3.11/site-packages/starlette/concurrency.py:19: DeprecationWarning: run_until_first_complete is deprecated and will be removed in a future version.
warnings.warn(
As per encode/starlette#1443, the alternative seems to be to use anyio
:
async def run_until_first_complete(*args: typing.Tuple[typing.Callable, dict]) -> None:
async def run(handler, kwargs):
await handler(**kwargs)
tg.cancel_scope.cancel()
async with anyio.create_task_group() as tg:
for handler, kwargs in args:
tg.start_soon(run, handler, kwargs)
We only support asyncio
for now (see usage of asyncio.Event()
). So as a first step, we could resolve the warning by bringing back what Starlette was doing before anyio
...
async def run_until_first_complete(*args: typing.Tuple[typing.Callable, dict]) -> None:
tasks = [create_task(handler(**kwargs)) for handler, kwargs in args]
(done, pending) = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
[task.cancel() for task in pending]
[task.result() for task in done]
I currently have big issues with running the middleware version of arel and pytest together, i have some Pydantic settings loaded that block arel from being loaded unless an enviroment variable is set (and it also has a default value). Arel loads either way and i dont know how to fix it.
Prompted by Kludex/uvicorn-extensions#15 (comment)
Problem description
Currently, arel
can be used by injecting a {{ script }}
in the user's app HTML.
But this is not workable on HTML the user can't control.
For example, the user may want their FastAPI docs page to reload when their Uvicorn server restarts, as the OpenAPI schema may have changed due to
On the other hand, it's possible they wouldn't want that. Maybe they're busy testing things in the Swagger UI and, while they're doing edits in the their Python source code, they may not want to lose what they've done in the UI (e.g. authentication credentials).
How should we address these use cases?
Suggested solution
TODO
Possible alternatives
{{ script }}
thing with automatic injection on HTML pages.
</body>
closing tag. When running in DEBUG
mode, users would turn this behavior off by not including the middleware.fastapi-debug-toolbar
(since that's an HTML page as well).HotReload
should be an actual ASGI app that we can mount onto an app, instead of having to manually register its WebSocketEndpoint
:
import arel
from starlette.applications import Starlette
from starlette.routing import Mount
hotreload = arel.HotReload("./path/to/files")
app = Starlette(
routes=[Mount("/hot-reload", hotreload, name="hot-reload")],
on_startup=[hotreload.startup],
on_shutdown=[hot_reaload.shutdown],
)
Then the WebSocketEndpoint
could be provided internally at /
, so that the route name stays hot-reload
, i.e. whatever is given to Mount
.
Wouldn't remove the need to register event handlers (most frameworks don't support lifespan on sub-apps, eg see encode/starlette#649), but at least it's a bit less framework-specific surface.
It appears that, in _on_changes
, the callbacks and notify
are called without passing the changeset.
I'm interested in handlers that know what changed, then do the least amount of work needed. Using the bundled example as a scenario, instead of regenerating the entire set of pages, only updating one.
It would be a great feature to add the ability to include/exclude paths!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.