1. Ben Rousch
  2. CherryPy


CherryPy / cherrypy / __init__.py

"""Global module that all modules developing with CherryPy should import."""

__version__ = '3.0.0beta'

import os as _os
_localdir = _os.path.dirname(__file__)

from cherrypy._cperror import HTTPError, HTTPRedirect, InternalRedirect, NotFound
from cherrypy._cperror import TimeoutError

from cherrypy import _cptools
tools = _cptools.default_toolbox
Tool = _cptools.Tool

from cherrypy import _cptree
tree = _cptree.Tree()
from cherrypy._cptree import Application
from cherrypy import _cpwsgi as wsgi
from cherrypy import _cpengine
engine = _cpengine.Engine()
from cherrypy import _cpserver
server = _cpserver.Server()

def quickstart(root, script_name="", config=None):
    """Mount the given app, start the engine and builtin server, then block."""
    tree.mount(root, script_name, config)

    from threading import local as _local
except ImportError:
    from cherrypy._cpthreadinglocal import local as _local

# Create a threadlocal object to hold the request, response, and other
# objects. In this way, we can easily dump those objects when we stop/start
# a new HTTP conversation, yet still refer to them as module-level globals
# in a thread-safe way.
_serving = _local()

class _ThreadLocalProxy(object):
    __slots__ = ['__attrname__', '_default_child', '__dict__']
    def __init__(self, attrname, default):
        self.__attrname__ = attrname
        self._default_child = default
    def _get_child(self):
            return getattr(_serving, self.__attrname__)
        except AttributeError:
            # Bind dummy instances of default objects to help introspection.
            return self._default_child
    def __getattr__(self, name):
        return getattr(self._get_child(), name)
    def __setattr__(self, name, value):
        if name in ("__attrname__", "_default_child"):
            object.__setattr__(self, name, value)
            setattr(self._get_child(), name, value)
    def __delattr__(self, name):
        delattr(self._get_child(), name)
    def _get_dict(self):
        childobject = self._get_child()
        d = childobject.__class__.__dict__.copy()
        return d
    __dict__ = property(_get_dict)
    def __getitem__(self, key):
        return self._get_child()[key]
    def __setitem__(self, key, value):
        self._get_child()[key] = value

# Create request and response object (the same objects will be used
#   throughout the entire life of the webserver, but will redirect
#   to the "_serving" object)
from cherrypy.lib import http as _http
request = _ThreadLocalProxy('request',
                            _cprequest.Request(_http.Host("localhost", 80),
                                               _http.Host("localhost", 1111)))
response = _ThreadLocalProxy('response', _cprequest.Response())

# Create thread_data object as a thread-specific all-purpose storage
thread_data = _local()

from cherrypy import _cplogging

class _GlobalLogManager(_cplogging.LogManager):
    def __init__(self, appid=None):
        _cplogging.LogManager.__init__(self, appid)
        # Set a default screen handler on the global log.
        self.screen = True
    def __call__(self, *args, **kwargs):
            log = request.app.log
        except AttributeError:
            log = self
        return log.error(*args, **kwargs)
    def access(self):
            return request.app.log.access()
        except AttributeError:
            return _cplogging.LogManager.access(self)

log = _GlobalLogManager()
log.error_file = _os.path.join(_os.getcwd(), _localdir, "error.log")
# Using an access file makes CP about 10% slower. Leave off by default.
log.access_file = ''

#                       Helper functions for CP apps                       #

def expose(func=None, alias=None):
    """Expose the function, optionally providing an alias or set of aliases."""
    def expose_(func):
        func.exposed = True
        if alias is not None:
            if isinstance(alias, basestring):
                parents[alias.replace(".", "_")] = func
                for a in alias:
                    parents[a.replace(".", "_")] = func
        return func
    import sys, types
    parents = sys._getframe(1).f_locals
    if isinstance(func, (types.FunctionType, types.MethodType)):
        # expose is being called directly, before the method has been bound
        return expose_(func)
        if alias is None:
            # expose is being called as a decorator "@expose"
            func.exposed = True
            return func
            # expose is returning a decorator "@expose(alias=...)"
            return expose_

# Set up config last so it can wrap other top-level objects
from cherrypy import _cpconfig
config = _cpconfig.Config()