1

我有一个用 zc.buildout 管理的 Pyramid Web 应用程序。在其中,我需要读取磁盘上的一个文件,该文件位于 buildout 目录的子目录中。

问题在于确定文件的路径 - 我不想硬编码绝对路径,并且在生产中提供应用程序时仅提供相对路径不起作用(可能是因为工作目录不同)。

所以我正在考虑的有前途的“钩子”是:

  • “根”构建目录,我可以在 buildout.cfg 中将其寻址为${buildout:directory}- 但是,我无法弄清楚如何“导出”它以便 Python 代码可以访问它

  • 启动应用程序的 Paster 的 .ini 文件的位置

4

3 回答 3

5

就像@MartijnPieters 在对您自己的答案的评论中建议的那样,我会使用collective.recipe.template.ini. 我想知道我如何才能在我的项目中访问这些数据,所以我解决了:-)

让我们倒退到你需要的东西。首先在您想要构建目录的视图代码中:

def your_view(request):
    buildout_dir = request.registry.settings['buildout_dir']
    ....

request.registry.settings参见文档)是一个“类似字典的部署设置对象”。请参阅部署设置,这就是**settings传递给您的主要方法的内容,例如def main(global_config, **settings)

这些设置是[app:main]deployment.iniproduction.ini文件的一部分。所以在那里添加 buildout 目录:

[app:main]
use = egg:your_app

buildout_dir = /home/you/wherever/it/is

pyramid.reload_templates = true
pyramid.debug_authorization = false
...

但是,这是最后一步,您不希望在其中包含硬编码路径。因此,使用模板生成 .ini。该模板development.ini.in使用${partname:variable}扩展语言。在您的情况下,您需要${buildout:directory}

[app:main]
use = egg:your_app

buildout_dir = ${buildout:dir}
#              ^^^^^^^^^^^^^^^

pyramid.reload_templates = true
pyramid.debug_authorization = false
...

添加一个构建部分以从以下buildout.cfg生成:development.inidevelopment.ini.in

[buildout]
...
parts =
    ...
    inifile
    ...

[inifile]
recipe = collective.recipe.template
input = ${buildout:directory}/development.ini.in
output = ${buildout:directory}/development.ini

请注意,您可以使用collective.recipe.template 做各种很酷的事情。例如,在 your和 your${serverconfig:portnumber}中生成匹配的端口号。玩得开心!production.iniyour_site_name.nginx.conf

于 2013-01-07T08:31:15.473 回答
2

如果相对于构建根目录或 paste.ini 位置的文件路径始终相同,这似乎来自您的问题,您可以在 paste.ini 中设置它:

[app:main]
...
config_file = %(here)s/path/to/file.txt

然后从注册表中访问它,如 Reinout 的回答:

def your_view(request):
    config_file = request.registry.settings['config_file']
于 2013-01-07T15:34:55.580 回答
0

这是我设计的一个相当笨拙的解决方案:

buildout.cfg我使用extra-paths选项zc.recipe.egg将构建目录添加到sys.path

....
[webserver]
recipe = zc.recipe.egg:scripts
eggs = ${buildout:eggs}
extra-paths = ${buildout:directory}

然后我将一个名为的文件app_config.py放入 buildout 目录:

# This remembers the root of the installation (similar to {buildout:directory}
# so we can import it and use where we need access to the filesystem.
# Note: we could use os.getcwd() for that but it feels kinda wonky
# This is not directly related to Celery, we may want to move it somewhere
import os.path
INSTALLATION_ROOT = os.path.dirname(__file__)

现在我们可以在 Python 代码中导入它:

from app_config import INSTALLATION_ROOT
filename = os.path.join(INSTALLATION_ROOT, "somefile.ext")
do_stuff_with_file(filename)

如果有人知道更好的解决方案,欢迎您:)

于 2013-01-05T00:43:25.443 回答