Merge pull request #799 from graingert/patch-3

#799 Support loading config from module

Thanks!
This commit is contained in:
Benoit Chesneau 2014-06-20 11:54:16 +02:00
commit d3832df37d
6 changed files with 43 additions and 8 deletions

View File

@ -52,7 +52,8 @@ After installing Gunicorn you will have access to the command line script
Commonly Used Arguments Commonly Used Arguments
+++++++++++++++++++++++ +++++++++++++++++++++++
* ``-c CONFIG, --config=CONFIG`` - Specify the path to a `config file`_ * ``-c CONFIG, --config=CONFIG`` - Specify the path to a `config file`_ or
python module.
* ``-b BIND, --bind=BIND`` - Specify a server socket to bind. Server sockets * ``-b BIND, --bind=BIND`` - Specify a server socket to bind. Server sockets
can be any of ``$(HOST)``, ``$(HOST):$(PORT)``, or ``unix:$(PATH)``. can be any of ``$(HOST)``, ``$(HOST):$(PORT)``, or ``unix:$(PATH)``.
An IP is a valid ``$(HOST)``. An IP is a valid ``$(HOST)``.

View File

@ -18,7 +18,7 @@ config
* ``-c FILE, --config FILE`` * ``-c FILE, --config FILE``
* ``None`` * ``None``
The path to a Gunicorn config file. The path to a Gunicorn config file, or python module.
Only has an effect when specified on the command line or as part of an Only has an effect when specified on the command line or as part of an
application specific configuration. application specific configuration.

View File

@ -75,11 +75,9 @@ class BaseApplication(object):
sys.exit(1) sys.exit(1)
class Application(BaseApplication): class Application(BaseApplication):
def load_config_from_file(self, filename):
""" def get_config_from_filename(self, filename):
Loads the configuration file: the file is a python file, otherwise raise an RuntimeError
Exception or stop the process if the configuration file contains a syntax error.
"""
if not os.path.exists(filename): if not os.path.exists(filename):
raise RuntimeError("%r doesn't exist" % filename) raise RuntimeError("%r doesn't exist" % filename)
@ -97,6 +95,22 @@ class Application(BaseApplication):
traceback.print_exc() traceback.print_exc()
sys.exit(1) sys.exit(1)
return cfg
def get_config_from_module_name(self, module_name):
return util.import_module(module_name).__dict__
def load_config_from_module_name_or_filename(self, location):
"""
Loads the configuration file: the file is a python file, otherwise raise an RuntimeError
Exception or stop the process if the configuration file contains a syntax error.
"""
try:
cfg = self.get_config_from_module_name(module_name=location)
except ImportError:
cfg = self.get_config_from_filename(filename=location)
for k, v in cfg.items(): for k, v in cfg.items():
# Ignore unknown names # Ignore unknown names
if k not in self.cfg.settings: if k not in self.cfg.settings:
@ -109,6 +123,11 @@ class Application(BaseApplication):
return cfg return cfg
def load_config_from_file(self, filename):
return self.load_config_from_module_name_or_filename(
location=filename
)
def load_config(self): def load_config(self):
# parse console args # parse console args
parser = self.cfg.parser() parser = self.cfg.parser()

View File

@ -454,7 +454,7 @@ class ConfigFile(Setting):
validator = validate_string validator = validate_string
default = None default = None
desc = """\ desc = """\
The path to a Gunicorn config file. The path to a Gunicorn config file, or python module.
Only has an effect when specified on the command line or as part of an Only has an effect when specified on the command line or as part of an
application specific configuration. application specific configuration.

0
tests/config/__init__.py Normal file
View File

View File

@ -14,6 +14,8 @@ from gunicorn.app.base import Application
from gunicorn.workers.sync import SyncWorker from gunicorn.workers.sync import SyncWorker
dirname = os.path.dirname(__file__) dirname = os.path.dirname(__file__)
def cfg_module():
return 'config.test_cfg'
def cfg_file(): def cfg_file():
return os.path.join(dirname, "config", "test_cfg.py") return os.path.join(dirname, "config", "test_cfg.py")
def paster_ini(): def paster_ini():
@ -185,12 +187,25 @@ def test_load_config():
t.eq(app.cfg.workers, 3) t.eq(app.cfg.workers, 3)
t.eq(app.cfg.proc_name, "fooey") t.eq(app.cfg.proc_name, "fooey")
def test_load_config_module():
with AltArgs(["prog_name", "-c", cfg_module()]):
app = NoConfigApp()
t.eq(app.cfg.bind, ["unix:/tmp/bar/baz"])
t.eq(app.cfg.workers, 3)
t.eq(app.cfg.proc_name, "fooey")
def test_cli_overrides_config(): def test_cli_overrides_config():
with AltArgs(["prog_name", "-c", cfg_file(), "-b", "blarney"]): with AltArgs(["prog_name", "-c", cfg_file(), "-b", "blarney"]):
app = NoConfigApp() app = NoConfigApp()
t.eq(app.cfg.bind, ["blarney"]) t.eq(app.cfg.bind, ["blarney"])
t.eq(app.cfg.proc_name, "fooey") t.eq(app.cfg.proc_name, "fooey")
def test_cli_overrides_config_module():
with AltArgs(["prog_name", "-c", cfg_module(), "-b", "blarney"]):
app = NoConfigApp()
t.eq(app.cfg.bind, ["blarney"])
t.eq(app.cfg.proc_name, "fooey")
def test_default_config_file(): def test_default_config_file():
default_config = os.path.join(os.path.abspath(os.getcwd()), default_config = os.path.join(os.path.abspath(os.getcwd()),
'gunicorn.conf.py') 'gunicorn.conf.py')