You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							223 lines
						
					
					
						
							6.5 KiB
						
					
					
				
			
		
		
	
	
							223 lines
						
					
					
						
							6.5 KiB
						
					
					
				# -*- coding: utf-8 -
 | 
						|
#
 | 
						|
# This file is part of gunicorn released under the MIT license.
 | 
						|
# See the NOTICE for more information.
 | 
						|
from __future__ import print_function
 | 
						|
 | 
						|
import os
 | 
						|
import sys
 | 
						|
import traceback
 | 
						|
 | 
						|
from gunicorn._compat import execfile_
 | 
						|
from gunicorn import util
 | 
						|
from gunicorn.arbiter import Arbiter
 | 
						|
from gunicorn.config import Config, get_default_config_file
 | 
						|
from gunicorn import debug
 | 
						|
 | 
						|
class BaseApplication(object):
 | 
						|
    """
 | 
						|
    An application interface for configuring and loading
 | 
						|
    the various necessities for any given web framework.
 | 
						|
    """
 | 
						|
    def __init__(self, usage=None, prog=None):
 | 
						|
        self.usage = usage
 | 
						|
        self.cfg = None
 | 
						|
        self.callable = None
 | 
						|
        self.prog = prog
 | 
						|
        self.logger = None
 | 
						|
        self.do_load_config()
 | 
						|
 | 
						|
    def do_load_config(self):
 | 
						|
        """
 | 
						|
        Loads the configuration
 | 
						|
        """
 | 
						|
        try:
 | 
						|
            self.load_default_config()
 | 
						|
            self.load_config()
 | 
						|
        except Exception as e:
 | 
						|
            print("\nError: %s" % str(e), file=sys.stderr)
 | 
						|
            sys.stderr.flush()
 | 
						|
            sys.exit(1)
 | 
						|
 | 
						|
    def load_default_config(self):
 | 
						|
        # init configuration
 | 
						|
        self.cfg = Config(self.usage, prog=self.prog)
 | 
						|
 | 
						|
    def init(self, parser, opts, args):
 | 
						|
        raise NotImplementedError
 | 
						|
 | 
						|
    def load(self):
 | 
						|
        raise NotImplementedError
 | 
						|
 | 
						|
    def load_config(self):
 | 
						|
        """
 | 
						|
        This method is used to load the configuration from one or several input(s).
 | 
						|
        Custom Command line, configuration file.
 | 
						|
        You have to override this method in your class.
 | 
						|
        """
 | 
						|
        raise NotImplementedError
 | 
						|
 | 
						|
    def reload(self):
 | 
						|
        self.do_load_config()
 | 
						|
        if self.cfg.spew:
 | 
						|
            debug.spew()
 | 
						|
 | 
						|
    def wsgi(self):
 | 
						|
        if self.callable is None:
 | 
						|
            self.callable = self.load()
 | 
						|
        return self.callable
 | 
						|
 | 
						|
    def run(self):
 | 
						|
        try:
 | 
						|
            Arbiter(self).run()
 | 
						|
        except RuntimeError as e:
 | 
						|
            print("\nError: %s\n" % e, file=sys.stderr)
 | 
						|
            sys.stderr.flush()
 | 
						|
            sys.exit(1)
 | 
						|
 | 
						|
 | 
						|
