跳转到主要内容

Zope应用设置助手

项目描述

zope.app.appsetup README

本软件包为Zope3应用服务器提供应用程序设置助手。

引导助手

引导助手提供了一些帮助引导的函数。

bootStrapSubscriber函数确保存在根对象。它订阅DatabaseOpened事件

>>> from zope.app.appsetup import bootstrap
>>> import zope.processlifetime
>>> from ZODB.MappingStorage import DB
>>> db = DB()
>>> bootstrap.bootStrapSubscriber(zope.processlifetime.DatabaseOpened(db))

订阅者确保存在根文件夹

>>> from zope.app.publication.zopepublication import ZopePublication
>>> conn = db.open()
>>> root = conn.root()[ZopePublication.root_name]
>>> sm = root.getSiteManager()
>>> conn.close()

使用数据库生成DatabaseOpenedWithRoot

>>> from zope.component.eventtesting import getEvents
>>> [event] = getEvents(zope.processlifetime.IDatabaseOpenedWithRoot)
>>> event.database is db
True

通常,启动代码期望根对象和站点已被创建,将想要订阅此事件,而不是IDataBaseOpenedEvent。

无论是否需要设置根对象,订阅者都会生成事件

>>> bootstrap.bootStrapSubscriber(zope.processlifetime.DatabaseOpened(db))
>>> [e, event] = getEvents(zope.processlifetime.IDatabaseOpenedWithRoot)
>>> event.database is db
True

检查安全策略

当安全策略重构为可插入时,安全策略配置的包含被移至顶级,即site.zcml中。这发生在r24770,在ZopeX3 3.0发布后,但在3.1之前。

现在,现有3.0站点的维护者需要在升级到3.1时手动更新他们的site.zcml以包含securitypolicy.zcml。参见http://www.zope.org/Collectors/Zope3-dev/381

>>> from zope.testing.loggingsupport import InstalledHandler
>>> handler = InstalledHandler('zope.app.appsetup')

如果安全策略从默认的ParanoidSecurityPolicy未设置,我们会收到警告

>>> from zope.app.appsetup.bootstrap import checkSecurityPolicy
>>> event = object()
>>> checkSecurityPolicy(event)
>>> print(handler)
zope.app.appsetup WARNING
  Security policy is not configured.
Please make sure that securitypolicy.zcml is included in site.zcml immediately
before principals.zcml

然而,如果安装了任何非默认的安全策略,则不会发出警告

>>> from zope.security.management import setSecurityPolicy
>>> defaultPolicy = setSecurityPolicy(object())
>>> handler.clear()
>>> checkSecurityPolicy(event)
>>> print(handler)
<BLANKLINE>

清理

>>> handler.uninstall()

调试控制台

调试控制台允许您拥有一个加载了完整Zope环境的Python提示符(这包括ZCML配置,以及一个开放的数据库连接)。

让我们定义一个助手来运行调试脚本并捕获SystemExit异常,否则这些异常会隐藏输出

>>> from __future__ import print_function
>>> import sys
>>> from zope.app.appsetup import debug
>>> def run(*args):
...     sys.argv[0] = 'debug'
...     sys.stderr = sys.stdout
...     try:
...         debug.main(args)
...     except SystemExit as e:
...         print("(exited with status %d)" % e.code)

如果您不带参数调用脚本,它将在stderr上显示一条简短的错误消息

>>> run()
Error: please specify a configuration file
For help, use debug -h
(exited with status 2)

我们需要传递一个ZConfig配置文件作为参数

>>> run('-C', 'test.conf.txt')
The application root is known as `root`.

现在,您可以从打开的数据库中获得根对象,作为__main__模块中名为'root'的全局变量

>>> main_module = sys.modules['__main__']
>>> main_module.root            # doctest: +ELLIPSIS
<zope.site.folder.Folder object at ...>

并且我们已经通过设置PYTHONINSPECT环境变量让Python进入交互模式

>>> import os
>>> os.environ.get('PYTHONINSPECT')
'true'

我们必须做一些额外的工作来尊重PYTHONSTARTUP环境变量

>>> pythonstartup = os.path.join(os.path.dirname(debug.__file__),
...                              'testdata', 'pythonstartup.py')
>>> os.environ['PYTHONSTARTUP'] = pythonstartup
>>> run('-C', 'test.conf.txt')
The application root is known as `root`.

您可以看到,我们的pythonstartup文件已执行,因为它改变了提示符

>>> sys.ps1
'debug> '

特定产品的配置

本包的product模块提供了一种非常简单的方式来处理传统上被称为“产品配置”的东西,其中“产品”指的是经典的Zope 2概念的产品。

应用程序服务器的配置架构允许添加命名的<product-config>部分到配置文件中,并且产品代码可以使用该模块提供的API检索给定名称的配置部分。

该模块中有两个公共函数应在正常操作中使用,以及一些用于测试的额外函数和类。

>>> from __future__ import print_function
>>> from zope.app.appsetup import product

