Specify wsgi_app in config #1359.

This commit is contained in:
Hasan Ramezni 2017-01-31 01:20:06 +03:30 committed by Hasan Ramezani
parent a232c270fd
commit 57a9e2eb7e
6 changed files with 81 additions and 6 deletions

View File

@ -21,12 +21,15 @@ gunicorn
Basic usage::
$ gunicorn [OPTIONS] APP_MODULE
$ gunicorn [OPTIONS] [WSGI_APP]
Where ``APP_MODULE`` is of the pattern ``$(MODULE_NAME):$(VARIABLE_NAME)``. The
Where ``WSGI_APP`` is of the pattern ``$(MODULE_NAME):$(VARIABLE_NAME)``. The
module name can be a full dotted path. The variable name refers to a WSGI
callable that should be found in the specified module.
.. versionchanged:: 20.1.0
``WSGI_APP`` is optional if it is defined in a :ref:`config` file.
Example with the test app:
.. code-block:: python

View File

@ -42,6 +42,17 @@ application specific configuration.
Loading the config from a Python module requires the ``python:``
prefix.
.. _wsgi-app:
wsgi_app
~~~~~~~~
* ``None``
A WSGI application path in pattern ``$(MODULE_NAME):$(VARIABLE_NAME)``.
.. versionadded:: 20.1.0
Debugging
---------

View File

@ -12,6 +12,8 @@ from gunicorn import util
class WSGIApplication(Application):
def init(self, parser, opts, args):
self.app_uri = None
if opts.paste:
from .pasterapp import has_logging_config
@ -29,11 +31,18 @@ class WSGIApplication(Application):
return
if not args:
parser.error("No application module specified.")
if len(args) > 0:
self.cfg.set("default_proc_name", args[0])
self.app_uri = args[0]
self.cfg.set("default_proc_name", args[0])
self.app_uri = args[0]
def load_config(self):
super().load_config()
if self.app_uri is None:
if self.cfg.wsgi_app is not None:
self.app_uri = self.cfg.wsgi_app
else:
raise ConfigError("No application module specified.")
def load_wsgiapp(self):
return util.import_app(self.app_uri)

View File

@ -560,6 +560,17 @@ class ConfigFile(Setting):
prefix.
"""
class WSGIApp(Setting):
name = "wsgi_app"
section = "Config File"
meta = "STRING"
validator = validate_string
default = None
desc = """\
A WSGI application path in pattern ``$(MODULE_NAME):$(VARIABLE_NAME)``.
.. versionadded:: 20.1.0
"""
class Bind(Setting):
name = "bind"

View File

@ -0,0 +1 @@
wsgi_app = "app1:app1"

View File

@ -11,6 +11,7 @@ import pytest
from gunicorn import config
from gunicorn.app.base import Application
from gunicorn.app.wsgiapp import WSGIApplication
from gunicorn.errors import ConfigError
from gunicorn.workers.sync import SyncWorker
from gunicorn import glogging
@ -25,6 +26,8 @@ def cfg_file():
return os.path.join(dirname, "config", "test_cfg.py")
def alt_cfg_file():
return os.path.join(dirname, "config", "test_cfg_alt.py")
def cfg_file_with_wsgi_app():
return os.path.join(dirname, "config", "test_cfg_with_wsgi_app.py")
def paster_ini():
return os.path.join(dirname, "..", "examples", "frameworks", "pylonstest", "nose.ini")
@ -52,6 +55,14 @@ class NoConfigApp(Application):
pass
class WSGIApp(WSGIApplication):
def __init__(self):
super().__init__("no_usage", prog="gunicorn_test")
def load(self):
pass
def test_defaults():
c = config.Config()
for s in config.KNOWN_SETTINGS:
@ -353,6 +364,7 @@ def test_invalid_enviroment_variables_config(monkeypatch, capsys):
_, err = capsys.readouterr()
assert "error: unrecognized arguments: --foo" in err
def test_cli_overrides_enviroment_variables_module(monkeypatch):
monkeypatch.setenv("GUNICORN_CMD_ARGS", "--workers=4")
with AltArgs(["prog_name", "-c", cfg_file(), "--workers", "3"]):
@ -360,6 +372,34 @@ def test_cli_overrides_enviroment_variables_module(monkeypatch):
assert app.cfg.workers == 3
@pytest.mark.parametrize("options, expected", [
(["app:app"], 'app:app'),
(["-c", cfg_file(), "app:app"], 'app:app'),
(["-c", cfg_file_with_wsgi_app(), "app:app"], 'app:app'),
(["-c", cfg_file_with_wsgi_app()], 'app1:app1'),
])
def test_wsgi_app_config(options, expected):
cmdline = ["prog_name"]
cmdline.extend(options)
with AltArgs(cmdline):
app = WSGIApp()
assert app.app_uri == expected
@pytest.mark.parametrize("options", [
([]),
(["-c", cfg_file()]),
])
def test_non_wsgi_app(options, capsys):
cmdline = ["prog_name"]
cmdline.extend(options)
with AltArgs(cmdline):
with pytest.raises(SystemExit):
WSGIApp()
_, err = capsys.readouterr()
assert "Error: No application module specified." in err
@pytest.mark.parametrize("options, expected", [
(["myapp:app"], False),
(["--reload", "myapp:app"], True),