miguelgrinberg / flask-sock

Modern WebSocket support for Flask.
MIT License
274 stars 24 forks source link

Try catching "AssertionError: write() before start_response" exception in a Flask application #27

Closed pedro-german closed 2 years ago

pedro-german commented 2 years ago

Hello,

I have a Python program running with flask-sock (the same library as this GitHub), which sends data to a local client (based on a web application running with Svelte as the framework). Basically, I followed the same example put in this repo, and it works perfectly fine.

Just to summarize quickly, when I execute the project, the Flask application runs as follows:

image

Which is normal condition. Then I open the local webpage (http://127.0.0.1:5000), and it establish a stable communication in both sides. The fact is, when I close the local page, the Python program throws an AssertionError located in serving.py Python file (from the werkzeug package).

image

Then, when I open back the local webpage, it reloads as if normal:

image

The questions are:

  1. How can I catch the raised AssertionError from the current decorator or function (which is currently @sock.route("/sent-package-frontend")) when the local webpage is closed or restarted?

It is necessary for me to do this since I have a BLE connection instance with many devices, and whenever the webpage is closed or restarted, the communication is lost by the raising error above.

  1. If possible, how can I make the Python program (server, in this case) to recognized when the local webpage has been opened again?

For instance, when restarted or closed, the information displayed in the local webpage is cleaned, and I have to recover it from the Python program via a notification or any signal. Currently I have a method for sending the data back to frontend via flask-sock, but since the Python program does not know when to act, the method is never executed.

Any information is greatly appreciated, and I will be attentive to any suggestion or , so we can solve this issue as soon as possible. Thanks in advance!

miguelgrinberg commented 2 years ago

You are using the flask development web server, which does not have native support for websocket. When you switch to a production server this problem will not occur anymore. Also see #21.

pedro-german commented 2 years ago

Hello,

Thanks for the reply! After some searches about both questions I described, I found a solution that works great for my case.

The first one, related with catch the AssertionError, is thanks to this post on StackOverflow, which makes use of the abort method from the flask library itself. For that it is necessary to implement the snippet over the function that manages the communication with the client (in this case, the local webpage).

As for the second one, in order to know if the client is ready/initialized, it is just sufficient with sending a package from the client with the websocket.send() method (which comes with the flask-sock class already).

As for what you stated in your comment, I apologize for my lack of knowledge regarding whether a project is in production server, but just to be sure: do you mean that when I set app.run(debug=False), it would be configured as a production server? If so, would any of the methods implemented for my case not be of use, or simply debug=False already take care of those?

Thanks in advance!

miguelgrinberg commented 2 years ago

When you use app.run or flask run to start your server you are using the Flask development web server, regardless of settings. This is a web server that is not properly written to be used in a production setting, it is only intended as a development web server. What I mean by production server is that you use a different web server, such as Gunicorn, which is designed to be used in production.

pedro-german commented 2 years ago

Understood, thanks for the explanation and your time! I will take note of that for a next project👍