Estoy acostumbrado a desarrollar aplicaciones web en Django y gunicornio.¿Cómo obtener la configuración del Registro() durante el tiempo de inicio de la aplicación Pyramid?
En el caso de Django, cualquier módulo de aplicación en una aplicación Django puede obtener configuraciones de implementación a través de django.conf.settings. El "settings.py" está escrito en Python, por lo que se puede definir cualquier configuración arbitraria y preprocesamiento dinámicamente.
En caso de gunicorn, tiene tres lugares de configuración en orden de precedencia, y de una configuración instancia de clase de registro combina esos. (Pero por lo general estos valores sólo se utilizan para gunicorn no aplicación.)
- línea de comandos parámetros.
- Archivo de configuración. (como Django, escrito en Python que puede tener cualquier configuración arbitraria dinámicamente.)
- Ajustes de la aplicación de Paster.
En caso de pirámide, según la documentación de la pirámide, la configuración de implementación puede ser por lo general ponen en pyramid.registry.Registry(). configuración. Pero parece que se accede solo cuando existe una pyramid.router.Router() instancias. Eso es pyramid.threadlocal.get_current_registry(). Settings devuelve None, durante el proceso de inicio en una aplicación "main.py".
Por ejemplo, generalmente defino cierta lógica comercial en los módulos de modelo SQLAlchemy, que requiere la configuración de implementación de la siguiente manera.
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)
Pero, "los ajustes [ 'external_api_endpoint']" plantea una excepción TypeError debido a la "configuración" no es.
Pensé dos soluciones.
definir un exigible, que acepta el argumento "config" en "models.py" y "main.py" lo llama con una instancia configurador().
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
o, dicho de un módulo vacío "app/settings.py", y poner la configuración en él más tarde.
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()
Tanto y otras soluciones cumplen con los requisitos, pero me siento molesto. Lo que quiero es lo siguiente.
development.ini
define la configuración en bruto al desarrollo.ini solo puede tener string tipo de constantes.
[app:myapp] use = egg:myapp env = dev0 api_signature = xxxxxx
miaplicacion/settings.py
define la configuración detalle basándose en development.ini, Beacause cualesquiera variables arbitrarias (tipos) se puede ajustar.
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']}))
Luego, otros módulos puede obtener la configuración de implementación arbitraria a través de "importación" myapp.settings. O, si la configuración del Registro(). Es preferible a "settings.py", ** las configuraciones kwargs y "settings.py" pueden combinarse y registrarse en la configuración del Registro() durante el proceso de inicio "main.py".
De todos modos, ¿cómo obtener la configuración dictionay durante el tiempo de inicio? O bien, Pyramid nos obliga a colocar todos los códigos que requieren configuración de implementación en callables de "vistas" que pueden obtener el diccionario de configuración en cualquier momento a través de request.registry.settings?
EDITAR
Gracias, Michael y Chris.
Finalmente, entiendo por qué Pyramid usa variables threadlocal (registro y solicitud), en particular objeto de registro para más de una aplicación Pyramid.
En mi opinión, sin embargo, la configuración de implementación generalmente afecta las lógicas comerciales que pueden definir algunas cosas específicas de la aplicación. Esas lógicas se suelen incluir en uno o más módulos de Python que pueden ser distintos de "app/init .py" o "app/views.py" que pueden acceder fácilmente a Config() o Registry(). Esos módulos de Python son normalmente "globales" en el nivel de proceso de Python.
Es decir, incluso cuando más de una aplicación Pyramid coexisten, a pesar de sus propias variables locales, deben compartir esos módulos "globales" de Python que pueden contener aplicaciones específicas en el nivel de proceso de Python.
De causa, cada uno de esos módulos puede tener "initialize()" callalbe que se llama con un Configurator() por la aplicación "principal" invocable, o pasando el objeto Registory() o Request() a través de series de funciones tan largas las llamadas pueden cumplir con los requisitos habituales. Pero, supongo que los principiantes de Pyramid (como yo) o los desarrolladores que tienen "grandes aplicaciones o tantos ajustes" pueden sentirse molestos, aunque ese sea el diseño de Pyramid.
Por lo tanto, creo que la configuración del Registro() debe tener solo variables reales "thread-local" y no debe tener una configuración lógica de negocios normal. La responsabilidad por la segregación de múltiples módulos específicos de la aplicación, clases, variables callables, etc. debe ser tomada por el desarrollador. A partir de ahora, desde mi punto de vista, responderé a la respuesta de Chris. O en "principal" invocable, haga "execfile ('settings.py', settings, settings)" y póngalo en algún espacio "global".
¡Gracias! Tomo su solución. La razón se describe más arriba en la parte "EDITAR". (Permítame editarla por descripción larga) – takaomag