Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gunicorn + flask (connexion/swagger_server) time out/not responding to API requests

swagger_server connexion/flask running fine when I do:

python3 -m swagger_server

It's running on port 8080.

When I try to put it on gunicorn (reference: how to use gunicorn with swagger_server on flask), gunicorn runs fine but requests to port 8080 fail.

First, when I use the same port 8080, it complains of bind/already in use (expected, I believe, as they're both on port 8080):

gunicorn "swagger_server.__main__:main" -b 0.0.0.0:8080 -w 4
...
OSError: [Errno 48] Address already in use

But when I move to port 4000, for example, requests time out:

gunicorn "swagger_server.__main__:main" -b 0.0.0.0:4000 -w 4
...
 * Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
[2020-02-16 17:21:18 -0500] [34798] [CRITICAL] WORKER TIMEOUT (pid:34802)

When I enable debug, I see it's trying to connect to port 4000, instead of 8080.

[2020-02-16 17:28:13 -0500] [34866] [INFO] Starting gunicorn 20.0.4
[2020-02-16 17:28:13 -0500] [34866] [ERROR] Connection in use: ('0.0.0.0', 4000)
[2020-02-16 17:28:13 -0500] [34866] [ERROR] Retrying in 1 second.
[2020-02-16 17:28:14 -0500] [34866] [ERROR] Connection in use: ('0.0.0.0', 4000)
...

Here's my main.py

def main(arg1, arg2):
    app = connexion.App(__name__, specification_dir='./swagger_server/', debug=False)
    app.app.json_encoder = encoder.JSONEncoder
    app.add_api('api-v2.yaml', arguments={'title': 'API'})
    app.run(host='0.0.0.0', port=8080)


if __name__ == '__main__':
    main(None, None)

Please advise what I'm missing here. Thank you.

like image 965
roysterphil Avatar asked Nov 21 '25 20:11

roysterphil


1 Answers

Swagger generates __main__.py in wrong way, you need to make a modifition base on it.

#!/usr/bin/env python3

import connexion

from swagger_server import encoder

app = connexion.App(__name__, specification_dir='./swagger/')
app.app.json_encoder = encoder.JSONEncoder
app.add_api('swagger.yaml', arguments={'title': 'My API'}, pythonic_params=True)

Then try it again

gunicorn swagger_server.__main__:app 

Gunicorn wraps netowrk request in WSGI and forward to flask(werkzeug), the varible app in __main__.py is werkzeug WSGI entry point.

like image 114
Tony Avatar answered Nov 24 '25 10:11

Tony



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!