zono
zono

Reputation: 8584

How can I use WSGI for my Flask app? My app uses thread

I have a python program. It produces new thread which is API server. It works on test environment. However I want to use WSGI (e.g. gunicorn) on production environment. How can I do it without major change?

There are many reasons why I want to use WSGI but one big reason is that I want to set up timeout in order to kill open connections for very slow requests. I am facing a performance issue. The very slow request affects another requests eventually.

*files

├── server.py
└── api.py

*server.py

import time
import api

api_server = api.APIServer()
api_server.daemon = True
api_server.start()

while True:
  time.sleep(1)

*api.py

import threading
from flask import Flask

class APIServer(threading.Thread):

  def __init__(self):
    threading.Thread.__init__(self)

  def run(self):
    app = Flask(__name__)

    @app.route('/')
    def index():
      return 'hello'

    app.run(host="127.0.0.1", port=5000, threaded=True)

Update 1

The real code is here. I picked up some from this code.

https://github.com/CounterpartyXCP/counterparty-lib/blob/master/counterpartylib/server.py#L403

vidstige's way is absolutely right. But I don't want to change a lot if possible.

Upvotes: 4

Views: 2118

Answers (1)

vidstige
vidstige

Reputation: 13085

The tricky part for you is to make sure you run your other thread smoothly. I suggest doing it in two steps

  1. Change the threads around so that the other stuff is started in a background thread.
  2. Then switch to gunicorn, you can start the background thread using post_worker_init server hook.

Your thread is not really needed here. You can just immediately switch to gunicorn. Just install pip install gunicorn and move out the app to e.g. server.py. This is very important.

from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
  return 'hello'

Now you can run it without threads like so FLASK_APP=server.py flask run. Once you have it at this point you can switch to a production WSGI such as gunicorn. Just launch it like this instead.

gunicorn server:app

Once you can run using gunicorn, you can configure it to use multiple threads, and even processes. If your work is IO-bound I recommend using gevent instead.

🦄

Upvotes: 1

Related Questions