TL, DR
Flask Sock and HTMX enable the creation of self-updating webpages that do not need refresh, with minimal dependencies and overhead. This is a solution you can easily implement and deploy for very simple projects.
HTMX makes webpages dynamic
HTMX is an interesting framework that helps you building interactive and self-updating webpages without other JavaScript frameworks. It lets you embed all interactivity directly in HTML.
This reduces the dependencies you may have in deploying your project, as well as the need to learn new technologies. In summary, HTMX lets you achieve a good level of animation and interactivity in your web application without forcing you to use React, Vue, or the trendy JavaScript framework of the moment.
To use HTMX in your webpage you need to source it like you would do with any other JavaScript file:
<!-- Load from unpkg -->
<script src="https://unpkg.com/htmx.org@1.6.1">
</script>
After that, in order to have some element that connects with a websocket all you need to do is to set it up this way:
<div hx-ws="connect:/chatroom">
<div id="chat_room">
...
</div>
<form hx-ws="send">
<input name="chat_message">
</form>
</div>
This will create a connection with the chatroom
endpoint when the page is loaded. Content that is sent down from the websocket will be parsed as HTML and swapped in by the id
property in the chat_room
div.
You can read more about HTMX on their website. They include plenty of examples for integration with Python, Java, or .NET backend.
Flask-Sock simplifies WebSockets
Flask-Sock is a relatively new Python library that enables simple and hassle-free support for WebSockets in Flask. You need to be on a Flask version from 2.0 onward if you want to use the included Werkzeug web server for development. And probably it’s what you want to do anyway, as the version 2.0 of Flask brought plenty of good news, like support for async and many other goodies.
Installing Flask-Sock can be easily done with pip. We suggest you do so in a virtual environment, as best practices recommend:
pip install flask-sock
Using Flask-Sock is equally simple. A minimal example, as also reported in the library documentation, is the following:
from flask import Flask, render_template
from flask_sock import Sock
app = Flask(__name__)
sock = Sock(app)
@sock.route('/echo')
def echo(ws):
while True:
data = ws.receive()
# Do anything you want with data
ws.send(data)
Combining HTMX and Flask-Sock
So, if we want to have a webpage that automatically updates itself, combining HTMX and Flask-Sock is pretty much all we need to do. We will show it in our toy example.
First of all, we need to create a webpage that sources HTMX – locally or from a CDN. Then we need to create our WebSocket connection. In this case, we will create the placeholder for a clock.
...
<div>
<p>Simple clock that update itself each 5 seconds using HTMX and Flask-Sock</p>
</div>
<div hx-ws="connect:/clock">
<div id="clock">
...
</div>
</div>
...
Then we need to create the corresponding WebSocket route in Flask with Flask Sock, like this:
...
@sock.route("/clock")
def timeflow(ws):
while True:
new_time = """<div id="clock"><p>Current date and time: {}</p></div>""".format(
datetime.now().strftime("%Y-%m-%d %H:%M:%S")
)
ws.send(new_time)
time.sleep(5)
...
As you can see, we use datetime to generate the current time and date, and we insert it into a formatted string. Then we send the HTML code fragment via the WebSocket, and HTMX will position it into the clock
div for us. Transitions will be timely and without the need to refresh the page!
This Github repository contains an additional example that includes calling an API to retrieve content and publish it seamlessly on the webpage, still without refreshing. You can actually run any arbitrary function of choice to create the new content updating your webpage.
Self-updating webpages without refresh summary
In summary, we showed that using Flask and HTMX we can create self-updating webpages that will automatically display new content without the need to refresh the webpage. This is helpful for many use cases, hope you can find this useful!
Related links
Do you like our content? Check more of our posts in our blog!