让我们首先看看辅助类,因为我们将在描述公共(应用程序)接口时使用它。然后我们将使用正常操作的函数,然后是剩余的测试支持函数。

模拟配置对象

FauxConfiguration类构建了类似于ZConfig部分对象的物体,以适应产品配置API所需的最小程度。这些将被在这里使用,也可能用于为消耗此类配置的测试组件创建配置。

构造函数需要两个参数:部分的名称,以及部分应提供的键到值的映射。让我们创建一个简单的例子

>>> one = product.FauxConfiguration("one", {})
>>> one.getSectionName()
'one'
>>> one.mapping
{}

提供一组非空的键/值对会按预期简单地表现

>>> two = product.FauxConfiguration("two", {"abc": "def"})
>>> two.getSectionName()
'two'
>>> two.mapping
{'abc': 'def'}

应用程序API

该模块的应用程序接口中有两个函数。一个由配置提供者使用,另一个由消费者使用。

提供者的API接受符合默认ZConfig部分对象表现行为的配置对象序列。由于FauxConfiguration类提供了这些行为,我们可以很容易地看到如何使用它

>>> product.setProductConfigurations([one, two])

现在我们已经建立了一些配置,我们想要能够使用它。我们通过使用getProductConfiguration()函数来完成。如果存在,该函数将返回匹配的配置部分,否则返回None

>>> product.getProductConfiguration("one")
{}
>>> product.getProductConfiguration("not-there") is None
True

请注意,对于存在的部分,只提供内部映射,而不是包含部分对象。这是一个历史遗留问题;我们只需忍受它,直到引入新的API。

第二次设置配置将覆盖以前的配置;以前可用的部分将不再存在

>>> product.setProductConfigurations([two])
>>> product.getProductConfiguration("one") is None
True

新的部分按预期可用

>>> product.getProductConfiguration("two")
{'abc': 'def'}

测试支持函数

提供了额外的函数,使测试中的配置状态管理更容易。

第一个函数可以用来为单个名称提供配置。该函数接受一个名称和一个配置映射或None作为参数。如果第二个参数提供为None,则移除名称的任何配置设置(如果存在)。如果第二个参数不是None,则它将被用作给定名称的getProductConfiguration的返回值。

>>> product.setProductConfiguration("first", None)
>>> print(product.getProductConfiguration("first"))
None
>>> product.setProductConfiguration("first", {"key": "value1"})
>>> product.getProductConfiguration("first")
{'key': 'value1'}
>>> product.setProductConfiguration("first", {"key": "value2"})
>>> product.getProductConfiguration("first")
{'key': 'value2'}
>>> product.setProductConfiguration("first", {"alt": "another"})
>>> product.getProductConfiguration("first")
{'alt': 'another'}
>>> product.setProductConfiguration("second", {"you": "there"})
>>> product.getProductConfiguration("first")
{'alt': 'another'}
>>> product.getProductConfiguration("second")
{'you': 'there'}
>>> product.setProductConfiguration("first", None)
>>> print(product.getProductConfiguration("first"))
None

其他两个函数协同工作,保存和恢复整个配置状态。

我们当前的配置包括“second”键的数据,以及“first”键的没有数据。

>>> print(product.getProductConfiguration("first"))
None
>>> print(product.getProductConfiguration("second"))
{'you': 'there'}

让我们保存这个状态。

>>> state = product.saveConfiguration()

现在让我们替换厨房水槽。

>>> product.setProductConfigurations([
...     product.FauxConfiguration("x", {"a": "b"}),
...     product.FauxConfiguration("y", {"c": "d"}),
...     ])
>>> print(product.getProductConfiguration("first"))
None
>>> print(product.getProductConfiguration("second"))
None
>>> product.getProductConfiguration("x")
{'a': 'b'}
>>> product.getProductConfiguration("y")
{'c': 'd'}

保存的配置状态可以被恢复。

>>> product.restoreConfiguration(state)
>>> print(product.getProductConfiguration("x"))
None
>>> print(product.getProductConfiguration("y"))
None
>>> print(product.getProductConfiguration("first"))
None
>>> print(product.getProductConfiguration("second"))
{'you': 'there'}

还有一个函数可以用来从文件对象中加载数据产品配置;只接受产品配置组件。该函数返回一个名称到配置对象的映射,适用于传递给setProductConfiguration。使用此功能与setProductConfigurations需要构造FauxConfiguration对象。

让我们创建一些示例配置文本。

>>> product_config = '''
... <product-config product1>
...   key1 product1-value1
...   key2 product1-value2
... </product-config>
...
... <product-config product2>
...   key1 product2-value1
...   key3 product2-value2
... </product-config>
... '''

现在我们可以使用loadConfiguration函数来加载配置。

>>> import io
>>> import pprint
>>> sio = io.StringIO(product_config)
>>> config = product.loadConfiguration(sio)
>>> pprint.pprint(config, width=1)
{'product1': {'key1': 'product1-value1',
               'key2': 'product1-value2'},
 'product2': {'key1': 'product2-value1',
               'key3': 'product2-value2'}}