class Application(BaseApplication):
 | 
						|
 | 
						|
    # 'init' and 'load' methods are implemented by WSGIApplication.
 | 
						|
    # pylint: disable=abstract-method
 | 
						|
 | 
						|
    def chdir(self):
 | 
						|
        # chdir to the configured path before loading,
 | 
						|
        # default is the current dir
 | 
						|
        os.chdir(self.cfg.chdir)
 | 
						|
 | 
						|
        # add the path to sys.path
 | 
						|
        if self.cfg.chdir not in sys.path:
 | 
						|
            sys.path.insert(0, self.cfg.chdir)
 | 
						|
 | 
						|
    def get_config_from_filename(self, filename):
 | 
						|
 | 
						|
        if not os.path.exists(filename):
 | 
						|
            raise RuntimeError("%r doesn't exist" % filename)
 | 
						|
 | 
						|
        cfg = {
 | 
						|
            "__builtins__": __builtins__,
 | 
						|
            "__name__": "__config__",
 | 
						|
            "__file__": filename,
 | 
						|
            "__doc__": None,
 | 
						|
            "__package__": None
 | 
						|
        }
 | 
						|
        try:
 | 
						|
            execfile_(filename, cfg, cfg)
 | 
						|
        except Exception:
 | 
						|
            print("Failed to read config file: %s" % filename, file=sys.stderr)
 | 
						|
            traceback.print_exc()
 | 
						|
            sys.stderr.flush()
 | 
						|
            sys.exit(1)
 | 
						|
 | 
						|
        return cfg
 | 
						|
 | 
						|
    def get_config_from_module_name(self, module_name):
 | 
						|
        return vars(util.import_module(module_name))
 | 
						|
 | 
						|
    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.
 | 
						|
        """
 | 
						|
 | 
						|
        if location.startswith("python:"):
 | 
						|
            module_name = location[len("python:"):]
 | 
						|
            cfg = self.get_config_from_module_name(module_name)
 | 
						|
        else:
 | 
						|
            if location.startswith("file:"):
 | 
						|
                filename = location[len("file:"):]
 | 
						|
            else:
 | 
						|
                filename = location
 | 
						|
            cfg = self.get_config_from_filename(filename)
 | 
						|
 | 
						|
        for k, v in cfg.items():
 | 
						|
            # Ignore unknown names
 | 
						|
            if k not in self.cfg.settings:
 | 
						|
                continue
 | 
						|
            try:
 | 
						|
                self.cfg.set(k.lower(), v)
 | 
						|
            except:
 | 
						|
                print("Invalid value for %s: %s\n" % (k, v), file=sys.stderr)
 | 
						|
                sys.stderr.flush()
 | 
						|
                raise
 | 
						|
 | 
						|
        return cfg
 | 
						|
 | 
						|
    def load_config_from_file(self, filename):
 | 
						|
        return self.load_config_from_module_name_or_filename(location=filename)
 | 
						|
 | 
						|
    def load_config(self):
 | 
						|
        # parse console args
 | 
						|
        parser = self.cfg.parser()
 | 
						|
        args = parser.parse_args()
 | 
						|
 | 
						|
        # optional settings from apps
 | 
						|
        cfg = self.init(parser, args, args.args)
 | 
						|
 | 
						|
        # set up import paths and follow symlinks
 | 
						|
        self.chdir()
 | 
						|
 | 
						|
        # Load up the any app specific configuration
 | 
						|
        if cfg:
 | 
						|
            for k, v in cfg.items():
 | 
						|
                self.cfg.set(k.lower(), v)
 | 
						|
 | 
						|
        env_args = parser.parse_args(self.cfg.get_cmd_args_from_env())
 | 
						|
 | 
						|
        if args.config:
 | 
						|
            self.load_config_from_file(args.config)
 | 
						|
        elif env_args.config:
 | 
						|
            self.load_config_from_file(env_args.config)
 | 
						|
        else:
 | 
						|
            default_config = get_default_config_file()
 | 
						|
            if default_config is not None:
 | 
						|
                self.load_config_from_file(default_config)
 | 
						|
 | 
						|
        # Load up environment configuration
 | 
						|
        for k, v in vars(env_args).items():
 | 
						|
            if v is None:
 | 
						|
                continue
 | 
						|
            if k == "args":
 | 
						|
                continue
 | 
						|
            self.cfg.set(k.lower(), v)
 | 
						|
 | 
						|
        # Lastly, update the configuration with any command line settings.
 | 
						|
        for k, v in vars(args).items():
 | 
						|
            if v is None:
 | 
						|
                continue
 | 
						|
            if k == "args":
 | 
						|
                continue
 | 
						|
            self.cfg.set(k.lower(), v)
 | 
						|
 | 
						|
        # current directory might be changed by the config now
 | 
						|
        # set up import paths and follow symlinks
 | 
						|
        self.chdir()
 | 
						|
 | 
						|
    def run(self):
 | 
						|
        if self.cfg.check_config:
 | 
						|
            try:
 | 
						|
                self.load()
 | 
						|
            except:
 | 
						|
                msg = "\nError while loading the application:\n"
 | 
						|
                print(msg, file=sys.stderr)
 | 
						|
                traceback.print_exc()
 | 
						|
                sys.stderr.flush()
 | 
						|
                sys.exit(1)
 | 
						|
            sys.exit(0)
 | 
						|
 | 
						|
        if self.cfg.spew:
 | 
						|
            debug.spew()
 | 
						|
 | 
						|
        if self.cfg.daemon:
 | 
						|
            util.daemonize(self.cfg.enable_stdio_inheritance)
 | 
						|
 | 
						|
        # set python paths
 | 
						|
        if self.cfg.pythonpath:
 | 
						|
            paths = self.cfg.pythonpath.split(",")
 | 
						|
            for path in paths:
 | 
						|
                pythonpath = os.path.abspath(path)
 | 
						|
                if pythonpath not in sys.path:
 | 
						|
                    sys.path.insert(0, pythonpath)
 | 
						|
 | 
						|
        super(Application, self).run()
 | 
						|
 |