-
-
Save vrslev/6d0602bfa939a01844f645c608afb85a to your computer and use it in GitHub Desktop.
import os | |
import arel | |
from fastapi import FastAPI, Request | |
from fastapi.templating import Jinja2Templates | |
app = FastAPI() | |
templates = Jinja2Templates("templates") | |
if _debug := os.getenv("DEBUG"): | |
hot_reload = arel.HotReload(paths=[arel.Path(".")]) | |
app.add_websocket_route("/hot-reload", route=hot_reload, name="hot-reload") | |
app.add_event_handler("startup", hot_reload.startup) | |
app.add_event_handler("shutdown", hot_reload.shutdown) | |
templates.env.globals["DEBUG"] = _debug | |
templates.env.globals["hot_reload"] = hot_reload | |
@app.get("/") | |
def index(request: Request): | |
return templates.TemplateResponse("index.html", context={"request": request}) | |
# run: | |
# DEBUG=true uvicorn main:app --reload |
fastapi | |
uvicorn[standard] | |
arel | |
jinja2 |
<body> | |
{% block content %}{% endblock %} | |
<!-- Hot reload script --> | |
{% if DEBUG %} {{ hot_reload.script(url_for('hot-reload')) | safe }} {% endif | |
%} | |
</body> |
{% extends "base.html" %} {% block content %} Hello, world! {% endblock %} |
Great! This kind of tool should be included as standard in frameworks like FastAPI and Jinja. Wonderful!
Great! This kind of tool should be included as standard in frameworks like FastAPI and Jinja. Wonderful!
@philmade Definitely! I like the vibe of frontend frameworks and tooling: they have such things by default, and it is amazing.
Huh, this didn't work in my instance, were there other steps you took to get this working? How did you load the FastAPI server, uvicorn?
@philmade I added a comment with running instruction, thanks!
I can see a WS connection open from the logs:
Done in 79ms.
INFO: Application startup complete.
INFO: 127.0.0.1:53242 - "GET / HTTP/1.1" 200 OK
INFO: ('127.0.0.1', 53244) - "WebSocket /hot-reload" [accepted]
INFO: connection open
and I can see the script in html:
<html lang="en">
<head>
<link rel="stylesheet" href="http://127.0.0.1:8000/static/css/main.css" type="text/css" />
<meta name="description" content="Home page description FUCKER!" />
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width" />
<title>Home</title>
</head>
<body>
<section id="body" class="flex flex-col bg-slate-50 justify-center items-center max-w-screen-lg m-auto">
<div class="flex flex-col justify-center items-center py-10">
<h2 class="text-2xl leading-relaxed text-slate-800 uppercase">Welcomsdsdsdsddsdsdsdsdsdsdsdsa</h2>
<div class="flex flex-col justify-center content-center text-center">
<img src="https://i.discogs.com/mXy5VCH7vfETEiVVrn4Slw_wKARXL7zYBcvEzQWwb7k/rs:fit/g:sm/q:90/h:544/w:600/czM6Ly9kaXNjb2dz/LWRhdGFiYXNlLWlt/YWdlcy9BLTUyMzEy/My0xNTcwMTc4NjE4/LTE2MTQuanBlZw.jpeg"/>
<span class="py-4 uppercase font-bold">Beirut</span>
</div>
</div>
</section>
<script>const ws = new WebSocket("ws://127.0.0.1:8000/hot-reload");
ws.onmessage = () => window.location.reload();
</script>
</body>
</html>
however the page does not get reloaded on save. Am I missing something?
This works for me, but only on the routes defined within the main file where app
is defined. Any ideas on how to get this to work on other routes? I have separate routes defined within a routers
directory and then apply them in the main file with app.include_router(my_router)
.
@dicolasi Please share your code 😊
@thisisthemurph I don't understand exactly your setup. Can you share a minimal reproducible example of what you're saying?
It works in Safari (Version 17.2 (19617.1.17.11.9)) just fine.
It works in Safari (Version 17.2 (19617.1.17.11.9)) just fine.
@yanky2000 Just tested it in Safari 17.1—it also works. Removed the comment, thanks.
Pretty neat 👍