在Pyramid中的非请求上下文中检索应用程序配置设置

时间:2013-10-13 18:48:10

标签: python pyramid

在我正在构建的金字塔应用程序(称为pyplay)中,我需要检索我在development.ini中的应用程序设置。问题是我尝试获取该设置的位置无法访问请求变量(例如,在模块文件的顶层)。

因此,在文档中查看此示例之后:http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/configuration/django_settings.html我开始做一些非常简单和硬编码的事情,只是为了让它工作。 由于我的development.ini有这一部分:[app:main],我尝试的简单示例如下:

from paste.deploy.loadwsgi import appconfig
config = appconfig('config:development.ini', 'main', relative_to='.')

但是应用程序拒绝启动并显示以下错误:

ImportError: <module 'pyplay' from '/home/pish/projects/pyplay/__init__.pyc'> has no 'main' attribute

所以,想到也许我应该把'pyplay'而不是'main',我继续,但我得到了这个错误:

LookupError: No section 'pyplay' (prefixed by 'app' or 'application' or 'composite' or 'composit' or 'pipeline' or 'filter-app') found in config ./development.ini

此时我有点陷入困境,我不知道自己做错了什么。有人可以帮我解释一下如何做到这一点吗?

提前致谢!

编辑:以下是我的development.ini文件的内容(请注意,pish.theparam是我想要的设置):

###
# app configuration
# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###

[app:main]
use = egg:pyplay

pyramid.reload_templates = true
pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.default_locale_name = en_US.utf8
pyramid.includes =
    pyramid_debugtoolbar
    pyramid_tm

sqlalchemy.url = mysql://user:passwd@localhost/pyplay?charset=utf8

# By default, the toolbar only appears for clients from IP addresses
# '127.0.0.1' and '::1'.
debugtoolbar.hosts = 127.0.0.1 ::1

pish.theparam = somevalue

###
# wsgi server configuration
###

[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = 6543

###
# logging configuration
# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###

[loggers]
keys = root, pyplay, sqlalchemy

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = INFO
handlers = console

[logger_pyplay]
level = DEBUG
handlers =
qualname = pyplay

[logger_sqlalchemy]
level = INFO
handlers =
qualname = sqlalchemy.engine
# "level = INFO" logs SQL queries.
# "level = DEBUG" logs SQL queries and results.
# "level = WARN" logs neither.  (Recommended for production systems.)

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s

3 个答案:

答案 0 :(得分:3)

在金字塔中难以做到的原因是因为总是一个错误的想法来进行模块级设置。这意味着您的模块只能以每个进程的一种方式使用(不同的代码路径不能以不同的方式使用您的库)。 : - )

无法访问请求对象的黑客是至少隐藏函数调用后的全局,以便全局可以是不同的每个线程(基本上是每个请求)。

def get_my_param(registry=None):
    if registry is None:
        registry = pyramid.threadlocals.get_current_registry()
    return registry.settings['pyplay.theparam']

答案 1 :(得分:1)

步骤1:在文件xyz_file中创建一个单例类

class Singleton:
def __init__(self, klass):
    self.klass = klass
    self.instance = None
def __call__(self, *args, **kwds):
    if self.instance == None:
        self.instance = self.klass(*args, **kwds)
    return self.instance

@Singleton
class ApplicationSettings(object):
   def __init__(self, app_settings=None):
       if app_settings is not None :
           self._settings = app_settings
   def get_appsettings_object(self):
       return self

   def get_application_configuration(self):
       return self._settings

第2步:在&#34; __ init __。py&#34;

def main(global_config, **settings):
  ....
  .......
  app_settings = ApplicationSettings(settings)

第3步:您应该能够访问代码的任何部分。

  from xyz_file import ApplicationSettings
  app_settings = ApplicationSettings().get_application_configuration()

答案 2 :(得分:0)

基本上,如果您无权访问请求对象,那么您在金字塔中“脱轨”。为了使用Pyramid方式,我们制作组件并找出它们在Pyramid生命周期中的位置,并且它们应该始终可以直接访问注册表(ZCA)和请求中的任何一个或两个。

如果你正在做的事情不符合请求生命周期,那么它可能应该在服务器启动时实例化,通常在你构建的 init .py中。填写配置程序(我们访问注册表)。不要害怕使用注册表来允许其他组件稍后“伪全局”地获取事物。所以你可能想为你的东西做一些工厂,在你的启动代码中调用工厂,也许传递对注册表的引用作为参数,然后将对象附加到注册表。如果您的组件需要与请求生命周期代码进行交互,请为其提供一个将请求作为参数的方法。以后,此对象需要的任何内容都可以从注册表中获取,此对象需要获取的任何内容都可以通过注册表或请求来完成。

你可以在另一个答案中完全使用hack来获取当前的全局注册表,但需要这样做是代码味道,你可以找出更好的设计来消除它。

伪代码示例,在服务器启动代码中:

# in in the init block where our Configurator has been built
from myfactory import MyFactory
registry.my_component = MyFactory(config.registry)
# you can now get at my_component from anywhere in a pyramid system

你的组件:

class MyFactory(oject):
    def __init__(self, registry):
        # server start up lifecycle stuff here    
        self.registry = registry

    def get_something(self, request):
        # do stuff with the rest of the system
        setting_wanted = self.registry.settings['my_setting']

Pyramid Views以这种方式工作。它们实际上是请求和上下文的ZCA多适配器。他们的 factory 在注册表中注册,然后当视图查找过程开始时,工厂将请求作为参数传递给实例。