还可以使用提供产品配置的扩展。

>>> product_config = '''
... %import zope.app.appsetup.testproduct
...
... <testproduct foobar>
... </testproduct>
...
... <testproduct barfoo>
...   key1 value1
...   key2 value2
... </testproduct>
... '''
>>> sio = io.StringIO(product_config)
>>> config = product.loadConfiguration(sio)
>>> pprint.pprint(config, width=1)
{'barfoo': {'key1': 'value1',
             'key2': 'value2',
             'product-name': 'barfoo'},
 'foobar': {'product-name': 'foobar'}}

变更日志

5.0 (2023-02-09)

  • 支持Python 3.9、3.10、3.11。

  • 停止支持Python 2.7、3.5、3.6。

4.2.0 (2020-05-20)

  • 停止支持python setup.py test

  • 支持Python 3.8。

  • 停止支持Python 3.4。

4.1.0 (2018-12-15)

  • 支持Python 3.6、3.7和PyPy3。

  • 停止支持Python 3.3。

4.0.0 (2016-08-08)

  • 添加对zdaemon(从ZODB分离出来)的依赖。

  • 声称支持Python 3.4、3.5和PyPy,这需要zope.app.publication >= 4.0。

  • 停止支持Python 2.6。

4.0.0a1 (2013-03-03)

  • 添加对Python 3.3的支持。

  • 将已弃用的zope.interface.implements使用替换为等效的zope.interface.implementer装饰器。

  • 停止支持Python 2.4和2.5。

3.16.0 (2011-01-27)

  • 添加对派生ZODBLayers中层/测试级别设置分离的存储堆叠支持。

3.15.0 (2010-09-25)

  • 更新测试以使用zope.testing >= 3.10运行,需要至少这个版本和zope.testrunner

  • IErrorReportingUtility copy_to_zlog字段切换到True

  • 使用Python的doctest模块代替已弃用的zope.testing.doctest

3.14.0 (2010-04-13)

  • zope.testing作为一个可选(测试)依赖项。

  • 删除对zope.app.testing的测试依赖项。

3.13.0 (2009-12-24)

  • 在从zope.site迁移到那里后,从zope.component导入导入钩子功能。

  • 在从zope.location迁移到那里后,从zope.component导入ISite。这消除了对zope.location的依赖。

  • 添加了对zope.testing的缺失安装依赖项。

3.12.0 (2009-06-20)

  • 直接使用zope.processlifetime接口和实现,而不是从zope.app.appsetup的BBB导入。

  • 消除了对zope.app.component的依赖。

  • 消除了对zope.app.security的测试依赖。

3.11 (2009-05-13)

  • 将事件接口/实现移动到zope.processlifetime,版本1.0。依赖此包,并添加BBB导入。

3.10.1 (2009-03-31)

  • 修复了3.10.0中引入的DeprecationWarning

  • 将doctests添加到长描述中,以便在pypi中显示。

3.10.0 (2009-03-19)

  • 最后,弃用zope.app.appsetup.bootstrap模块中辅助函数的“asObject”参数。如果您的代码使用这些函数中的任何一个,请删除在“asObject=True”参数传递中的任何位置,因为对该参数的支持将很快被删除。

  • 将session实用程序的引导逻辑从zope.session移入此包。这消除了对zope.session到此包的依赖。

  • 删除另一个已弃用的函数。

3.9.0 (2009-01-31)

  • 请使用 zope.site 代替 zope.app.folderzope.app.component

  • 请使用 zope.container 代替 zope.app.container

  • 将错误日志引导逻辑从 zope.error 移入本包。这消除了对 zope.error 的依赖。还添加了在此处引导错误日志的测试,这在 zope.error 中是缺失的。

3.8.0 (2008-08-25)

  • 特性:开发了一个入口点,允许您快速启动应用程序实例进行调试。 (由 Marius Gedminas 和 Stephan Richter 实现。)

3.7.0 (2008-08-19)

  • 添加了 .product.loadConfiguration 测试支持函数;从文件对象中加载产品配置(仅限配置),允许测试代码(包括设置)使用与正常启动相同的配置架构支持。

3.6.0 (2008-07-23)

  • 添加了额外的测试支持函数来设置单个部分的配置,以及保存/恢复整个配置。

3.5.0 (2008-06-17)

  • 添加了支持产品配置测试的辅助类。

  • 添加了产品配置 API 的文档,包括测试。

3.4.1 (2007-09-27)

  • 蛋包存在缺陷,已重新发布。

3.4.0 (2007-09-25)

  • 初始文档发布。

  • 反映 zope.app.error 重构的变化。

下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源代码分发

zope.app.appsetup-5.0.tar.gz (32.2 kB 查看哈希值)

上传时间 源代码

构建分发

zope.app.appsetup-5.0-py3-none-any.whl (35.6 kB 查看哈希值)

上传时间 Python 3

由以下支持