How to use Flask-Script and Gunicorn

I wrote a better version of GunicornServer based on Sean Lynch's, the command now accept all gunicorn's arguments

from yourapp import app
from flask.ext.script import Manager, Command, Option

class GunicornServer(Command):
    """Run the app within Gunicorn"""

    def get_options(self):
        from gunicorn.config import make_settings

        settings = make_settings()
        options = (
            Option(*klass.cli, action=klass.action)
            for setting, klass in settings.iteritems() if klass.cli
        )
        return options

    def run(self, *args, **kwargs):
        from gunicorn.app.wsgiapp import WSGIApplication

        app = WSGIApplication()
        app.app_uri = 'manage:app'
        return app.run()

manager = Manager(app)
manager.add_command("gunicorn", GunicornServer())

Based the answer of the Sean, I also wrote a version more preferred to me.

@manager.option('-h', '--host', dest='host', default='127.0.0.1')
@manager.option('-p', '--port', dest='port', type=int, default=6969)
@manager.option('-w', '--workers', dest='workers', type=int, default=3)
def gunicorn(host, port, workers):
    """Start the Server with Gunicorn"""
    from gunicorn.app.base import Application

    class FlaskApplication(Application):
        def init(self, parser, opts, args):
            return {
                'bind': '{0}:{1}'.format(host, port),
                'workers': workers
            }

        def load(self):
            return app

    application = FlaskApplication()
    return application.run()

you can run the gunicorn using command like thispython manager.py gunicorn


Flask actually has docs to run Gunicorn here.

You have to remember that Gunicorn is a WSGI server with some niceties.


As Dhaivat said, you can just use your Flask app directly with Gunicorn.

If you still want to use Flask-Script, you will need to create a custom Command. I don't have any experience with Gunicorn, but I found a similar solution for Flask-Actions and ported it to Flask-Script, although be warned, it's untested.

from flask_script import Command, Option

class GunicornServer(Command):

    description = 'Run the app within Gunicorn'

    def __init__(self, host='127.0.0.1', port=8000, workers=4):
        self.port = port
        self.host = host
        self.workers = workers

    def get_options(self):
        return (
            Option('-H', '--host',
                   dest='host',
                   default=self.host),

            Option('-p', '--port',
                   dest='port',
                   type=int,
                   default=self.port),

            Option('-w', '--workers',
                   dest='workers',
                   type=int,
                   default=self.workers),
        )

    def handle(self, app, host, port, workers):

        from gunicorn import version_info

        if version_info < (0, 9, 0):
            from gunicorn.arbiter import Arbiter
            from gunicorn.config import Config
            arbiter = Arbiter(Config({'bind': "%s:%d" % (host, int(port)),'workers': workers}), app)
            arbiter.run()
        else:
            from gunicorn.app.base import Application

            class FlaskApplication(Application):
                def init(self, parser, opts, args):
                    return {
                        'bind': '{0}:{1}'.format(host, port),
                        'workers': workers 
                    }

                def load(self):
                    return app

            FlaskApplication().run()

You can then either register it to replace Flask's local development server at python manage.py runserver

manager.add_command("runserver", GunicornServer())

or register as a new command such as python manage.py gunicorn

manager.add_command("gunicorn", GunicornServer())

Edit June 2016: With the latest version of Flask-Script, change the method handle with __call__. old flask-script vs new flask-script