30

Assuming I'm starting a Flask app under gunicorn as per http://gunicorn.org/deploy.html#runit, is there a way for me to include/parse/access additional command line arguments?

E.g., can I include and parse the foo option in my Flask application somehow?

gunicorn mypackage:app --foo=bar

Thanks,

Derlin
  • 9,572
  • 2
  • 32
  • 53
sholsapp
  • 15,542
  • 10
  • 50
  • 67

2 Answers2

41

You can't pass command line arguments directly but you can choose application configurations easily enough.

$ gunicorn 'mypackage:build_app(foo="bar")'

Will call the function "build_app" passing the foo="bar" kwarg as expected. This function should then return the WSGI callable that'll be used.

Paul J. Davis
  • 1,709
  • 15
  • 9
  • 3
    Thanks! Got here when searching for how to pass multiple arguments. Turned out to be as simple as passing them as comma separated values; for e.g. `(foo="bar", foo1="bar1")` – Karthic Raghupathi Mar 28 '17 at 15:58
  • 10
    Note that this doesn't work in `gunicorn>=20`, you'll get a `Failed to find application object 'build_app(foo="there")' in 'mypackage'` error. See https://github.com/benoitc/gunicorn/issues/2159 – Dustin Ingram Nov 18 '19 at 23:38
  • You can pass a custom name for the app (`-n xyz-app`) and use as an identifier (`import sys, re; appid = re.search(r'\-n\s{1,}([^\s|$]+)', ''.join(sys.argv)).group(1)`).. – Ismail Aug 31 '21 at 03:33
13

I usually put it in __init.py__ after main() and then I can run with or without gunicorn (assuming your main() supports other functions too).

# __init__.py

# Normal entry point
def main():
  ...

# Gunicorn entry point generator
def app(*args, **kwargs):
    # Gunicorn CLI args are useless.
    # https://stackoverflow.com/questions/8495367/
    #
    # Start the application in modified environment.
    # https://stackoverflow.com/questions/18668947/
    #
    import sys
    sys.argv = ['--gunicorn']
    for k in kwargs:
        sys.argv.append("--" + k)
        sys.argv.append(kwargs[k])
    return main()

That way you can run simply with e.g.

gunicorn 'app(foo=bar)' ...

and your main() can use standard code that expects the arguments in sys.argv.

personal_cloud
  • 3,943
  • 3
  • 28
  • 38