There are ways to bootleg this with Flask, but it's not recommended. In short, Flask does not have good support for multithreading, and parallel execution is one of the requirements needed for your solution (assuming you are planning on doing this the "more" standard way).
As I mentioned in the comments Flask alone cannot do what you are trying to do. The reason for this is because in a typical HTTP/1.1 transaction (the protocol your browser and Flask are using to communicate) does not have support for bidirectional data streams. In other words: when a client sends a request to the server Flask will response with the rendered HTML page and then close the connection. What you need is for the server to preserve the connection with the client, and send to the client any updates to the textfile.txt
.
To achieve this you need to use another protocol both on the client and the server end, as well as asynchronous code execution on the server end.
Regarding protocols, the standard is Websocket for these sort of things. Regarding asynchronous code execution, this is a bit of an issue with Flask: one of the requirements of this problem is the need for the server to (1) keep track of the text file, and (2) send text file to client on update. To do this with Flask would require some multithreading, which is not very Flask-friendly. Because of this I would actually recommend looking into something like FastAPI, which comes with Websocket built-in out of the box, and can be ran asynchronously.
I should also mention that the problem you are facing is rather quite unique, and something I've personally never seen being applicable. I can't confirm it, but this does seem like a XY problem.
As an example, here is some code to do what you are looking for using Flask, Flask-SocketIO (pip install flask-socketio
), and multithreading.
Note that Socket.IO is built on top of websocket and requires its own supporting code for both the client and server end. I won't go into the details on why one over the other, but just understand that there is a significant difference between vanilla Websocket and Socket.IO in terms of usage, application, etc. Also note that using threading
with Flask causes undefined behaviors that are annoying to have to deal with. Things like auto-reloading will break and force you to constantly reload the app.
Again: I can't express enough how I feel this is a problem better solved with FastAPI (due to the ability of asynchronous code execution), but for the sake of answering your question directly here is a subpar implementation with Flask:
from flask import Flask, render_template
from flask_socketio import SocketIO
from threading import Thread
from time import sleep
app = Flask(__name__)
io = SocketIO(app)
@app.route("/")
def index():
return render_template("texts.html", content=get_file())
def get_file(loop=False, io=None):
text = open("textfile.txt", "rb")
def read():
data = text.read()
text.seek(0)
return data
old = read()
while loop:
current = read()
if current != old:
io.emit("text", read().decode("utf-8"), broadcast=True)
old = current
sleep(1)
return text.read().decode("utf-8")
if __name__ == "__main__":
Thread(target=lambda: get_file(loop=True, io=io)).start()
io.run(app, debug=True)
In the client side you need to have:
<html>
<head>
<style>
.textzone {
overflow: scroll;
border: 3px solid #009688;
width: 330px;
background-color: rgb(231, 226, 226);
height: 330px;
position: relative;
left: 125px;
top: 80px;
-webkit-box-shadow: 11px 11px 10px 2px #262626;
box-shadow: 11px 11px 10px 2px #262626;
padding: 20px;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
<script type="text/javascript" charset="utf-8">
console.log("running.");
const socket = io('http://127.0.0.1:5000')
socket.on('text', function(msg) {
document.getElementById("content").innerHTML = msg;
});
</script>
</head>
<body>
<div class="textzone">
<pre id="content">{{ content }}</pre>
</div>
</body>
</html>