gunicorn/gunicorn/config.py
2010-02-17 10:59:33 +01:00

120 lines
3.4 KiB
Python

# -*- coding: utf-8 -
#
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.
import os
import sys
from gunicorn import util
class Config(object):
DEFAULTS = dict(
bind='127.0.0.1:8000',
daemon=False,
debug=False,
logfile='-',
loglevel='info',
pidfile=None,
workers=1,
umask=0,
user=None,
group=None,
after_fork=lambda server, worker: server.log.info(
"worker=%s spawned pid=%s" % (worker.id, str(worker.pid))),
before_fork=lambda server, worker: server.log.info(
"worker=%s spawning" % worker.id),
before_exec=lambda server: server.log.info("forked child, reexecuting")
)
def __init__(self, cmdopts, path=None):
if not path:
self.config_file = os.path.join(os.getcwd(), 'gunicorn.conf.py')
else:
self.config_file = os.path.abspath(os.path.normpath(path))
self.cmdopts = cmdopts
self.conf = {}
self.load()
def _load_file(self):
"""
Returns a dict of stuff found in the config file.
Defaults to $PWD/gunicorn.conf.py.
"""
if not os.path.exists(self.config_file):
return {}
config = {}
try:
execfile(self.config_file, config)
except:
sys.exit("Could not read config file %r" % (self.config_file,))
config.pop("__builtins__", None)
return config
def load(self):
self.conf = self.DEFAULTS.copy()
self.conf.update(self._load_file())
for key, value in list(self.cmdopts.items()):
if value and value is not None:
self.conf[key] = value
def __getitem__(self, key):
try:
return getattr(self, key)
except AttributeError:
pass
return self.conf[key]
def __getattr__(self, key):
try:
getattr(super(Config, self), key)
except AttributeError:
if key in self.conf:
return self.conf[key]
raise
def __contains__(self, key):
return (key in self.conf)
def __iter__(self):
return self.conf.iteritems()
@property
def workers(self):
if not self.conf.get('workers'):
raise RuntimeError("invalid workers number")
workers = int(self.conf["workers"])
if not workers:
raise RuntimeError("number of workers < 1")
if self.conf['debug'] == True:
workers = 1
return workers
@property
def address(self):
if not self.conf['bind']:
raise RuntimeError("Listener address is not set")
return util.parse_address(util.to_bytestring(self.conf['bind']))
def _hook(self, hookname, *args):
hook = self.conf.get(hookname)
if not hook: return
if not callable(hook):
raise RuntimeError("%s hook isn't a callable" % hookname)
return hook(*args)
def after_fork(self, *args):
return self._hook("after_fork", *args)
def before_fork(self, *args):
return self._hook("before_fork", *args)
def before_exec(self, *args):
return self._hook("before_exec", *args)