Я использую для разработки веб-приложений на Django и gunicorn.
В случае Django любые прикладные модули в приложении Django могут получить настройки развертывания через django.conf.settings. "Settings.py" написан на Python, так что любые произвольные настройки и предварительная обработка могут быть определены динамически.
В случае с пушкой, у него есть три места конфигурации в порядке приоритета, и один экземпляр класса реестра объединяет их. (Но обычно эти настройки используются только для несобственного применения gunicorn.)
- Параметры командной строки.
- Конфигурационный файл. (например, Django, написанный Python, который может иметь любые произвольные настройки динамически.)
- Настройки приложения Paster.
В случае с Pyramid, согласно документации Pyramid, параметры развертывания обычно можно поместить в настройки pyramid.registry.Registry(). Но, похоже, он доступен только тогда, когда существуют экземпляры pyramid.router.Router(). Это pyramid.threadlocal.get_current_registry(). Settings возвращает None во время процесса запуска в приложении "main.py" .
Например, я обычно определяю некоторую бизнес-логику в модулях модели SQLAlchemy, для чего требуются настройки развертывания следующим образом.
myapp/models.py
from sqlalchemy import Table, Column, Types
from sqlalchemy.orm import mapper
from pyramid.threadlocal import get_current_registry
from myapp.db import session, metadata
settings = get_current_registry().settings
mytable = Table('mytable', metadata,
Column('id', Types.INTEGER, primary_key=True,)
(other columns)...
)
class MyModel(object):
query = session.query_property()
external_api_endpoint = settings['external_api_uri']
timezone = settings['timezone']
def get_api_result(self):
(interact with external api ...)
mapper(MyModel, mytable)
Но "settings ['external_api_endpoint'] вызывает исключение TypeError, потому что" настройки "-" Нет ".
Я думал о двух решениях.
-
Определите вызываемый, который принимает аргумент "config" в "models.py" и "main.py" , вызывает его с помощью Экземпляр Configurator().
myapp/models.py
from sqlalchemy import Table, Column, Types from sqlalchemy.orm import mapper from myapp.db import session, metadata _g = globals() def initialize(config): settings = config.get_settings() mytable = Table('mytable', metadata, Column('id', Types.INTEGER, rimary_key = True,) (other columns ...) ) class MyModel(object): query = session.query_property() external_api_endpoint = settings['external_api_endpoint'] def get_api_result(self): (interact with external api)... mapper(MyModel, mytable) _g['MyModel'] = MyModel _g['mytable'] = mytable
-
Или, поместите пустой модуль "app/settings.py" и поместите в него настройки позже.
myapp/__init__.py
from pyramid.config import Configurator from .resources import RootResource def main(global_config, **settings): config = Configurator( settings = settings, root_factory = RootResource, ) import myapp.settings myapp.setting.settings = config.get_settings() (other configurations ...) return config.make_wsgi_app()
Оба и другие решения отвечают требованиям, но я чувствую себя хлопотно. Я хочу, чтобы следующие.
-
development.ini
определяет грубые настройки, так как для development.ini могут быть только константы string.
[app:myapp] use = egg:myapp env = dev0 api_signature = xxxxxx
-
MyApp/settings.py
определяет подробные настройки на основе development.ini, поскольку любые произвольные переменные (типы) могут быть установлены.
import datetime, urllib from pytz import timezone from pyramid.threadlocal import get_current_registry pyramid_settings = get_current_registry().settings if pyramid_settings['env'] == 'production': api_endpoint_uri = 'http://api.external.com/?{0}' timezone = timezone('US/Eastern') elif pyramid_settings['env'] == 'dev0': api_endpoint_uri = 'http://sandbox0.external.com/?{0}' timezone = timezone('Australia/Sydney') elif pyramid_settings['env'] == 'dev1': api_endpoint_uri = 'http://sandbox1.external.com/?{0}' timezone = timezone('JP/Tokyo') api_endpoint_uri = api_endpoint_uri.format(urllib.urlencode({'signature':pyramid_settings['api_signature']}))
Затем другие модули могут получить произвольные параметры развертывания через "import myapp.settings". Или, если настройки Registry() предпочтительны, чем "settings.py", ** настройки kwargs и "settings.py" могут быть объединены и зарегистрированы в настройках Registry() во время запуска "main.py" .
Во всяком случае, как получить настройки dictionay во время запуска? Или, Pyramid мягко заставляет нас помещать каждый код, который требует настроек развертывания в "обратных" вызовах, которые могут получить словарь настроек в любое время через request.registry.settings?
ИЗМЕНИТЬ
Спасибо, Майкл и Крис.
Наконец-то я понимаю, почему Pyramid использует переменные threadlocal (реестр и запрос), в частности объект реестра для более чем одного приложения Pyramid.
Однако, на мой взгляд, параметры развертывания обычно влияют на бизнес-логику, которая может определять специфические для приложения проблемы. Эти логики обычно помещаются в один или несколько модулей Python, которые могут быть отличными от "app/ init.py" или "app/views.py", которые могут легко получить доступ к Config() или Registry (). Эти модули Python обычно являются "глобальными" на уровне процесса Python.
То есть, даже если более одного приложения Pyramid сосуществуют, несмотря на собственные переменные потока, они должны делиться этими "глобальными" модулями Python, которые могут содержать специфические для приложения значения на уровне процесса Python.
Из-за причин, каждый из этих модулей может иметь "initialize()" callalbe, который вызывается с помощью Configurator() приложением "main", вызываемым или передающим объект Registory() или Request() через столь длинные серии вызовов функций могут соответствовать обычным требованиям. Но я думаю, что начинающие пирамиды (например, я) или разработчики, у которых есть "большое приложение или так много настроек", могут чувствовать себя хлопотно, хотя это и есть дизайн Pyramid.
Итак, я думаю, что Registry(). настройки должны иметь только реальные "поточно-локальные" переменные и не должны иметь обычных параметров бизнес-логики. Разработчик должен взять на себя ответственность за сегрегацию нескольких модулей, классов, переменных вызовов и т.д. На данный момент, с моей точки зрения, я отвечу Крису. Или в "main" callable, выполните "execfile (" settings.py ", настройки, настройки)" и поместите его в какое-то "глобальное" пространство.