No project description provided
Project description
FastAPI Reloader
A lightweight middleware ASGI applications that enables automatic browser page reloading during development.
Features
- 🔄 Automatic browser refresh when server restarts
- 🚀 Works with any ASGI application and any event loop
- 🔌 Simple integration with just two steps
Installation
pip install fastapi-reloader
For a more comprehensive development experience, consider using uvicorn-hmr which includes this package:
pip install uvicorn-hmr[all]
Then run your app with:
uvicorn-hmr main:app --refresh
Standalone Usage
You can also use fastapi-reloader as a standalone package without uvicorn-hmr. However, there are a few things to keep in mind.
It's important to understand the roles of the different packages:
uvicorn-hmrProvides server-side hot module reloading (as a drop-in replacement foruvicorn --reload).fastapi-reloaderTriggers a browser page refresh when the server restarts.
If you configure fastapi-reloader manually and run your ASGI app with a standard reloader like uvicorn --reload, the behavior will be similar to uvicorn-hmr --refresh but with "cold" (process-restarting) server reloads instead of "hot" (in-process) reloads provided by hmr.
The manual integration steps are quite straightforward:
Step 1: Add Middleware
fastapi-reloader works by injecting a <script> tag into HTML responses.
from fastapi import FastAPI
from fastapi_reloader import auto_refresh_middleware
app = FastAPI()
app.add_middleware(auto_refresh_middleware)
Note that this middleware must be placed before any compression middleware (like Starlette's GZipMiddleware).
If you can't place it as early as possible in the middleware stack, you can use the following ways:
# Approach 1: wrap your app with it (works with any ASGI app)
app = html_injection_middleware(app)
# Approach 2: manually add it to the user_middleware list (supported FastAPI, Starlette etc.)
app.user_middleware.append(html_injection_middleware)
It's safe to add
html_injection_middlewarein multiple places, even if their scopes overlap. We have safeguards in place to prevent double injection on both server and client side.
The auto_refresh_middleware is a convenient wrapper that applies both reloader_route_middleware and html_injection_middleware. However, you can add them separately for more control:
- Fine-grained control: If a sub-router in your application uses compression, you must add
html_injection_middlewarebefore the compression middleware on that router. - Scoped reloading: If you only want to enable auto-reloading for a specific part of your app, you can apply
html_injection_middlewareonly to that sub-router.
The
reloader_route_middlewaremounts the necessary endpoints and should typically be added to the main application instance.
from fastapi import FastAPI
from starlette.middleware.gzip import GZipMiddleware
from fastapi_reloader import html_injection_middleware, reloader_route_middleware
app = FastAPI()
# Apply the reloader routes to the main app
app.add_middleware(reloader_route_middleware)
# Apply HTML injection middleware before compression ones
app.add_middleware(html_injection_middleware)
app.add_middleware(GZipMiddleware) # or BrotliMiddleware, ZstMiddleware, etc.
FastAPI routers needs further configuration like this (because fastapi.APIRouter doesn't support middlewares directly):
app.mount(router.prefix, html_injection_middleware(router)) # place this first to shadows the next line
app.include_router(router) # this can't be removed because FastAPI needs it to generate OpenAPI schema
Step 2: Manually Triggering Reloads
When used standalone, you have to add a few lines into your code to manually trigger the reload signal (aka. call send_reload_signal()) before your ASGI server shuts down (I mean, when a server receives a shutdown signal like SIGINT/SIGTERM or it want to restart because of code changes etc.). fastapi-reloader works with any ASGI server, but most of them wait for open connections to close before shutting down. The long-polling connection internally used by uvicorn-hmr won't close on its own (because we have no idea of when it will happen), preventing the server from shutting down gracefully (behaving like a deadlock).
So you need to hook into your ASGI server's shutdown process to call send_reload_signal(). This can be done through subclassing, monkey-patching, or using a library like dowhen.
Here is an example for uvicorn:
from fastapi_reloader import send_reload_signal
import uvicorn
_shutdown = uvicorn.Server.shutdown
def shutdown(self, *args, **kwargs):
send_reload_signal()
return _shutdown(self, *args, **kwargs)
uvicorn.Server.shutdown = shutdown
and start the server as normal
uvicorn main:app --reload
or this way:
if __name__ == "__main__":
uvicorn.run("main:app", reload=True)
How It Works
The package injects a small JavaScript snippet into your HTML responses that:
- Opens a long-lived connection to the server
- Listens for reload signals
- Starts polling for heartbeat when
send_reload_signalis called - Reloads the page when heartbeat from new server is received
Configuration
The package works out-of-the-box with default settings. No additional configuration is required.
Limitations
- Unlike
uvicorn-hmr, which does on-demand fine-grained reloading on the server side, this package simply reloads all the pages in the browser. - Designed for development use only (not for production)
- Requires JavaScript to be enabled in the browser
Contributing
Contributions are welcome! Please open an issue or submit a pull request.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fastapi_reloader-1.3.4-py2.py3-none-any.whl.
File metadata
- Download URL: fastapi_reloader-1.3.4-py2.py3-none-any.whl
- Upload date:
- Size: 7.2 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ec07766f2d81d69d3661e8390a09ab2ac7efef7883f4ecb62e1ceabcf563c831
|
|
| MD5 |
3510c4c8e56b8411bd9f358d86edf35c
|
|
| BLAKE2b-256 |
5b653fa70471ec6e5ce7a996a7e3144e6ab3c8aeffc6eeefb23607cbd3529641
|