arel
Browser hot reload for Python ASGI web apps.
Overview
What is this for?
arel can be used to implement development-only hot-reload for non-Python files that are not read from disk on each request. This may include HTML templates, GraphQL schemas, cached rendered Markdown content, etc.
How does it work?
arel watches changes over a set of files. When a file changes, arel notifies the browser (using WebSocket), and an injected client script triggers a page reload. You can register your own reload hooks for any extra server-side operations, such as reloading cached content or re-initializing other server-side resources.
Installation
pip install 'arel==0.5.*'
Quickstart
For a working example using Starlette, see the Example section.
Although the exact instructions to set up hot reload with arel depend on the specifics of your ASGI framework, there are three general steps to follow:
-
Create an
HotReloadinstance, passing one or more directories of files to watch, and optionally a list of callbacks to call before a reload is triggered:import arel async def reload_data(): print("Reloading server data...") hotreload = arel.HotReload( paths=[ arel.Path("./server/data", on_reload=[reload_data]), arel.Path("./server/static"), ], )
-
Mount the hot reload endpoint, and wire its startup and shutdown into the application's lifespan. If using Starlette, this can be done like this:
from contextlib import asynccontextmanager from starlette.applications import Starlette from starlette.routing import WebSocketRoute @asynccontextmanager async def lifespan(app): await hotreload.startup() try: yield finally: await hotreload.shutdown() app = Starlette( routes=[WebSocketRoute("/hot-reload", hotreload, name="hot-reload")], lifespan=lifespan, )
-
Add the JavaScript code to your website HTML. If using Starlette with Jinja templates, you can do this by updating the global environment, then injecting the script into your base template:
templates.env.globals["DEBUG"] = os.getenv("DEBUG") # Development flag. templates.env.globals["hotreload"] = hotreload
<body> <!-- Page content... --> <!-- Hot reload script --> {% if DEBUG %} {{ hotreload.script(url_for('hot-reload')) | safe }} {% endif %} </body>
Example
The example directory contains an example Markdown-powered website that uses arel to refresh the browser when Markdown content or HTML templates change.
License
MIT
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog.
0.5.0 - 2026-10-20
Added
- Add support for Starlette 1.x. This widens the
starlettedependency to>=0.21,<2.0, and addsanyio>=3.4,<5as a direct dependency. (Pull #42) - Add optional nonce parameter to HotReload.script() (Pull #41)
Changed
- Users must now register
hotreload.startupandhotreload.shutdownfrom alifespancontext manager. Starlette 1.0 removed theon_startupandon_shutdownarguments. Please see the updated README for usage. (Pull #42, #43)
0.4.0 - 2025-09-22
Removed
- Drop support for Python 3.7 and 3.8 (EOL versions). (Pull #39)
Added
- Add support for Python 3.13. (Pull #39)
Fixed
- Update watchfiles dependency to support modern versions (>=0.18,<2.0). (Pull #39)
0.3.0 - 2023-12-29
Changed
- Use
watchfilesinstead ofwatchgod. This unlocks Python 3.12 support. (Pull #34)
Added
- Add support for Python 3.12. (Pull #35)
0.2.0 - 2020-07-08
Added
- Add support for watching multiple directories, each with its own reload callbacks. (Pull #15)
Changed
arel.HotReload("./directory", on_reload=[...])should now be written asarel.HotReload(paths=[arel.Path("./directory", on_reload=[...])]). (Pull #15)
0.1.0 - 2020-04-11
Initial release.
Added
- Add
HotReloadASGI application class. (Pull #1)
Metadata
Release files for arel 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| arel-0.5.0.tar.gz | 14.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| arel-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 23.5 kB
Release files / arel-0.5.0.tar.gz
| Download URL | arel-0.5.0.tar.gz |
|---|---|
| Size | 14.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
422a27f089835951cf0931db848e26176341593ba33364f03de89c1c00ef66dd
|
|
BLAKE2b-256 checksum How to use checksums |
4017baf088f4a04d163b4be8d82d6628a9a4c25bf2019613c4b60aee000195bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.15
|
Release files / arel-0.5.0-py3-none-any.whl
| Download URL | arel-0.5.0-py3-none-any.whl |
|---|---|
| Size | 8.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e7680a40373e827beeeb14f0f6f8dc7aab9deed5dd9ce2d71b79efbf6203c8d7
|
|
BLAKE2b-256 checksum How to use checksums |
c8932092b311b3b20e5bbdceb1da74b0422a03ee01c9b2205649a72a222ab53b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.15
|
Security for arel 0.5.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.