I am having an issue when running a Flask server with guncicorn where the server code is wrapped in a Class.
Here is my server class:
class WebServer:
def __init__(self):
self.app = Flask(__name__)
self.generateURL()
def generateURL(self):
self.app.route("/")(self.test)
self.app.route('/weight', methods=['GET'])(self.receive_weight)
self.app.route('/usage', methods=['GET'])(self.receive_usage)
...
def run(self):
self.app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
if __name__ == "__main__":
my_app = WebServer()
my_app.run()
I tried to use gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 WebServer:my_app
to run the server, but I got the error:
2023-04-10 01:41:27 Failed to find attribute 'my_app' in 'WebServer'.
2023-04-10 01:41:27 [2023-04-10 05:41:27 +0000] [6] [INFO] Worker exiting (pid: 6)
2023-04-10 01:41:27 [2023-04-10 05:41:27 +0000] [1] [INFO] Shutting down: Master
2023-04-10 01:41:27 [2023-04-10 05:41:27 +0000] [1] [INFO] Reason: App failed to load.
May I ask for the right command to run this Flask server which is wrapped in a Class with gunicorn?
Thanks!
This isn't working because gunicorn expects an object of your Flask application. Your my_app.run()
return None
which will not work with gunicorn. Another method for you is to modify the run method to return an self.app
without giving the host or port as Gunicorn will take care of that. The creation should then take place through an explicit method call. This is how you can go about it:
class WebServer:
def __init__(self):
self.app = Flask(__name__)
self.generateURL()
def generateURL(self):
self.app.route("/")(self.test)
self.app.route('/weight', methods=['GET'])(self.receive_weight)
self.app.route('/usage', methods=['GET'])(self.receive_usage)
...
def run(self):
return self.app
def create_app():
my_app = WebServer()
return my_app.run()
To run the above app use the command, assuming your file's name is 'WebServer.py`:
gunicorn --bind=0.0.0.0:8080 --workers 1 --threads 8 --timeout 0 "WebServer:create_app()"