summaryrefslogtreecommitdiff
path: root/docs/config.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/config.rst')
-rw-r--r--docs/config.rst484
1 files changed, 484 insertions, 0 deletions
diff --git a/docs/config.rst b/docs/config.rst
new file mode 100644
index 00000000..a4eb3acc
--- /dev/null
+++ b/docs/config.rst
@@ -0,0 +1,484 @@
+.. _configindepth:
+
+Configure
+---------
+
+Configuration in CherryPy is implemented via dictionaries. Keys are strings
+which name the mapped value; values may be of any type.
+
+In CherryPy 3, you use configuration (files or dicts) to set attributes
+directly on the engine, server, request, response, and log objects. So the
+best way to know the full range of what's available in the config file is to
+simply import those objects and see what ``help(obj)`` tells you.
+
+.. note::
+
+ If you are new to CherryPy, please refer first to the simpler
+ :ref:`basic config <config>` section first.
+
+.. contents::
+ :depth: 3
+
+Architecture
+############
+
+The first thing you need to know about CherryPy 3's configuration is that it
+separates *global* config from *application* config. If you're deploying
+multiple *applications* at the same *site* (and more and more people are,
+as Python web apps are tending to decentralize), you need to be careful to
+separate the configurations, as well. There's only ever one "global config",
+but there is a separate "app config" for each app you deploy.
+
+CherryPy *Requests* are part of an *Application*, which runs in a *global*
+context, and configuration data may apply to any of those three scopes.
+Let's look at each of those scopes in turn.
+
+Global config
+^^^^^^^^^^^^^
+
+Global config entries apply everywhere, and are stored in
+:class:`cherrypy.config <cherrypy._cpconfig.Config>`. This flat dict only holds
+global config data; that is, "site-wide" config entries which affect all
+mounted applications.
+
+Global config is stored in the
+:class:`cherrypy.config <cherrypy._cpconfig.Config>` dict,
+and you therefore update it by calling ``cherrypy.config.update(conf)``.
+The ``conf`` argument can be either a filename, an open file, or a dict of
+config entries. Here's an example of passing a dict argument:
+
+.. code-block:: python
+
+ cherrypy.config.update({'server.socket_host': '64.72.221.48',
+ 'server.socket_port': 80,
+ })
+
+The ``server.socket_host`` option in this example determines on which network
+interface CherryPy will listen. The ``server.socket_port`` option declares
+the TCP port on which to listen.
+
+Application config
+^^^^^^^^^^^^^^^^^^
+
+Application entries apply to a single mounted application, and are stored on
+each Application object itself as
+:attr:`app.config <cherrypy._cptree.Application.config>`. This is a two-level
+dict where each top-level key is a path, or "relative URL" (for example,
+``"/"`` or ``"/my/page"``), and each value is a dict of config entries.
+The URL's are relative to the script name (mount point) of the Application.
+Usually, all this data is provided in the call to
+``tree.mount(root(), script_name='/path/to', config=conf)``,
+although you may also use ``app.merge(conf)``.
+The ``conf`` argument can be either a filename, an open file, or a dict of
+config entries.
+
+Configuration file example:
+
+.. code-block:: ini
+
+ [/]
+ tools.trailing_slash.on = False
+ request.dispatch: cherrypy.dispatch.MethodDispatcher()
+
+or, in python code:
+
+.. code-block:: python
+
+ config = {'/':
+ {
+ 'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
+ 'tools.trailing_slash.on': False,
+ }
+ }
+ cherrypy.tree.mount(Root(), config=config)
+
+CherryPy only uses sections that start with ``"/"`` (except
+``[global]``, see below). That means you can place your own configuration
+entries in a CherryPy config file by giving them a section name which does not
+start with ``"/"``. For example, you might include database entries like this:
+
+.. code-block:: ini
+
+ [global]
+ server.socket_host: "0.0.0.0"
+
+ [Databases]
+ driver: "postgres"
+ host: "localhost"
+ port: 5432
+
+ [/path]
+ response.timeout: 6000
+
+Then, in your application code you can read these values during request time
+via ``cherrypy.request.app.config['Databases']``. For code that is outside the
+request process, you'll have to pass a reference to your Application around.
+
+Request config
+^^^^^^^^^^^^^^
+
+Each Request object possesses a single
+:attr:`request.config <cherrypy._cprequest.Request.config>` dict. Early in the
+request process, this dict is populated by merging Global config, Application
+config, and any config acquired while looking up the page handler (see next).
+This dict contains only those config entries which apply to the given request.
+
+.. note::
+
+ when you do an :class:`InternalRedirect<cherrypy._cperror.InternalRedirect>`,
+ this config attribute is recalculated for the new path.
+
+Declaration
+###########
+
+Configuration data may be supplied as a Python dictionary, as a filename,
+or as an open file object.
+
+Configuration files
+^^^^^^^^^^^^^^^^^^^
+
+When you supply a filename or file, CherryPy uses Python's builtin ConfigParser;
+you declare Application config by writing each path as a section header,
+and each entry as a ``"key: value"`` (or ``"key = value"``) pair:
+
+.. code-block:: ini
+
+ [/path/to/my/page]
+ response.stream: True
+ tools.trailing_slash.extra = False
+
+Combined Configuration Files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you are only deploying a single application, you can make a single config
+file that contains both global and app entries. Just stick the global entries
+into a config section named ``[global]``, and pass the same file to both
+:func:`config.update <cherrypy._cpconfig.Config.update>` and
+:func:`tree.mount <cherrypy._cptree.Tree.mount`. If you're calling
+``cherrypy.quickstart(app root, script name, config)``, it will pass the
+config to both places for you. But as soon as you decide to add another
+application to the same site, you need to separate the two config files/dicts.
+
+Separate Configuration Files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you're deploying more than one application in the same process, you need
+(1) file for global config, plus (1) file for *each* Application.
+The global config is applied by calling
+:func:`cherrypy.config.update <cherrypy._cpconfig.Config.update>`,
+and application config is usually passed in a call to
+:func:`cherrypy.tree.mount <cherrypy._cptree.Tree.mount>`.
+
+In general, you should set global config first, and then mount each
+application with its own config. Among other benefits, this allows you to set
+up global logging so that, if something goes wrong while trying to mount
+an application, you'll see the tracebacks. In other words, use this order:
+
+.. code-block:: python
+
+ # global config
+ cherrypy.config.update({'environment': 'production',
+ 'log.error_file': 'site.log',
+ # ...
+ })
+
+ # Mount each app and pass it its own config
+ cherrypy.tree.mount(root1, "", appconf1)
+ cherrypy.tree.mount(root2, "/forum", appconf2)
+ cherrypy.tree.mount(root3, "/blog", appconf3)
+
+ if hasattr(cherrypy.engine, 'block'):
+ # 3.1 syntax
+ cherrypy.engine.start()
+ cherrypy.engine.block()
+ else:
+ # 3.0 syntax
+ cherrypy.server.quickstart()
+ cherrypy.engine.start()
+
+Values in config files use Python syntax
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Config entries are always a key/value pair, like ``server.socket_port = 8080``.
+The key is always a name, and the value is always a Python object. That is,
+if the value you are setting is an ``int`` (or other number), it needs to look
+like a Python ``int``; for example, ``8080``. If the value is a string, it
+needs to be quoted, just like a Python string. Arbitrary objects can also be
+created, just like in Python code (assuming they can be found/imported).
+Here's an extended example, showing you some of the different types:
+
+.. code-block:: ini
+
+ [global]
+ log.error_file: "/home/fumanchu/myapp.log"
+ environment = 'production'
+ server.max_request_body_size: 1200
+
+ [/myapp]
+ tools.trailing_slash.on = False
+ request.dispatch: cherrypy.dispatch.MethodDispatcher()
+
+.. _cp_config:
+
+_cp_config: attaching config to handlers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Config files have a severe limitation: values are always keyed by URL.
+For example:
+
+.. code-block:: ini
+
+ [/path/to/page]
+ methods_with_bodies = ("POST", "PUT", "PROPPATCH")
+
+It's obvious that the extra method is the norm for that path; in fact,
+the code could be considered broken without it. In CherryPy, you can attach
+that bit of config directly on the page handler:
+
+.. code-block:: python
+
+ def page(self):
+ return "Hello, world!"
+ page.exposed = True
+ page._cp_config = {"request.methods_with_bodies": ("POST", "PUT", "PROPPATCH")}
+
+``_cp_config`` is a reserved attribute which the dispatcher looks for at
+each node in the object tree. The ``_cp_config`` attribute must be a CherryPy
+config dictionary. If the dispatcher finds a ``_cp_config`` attribute,
+it merges that dictionary into the rest of the config. The entire merged
+config dictionary is placed in
+:attr:`cherrypy.request.config <cherrypy._cprequest.Request.config>`.
+
+This can be done at any point in the tree of objects; for example, we could have
+attached that config to a class which contains the page method:
+
+.. code-block:: python
+
+ class SetOPages:
+
+ _cp_config = {"request.methods_with_bodies": ("POST", "PUT", "PROPPATCH")}
+
+ def page(self):
+ return "Hullo, Werld!"
+ page.exposed = True
+
+.. note::
+
+ This behavior is only guaranteed for the default dispatcher. Other
+ dispatchers may have different restrictions on where you can attach
+ ``_cp_config`` attributes.
+
+This technique allows you to:
+
+ * Put config near where it's used for improved readability and maintainability.
+ * Attach config to objects instead of URL's. This allows multiple URL's to
+ point to the same object, yet you only need to define the config once.
+ * Provide defaults which are still overridable in a config file.
+
+.. _namespaces:
+
+Namespaces
+##########
+
+Because config entries usually just set attributes on objects, they're almost
+all of the form: ``object.attribute``. A few are of the form:
+``object.subobject.attribute``. They look like normal Python attribute chains,
+because they work like them. We call the first name in the chain the
+*"config namespace"*. When you provide a config entry, it is bound as early
+as possible to the actual object referenced by the namespace; for example,
+the entry ``response.stream`` actually sets the ``stream`` attribute of
+:class:`cherrypy.response <cherrypy._cprequest.Response>`! In this way,
+you can easily determine the default value by firing up a python interpreter
+and typing:
+
+.. code-block:: python
+
+ >>> import cherrypy
+ >>> cherrypy.response.stream
+ False
+
+Each config namespace has its own handler; for example, the "request" namespace
+has a handler which takes your config entry and sets that value on the
+appropriate "request" attribute. There are a few namespaces, however, which
+don't work like normal attributes behind the scenes; however, they still use
+dotted keys and are considered to "have a namespace".
+
+Builtin namespaces
+^^^^^^^^^^^^^^^^^^
+
+Entries from each namespace may be allowed in the global, application root
+(``"/"``) or per-path config, or a combination:
+
+========== ====== ================== =========
+Scope Global Application Root App Path
+---------- ------ ------------------ ---------
+engine X
+hooks X X X
+log X X
+request X X X
+response X X X
+server X
+tools X X X
+========== ====== ================== =========
+
+engine
+~~~~~~
+
+Entries in this namespace controls the 'application engine'. These can only be
+declared in the global config. Any attribute of
+:class:`cherrypy.engine<cherrypy.process.wspbus.Bus>` may be set
+in config; however, there are a few extra entries available in config:
+
+ * Plugin attributes. Many of the :ref:`Engine Plugins<plugins>` are themselves
+ attributes of ``cherrypy.engine``. You can set any attribute of an attached
+ plugin by simply naming it. For example, there is an instance of the
+ :class:`Autoreloader<cherrypy.process.plugins.Autoreloader>` class at
+ ``engine.autoreload``; you can set its "frequency" attribute via the config
+ entry ``engine.autoreload.frequency = 60``. In addition, you can turn such
+ plugins on and off by setting ``engine.autoreload.on = True`` or ``False``.
+ * ``engine.SIGHUP/SIGTERM``: These entries can be used to set the list of
+ listeners for the given :ref:`channel<channels>`. Mostly, this is used
+ to turn off the signal handling one gets automatically via
+ :func:`cherrypy.quickstart`.
+
+hooks
+~~~~~
+
+Declares additional request-processing functions. Use this to append your own
+:class:`Hook<cherrypy._cprequest.Hook>` functions to the request. For example,
+to add ``my_hook_func`` to the ``before_handler`` hookpoint:
+
+.. code-block:: ini
+
+ [/]
+ hooks.before_handler = myapp.my_hook_func
+
+log
+~~~
+
+Configures logging. These can only be declared in the global config (for global
+logging) or ``[/]`` config (for each application).
+See :class:`LogManager<cherrypy._cplogging.LogManager>` for the list of
+configurable attributes. Typically, the "access_file", "error_file", and
+"screen" attributes are the most commonly configured.
+
+request
+~~~~~~~
+
+Sets attributes on each Request. See the
+:class:`Request<cherrypy._cprequest.Request>` class for a complete list.
+
+response
+~~~~~~~~
+
+Sets attributes on each Response. See the
+:class:`Response<cherrypy._cprequest.Response>` class for a complete list.
+
+server
+~~~~~~
+
+Controls the default HTTP server via
+:class:`cherrypy.server<cherrypy._cpserver.Server>` (see that class for a
+complete list of configurable attributes). These can only be
+declared in the global config.
+
+tools
+~~~~~
+
+Enables and configures additional request-processing packages. See the
+:doc:`/tutorial/tools` overview for more information.
+
+wsgi
+~~~~
+
+Adds WSGI middleware to an Application's "pipeline". These can only be
+declared in the app's root config ("/").
+
+ * ``wsgi.pipeline``: Appends to the WSGi pipeline. The value must be a list of
+ (name, app factory) pairs. Each app factory must be a WSGI callable class
+ (or callable that returns a WSGI callable); it must take an initial
+ 'nextapp' argument, plus any optional keyword arguments. The optional
+ arguments may be configured via ``wsgi.<name>.<arg>``.
+ * ``wsgi.response_class``: Overrides the default
+ :class:`Response<cherrypy._cprequest.Response>` class.
+
+checker
+~~~~~~~
+
+Controls the "checker", which looks for common errors in app state (including
+config) when the engine starts. You can turn off individual checks by setting
+them to ``False`` in config. See :class:`cherrypy._cpchecker.Checker` for a
+complete list. Global config only.
+
+
+Custom config namespaces
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+
+You can define your own namespaces if you like, and they can do far more than
+simply set attributes. The ``test/test_config`` module, for example, shows an
+example of a custom namespace that coerces incoming params and outgoing body
+content. The :mod:`cherrypy._cpwsgi` module includes an additional, builtin
+namespace for invoking WSGI middleware.
+
+In essence, a config namespace handler is just a function, that gets passed
+any config entries in its namespace. You add it to a namespaces registry
+(a dict), where keys are namespace names and values are handler functions.
+When a config entry for your namespace is encountered, the corresponding
+handler function will be called, passing the config key and value; that is,
+``namespaces[namespace](k, v)``. For example, if you write:
+
+.. code-block:: python
+
+ def db_namespace(k, v):
+ if k == 'connstring':
+ orm.connect(v)
+ cherrypy.config.namespaces['db'] = db_namespace
+
+then ``cherrypy.config.update({"db.connstring": "Oracle:host=1.10.100.200;sid=TEST"})``
+will call ``db_namespace('connstring', 'Oracle:host=1.10.100.200;sid=TEST')``.
+
+The point at which your namespace handler is called depends on where you add it:
+
+=========== ============================================================================= ===================================
+Scope Namespace dict Handler is called in
+----------- ----------------------------------------------------------------------------- -----------------------------------
+Global :attr:`cherrypy.config.namespaces <cherrypy._cpconfig.Config.namespaces>` cherrypy.config.update
+Application :attr:`app.namespaces <cherrypy._cptree.Application.namespaces>` Application.merge (which is called by cherrypy.tree.mount)
+Request :attr:`app.request_class.namespaces <cherrypy._cprequest.Request.namespaces>` Request.configure (called for each request, after the handler is looked up)
+=========== ============================================================================= ===================================
+
+The name can be any string, and the handler must be either a callable or a
+(Python 2.5 style) context manager.
+
+If you need additional code to run when all your namespace keys are collected,
+you can supply a callable context manager in place of a normal function for
+the handler. Context managers are defined in :pep:`343`.
+
+.. _environments:
+
+Environments
+^^^^^^^^^^^^
+
+The only key that does not exist in a namespace is the *"environment"* entry.
+It only applies to the global config, and only when you use
+:func:`cherrypy.config.update <cherrypy._cpconfig.Config.update>`. This special
+entry *imports* other config entries from the following template stored in
+``cherrypy._cpconfig.environments[environment]``.
+
+.. literalinclude:: ../../../cherrypy/_cpconfig.py
+ :start-after: Sphinx begin config.environments
+ :end-before: Sphinx end config.environments
+
+If you find the set of existing environments (production, staging, etc) too
+limiting or just plain wrong, feel free to extend them or add new environments:
+
+.. code-block:: python
+
+ cherrypy._cpconfig.environments['staging']['log.screen'] = False
+
+ cherrypy._cpconfig.environments['Greek'] = {
+ 'tools.encode.encoding': 'ISO-8859-7',
+ 'tools.decode.encoding': 'ISO-8859-7',
+ }
+