配置¶
Cherrypy中的配置是通过字典实现的。键是命名映射值的字符串;值可以是任何类型。
在Cherrypy3中,可以使用配置(文件或dict)直接在引擎、服务器、请求、响应和日志对象上设置属性。因此,了解配置文件中可用内容的完整范围的最佳方法是简单地导入这些对象并查看 help(obj)
告诉你。
注解
如果你是新来的奇瑞,请先看简单的 basic config 第一节。
建筑¶
关于Cherrypy3的配置,你首先需要知道的是它是分开的 全球的 配置自 应用 配置。如果部署多个 应用 同时 site (随着python web应用程序趋向于去中心化,越来越多的人这样做了),您还需要小心地分离配置。只有一个“全局配置”,但每个部署的应用都有一个单独的“应用配置”。
CherryPy 请求 属于 应用 ,运行在 全球的 上下文和配置数据可以应用于这三个作用域中的任何一个。让我们依次查看每个范围。
全局配置¶
全局配置条目适用于所有地方,并存储在 cherrypy.config
.这个平面dict只保存全局配置数据,即影响所有已装入应用程序的“站点范围”配置条目。
全局配置存储在 cherrypy.config
dict,因此您可以通过调用 cherrypy.config.update(conf)
. 这个 conf
参数可以是文件名、打开的文件或配置项的dict。下面是传递dict参数的示例:
cherrypy.config.update({'server.socket_host': '64.72.221.48',
'server.socket_port': 80,
})
这个 server.socket_host
这个例子中的选项决定了Cherrypy将监听哪个网络接口。这个 server.socket_port
选项声明要侦听的TCP端口。
应用程序配置¶
应用程序条目应用于单个已装入的应用程序,并作为 app.config
.这是一个两级dict,其中每个顶级键都是路径或“相对URL”(例如, "/"
或 "/my/page"
,每个值都是配置项的dict。URL与应用程序的脚本名(装入点)相关。通常,所有这些数据都是在调用 tree.mount(root(), script_name='/path/to', config=conf)
,尽管您也可以使用 app.merge(conf)
. 这个 conf
参数可以是文件名、打开的文件或配置项的dict。
配置文件示例:
[/]
tools.trailing_slash.on = False
request.dispatch: cherrypy.dispatch.MethodDispatcher()
或者,在python代码中:
config = {'/':
{
'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
'tools.trailing_slash.on': False,
}
}
cherrypy.tree.mount(Root(), config=config)
Cherrypy只使用以 "/"
(除外) [global]
,见下文)。这意味着您可以在cherrypy配置文件中放置自己的配置条目,方法是为它们指定一个不以开头的节名。 "/"
.例如,您可以包括这样的数据库条目:
[global]
server.socket_host: "0.0.0.0"
[Databases]
driver: "postgres"
host: "localhost"
port: 5432
[/path]
response.timeout: 6000
然后,在应用程序代码中,您可以通过 cherrypy.request.app.config['Databases']
.对于在请求过程之外的代码,您必须传递一个对应用程序的引用。
请求配置¶
每个请求对象拥有一个 request.config
dict.在请求过程的早期,这个dict是通过合并全局配置、应用程序配置和在查找页面处理程序时获取的任何配置来填充的(参见下一步)。此dict仅包含适用于给定请求的配置项。
注解
当你做一个 InternalRedirect
,将为新路径重新计算此配置属性。
宣言¶
配置数据可以作为python字典、文件名或打开的文件对象提供。
配置文件¶
当您提供一个文件名或文件时,cherrypy使用了python的内置configparser;通过将每个路径写为一个节头,并将每个条目写为 "key: value"
(或) "key = value"
)配对:
[/path/to/my/page]
response.stream: True
tools.trailing_slash.extra = False
组合配置文件¶
如果您只部署一个应用程序,那么可以创建一个包含全局和应用程序条目的配置文件。只需将全局条目插入名为 [global]
,并将同一文件传递给 config.update
和 tree.mount <cherrypy._cptree.Tree.mount()
.如果你打电话来 cherrypy.quickstart(app root, script name, config)
,它将为您将配置传递到两个位置。但一旦决定向同一站点添加另一个应用程序,就需要将两个配置文件/dict分开。
单独的配置文件¶
如果在同一进程中部署多个应用程序,则需要(1)个文件用于全局配置,以及(1)个文件用于 each 应用程序。全局配置通过调用 cherrypy.config.update
和应用程序配置通常在调用中传递给 cherrypy.tree.mount
.
一般来说,您应该首先设置全局配置,然后用自己的配置装载每个应用程序。除其他好处外,这允许您设置全局日志记录,以便在尝试装载应用程序时出错时,可以看到跟踪。换言之,使用以下顺序:
# 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()
配置文件中的值使用python语法¶
配置项始终是键/值对,例如 server.socket_port = 8080
.键始终是名称,值始终是Python对象。也就是说,如果您设置的值是 int
(或其他数字),它需要看起来像一条 Python int
例如, 8080
.如果该值是一个字符串,则需要引用它,就像python字符串一样。也可以创建任意对象,就像在Python代码中一样(假定可以找到/导入这些对象)。下面是一个扩展示例,向您展示了一些不同的类型:
[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:将config附加到处理程序¶
配置文件有一个严重的限制:值总是由URL键控。例如:
[/path/to/page]
methods_with_bodies = ("POST", "PUT", "PROPPATCH")
很明显,额外的方法是该路径的规范;事实上,如果没有它,代码可能会被认为是被破坏的。在Cherrypy中,可以将该配置位直接附加到页面处理程序上:
@cherrypy.expose
def page(self):
return "Hello, world!"
page._cp_config = {"request.methods_with_bodies": ("POST", "PUT", "PROPPATCH")}
_cp_config
是调度程序在对象树中的每个节点上查找的保留属性。这个 _cp_config
属性必须是Cherrypy配置字典。如果调度员发现 _cp_config
属性,它将字典合并到配置的其余部分。整个合并的配置字典都放在 cherrypy.request.config
.
这可以在对象树的任意点上完成;例如,我们可以将该配置附加到包含page方法的类上:
class SetOPages:
_cp_config = {"request.methods_with_bodies": ("POST", "PUT", "PROPPATCH")}
@cherrypy.expose
def page(self):
return "Hullo, Werld!"
注解
只有默认的调度器才能保证这种行为。其他调度员可能对可以附加的位置有不同的限制 _cp_config
属性。另外,因为调度员负责处理 _cp_config
,无法更改调度员(即 request.dispatch
在这个构造中不受尊重)。
此技术允许您:
把config放在它用来提高可读性和可维护性的地方。
将config附加到对象而不是url。这允许多个url指向同一个对象,但您只需要定义一次config。
提供在配置文件中仍然可重写的默认值。
命名空间¶
因为配置条目通常只设置对象的属性,所以它们几乎都是表单的组成部分: object.attribute
.一些是这样的形式: object.subobject.attribute
.它们看起来像普通的python属性链,因为它们的工作方式与它们类似。我们把这条链子的名字叫做 “配置命名空间” .当您提供一个配置条目时,它将尽可能早地绑定到命名空间引用的实际对象;例如,条目 response.stream
实际上设置 stream
属性 cherrypy.response
你看!通过这种方式,您可以通过启动Python解释器并键入以下内容轻松确定默认值:
>>> import cherrypy
>>> cherrypy.response.stream
False
每个配置名称空间都有自己的处理程序;例如,“请求”名称空间有一个处理程序,它接受配置条目并在相应的“请求”属性上设置该值。但是,有一些名称空间并不像场景后面的普通属性那样工作;但是,它们仍然使用点键,并被认为是“有名称空间”。
内置命名空间¶
在全局应用程序根目录中,可以允许来自每个命名空间的条目 ("/"
)或按路径配置,或组合:
范围 |
全球的 |
应用程序根 |
应用程序路径 |
发动机 |
X |
||
钩子 |
X |
X |
X |
日志 |
X |
X |
|
请求 |
X |
X |
X |
响应 |
X |
X |
X |
服务器 |
X |
||
工具 |
X |
X |
X |
发动机¶
此命名空间中的条目控制“应用程序引擎”。这些只能在全局配置中声明。的任何属性 cherrypy.engine
可以在config中设置;但是,config中有一些额外的条目可用:
插件属性。很多 Engine Plugins 他们本身就是
cherrypy.engine
.您可以通过简单地命名附加插件来设置它的任何属性。例如,有一个Autoreloader
上课时间:engine.autoreload
;您可以通过config条目设置其“frequency”属性。engine.autoreload.frequency = 60
.此外,您可以通过设置engine.autoreload.on = True
或False
.
engine.SIGHUP/SIGTERM
:这些条目可用于为给定的 channel .大多数情况下,这用于关闭自动通过cherrypy.quickstart()
.
钩子¶
声明其他请求处理函数。用这个附加你自己的 Hook
请求的函数。例如,添加 my_hook_func
到 before_handler
挂钩点:
[/]
hooks.before_handler = myapp.my_hook_func
日志¶
配置日志记录。这些只能在全局配置(用于全局日志记录)中声明,或者 [/]
配置(针对每个应用程序)。参见 LogManager
用于可配置属性列表。通常,“访问文件”、“错误文件”和“屏幕”属性是最常见的配置。
请求¶
为每个请求设置属性。查看 Request
类获取完整列表。
响应¶
设置每个响应的属性。查看 Response
类获取完整列表。
服务器¶
通过控制默认HTTP服务器 cherrypy.server
(有关可配置属性的完整列表,请参见该类)。这些只能在全局配置中声明。
工具¶
启用和配置其他请求处理包。查看 /tutorial/tools 概述了解更多信息。
WSGi¶
将wsgi中间件添加到应用程序的“管道”。这些只能在应用程序的根配置(“/”)中声明。
wsgi.pipeline
:附加到wsgi管道。该值必须是(名称、应用程序工厂)对的列表。每个应用程序工厂必须是一个wsgi可调用类(或返回wsgi可调用的可调用类);它必须接受一个初始的“nextap”参数,以及任何可选的关键字参数。可选参数可通过以下方式配置:wsgi.<name>.<arg>
.
wsgi.response_class
:覆盖默认值Response
班级。
棋盘格¶
控制“检查器”,它在引擎启动时查找应用程序状态(包括配置)中的常见错误。您可以通过将单个支票设置为 False
在配置中。参见 cherrypy._cpchecker.Checker
以获取完整的列表。仅全局配置。
自定义配置命名空间¶
如果愿意的话,您可以定义自己的名称空间,它们可以做的远不止设置属性。这个 test/test_config
例如,模块显示了强制传入参数和传出正文内容的自定义命名空间的示例。这个 cherrypy._cpwsgi
模块包括一个额外的内置命名空间,用于调用WSGi中间件。
本质上,配置名称空间处理程序只是一个函数,它在其名称空间中传递任何配置项。将其添加到名称空间注册表(dict),其中键是名称空间名称,值是处理程序函数。当遇到命名空间的配置项时,将调用相应的处理程序函数,并传递配置键和值;也就是说, namespaces[namespace](k, v)
.例如,如果你写:
def db_namespace(k, v):
if k == 'connstring':
orm.connect(v)
cherrypy.config.namespaces['db'] = db_namespace
然后 cherrypy.config.update({{"db.connstring": "Oracle:host=1.10.100.200;sid=TEST"}})
将呼叫 db_namespace('connstring', 'Oracle:host=1.10.100.200;sid=TEST')
.
调用命名空间处理程序的位置取决于添加它的位置:
范围 |
命名空间dict |
调用了处理程序 |
全球的 |
|
cherrypy.config.update |
应用 |
application.merge(由cherrypy.tree.mount调用) |
|
请求 |
request.configure(在查找处理程序后为每个请求调用) |
名称可以是任何字符串,处理程序必须是可调用的或(python 2.5样式)上下文管理器。
如果需要在收集所有命名空间键时运行其他代码,可以为处理程序提供一个可调用的上下文管理器,而不是普通函数。上下文管理器在中定义 PEP 343 .
环境¶
命名空间中不存在的唯一键是 “环境” 进入。它仅适用于全局配置,并且仅在使用 cherrypy.config.update
.这个特别条目 进口 以下模板中存储的其他配置项 cherrypy._cpconfig.environments[environment]
.
Config.environments = environments = {
'staging': {
'engine.autoreload.on': False,
'checker.on': False,
'tools.log_headers.on': False,
'request.show_tracebacks': False,
'request.show_mismatched_params': False,
},
'production': {
'engine.autoreload.on': False,
'checker.on': False,
'tools.log_headers.on': False,
'request.show_tracebacks': False,
'request.show_mismatched_params': False,
'log.screen': False,
},
'embedded': {
# For use with CherryPy embedded in another deployment stack.
'engine.autoreload.on': False,
'checker.on': False,
'tools.log_headers.on': False,
'request.show_tracebacks': False,
'request.show_mismatched_params': False,
'log.screen': False,
'engine.SIGHUP': None,
'engine.SIGTERM': None,
},
'test_suite': {
'engine.autoreload.on': False,
'checker.on': False,
'tools.log_headers.on': False,
'request.show_tracebacks': True,
'request.show_mismatched_params': True,
'log.screen': False,
},
}
如果您发现现有环境集(生产、分段等)太过局限或完全错误,请随意扩展它们或添加新环境:
cherrypy._cpconfig.environments['staging']['log.screen'] = False
cherrypy._cpconfig.environments['Greek'] = {
'tools.encode.encoding': 'ISO-8859-7',
'tools.decode.encoding': 'ISO-8859-7',
}