質問

I am writing a pyramid application in Python, and I have several scripts that all require the same information which is situated in development.ini

How do I fetch the information from development.ini and assign it to a variable in another script? Such that I can take this

# development.ini

[app:main]
some.url = some_url

[other_thing]
info.partA = some_info
info.partB = some_other_info

and turn it into this

# some_script.py

url = some_url
infoA = some_info
infoB = some_other_info

This page's solution uses def main(global_config, **settings):, but that makes no sense to me at all. This and this page use ConfigParser.ConfigParser(), but I'm not getting that to work either.

I am fairly new at this, so would you please be as explicit as possible?

役に立ちましたか?

解決

Good question. Pyramid can use PasteDeploy configuration files for application configuration. Therefore it offers pyramid.paster for that. Consider you want to setup your database tables before running your web application the first time, or have a maintenance script that runs on a daily basis. You want both scripts to take the connection string from the development.ini/production.ini as well. This is considered good practice.

This is a common yourwebapp.__init__.py you already know. PasteDeploy configuration is passed into main() function by running bin\pserve development.ini

from pyramid.config import Configurator

from sqlalchemy import engine_from_config

from .models import DBSession, Base

def main(global_config, **settings):
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)
    Base.metadata.bind = engine

    config = Configurator(settings=settings,
                          root_factory='tutorial.models.Root')
    config.include('pyramid_chameleon')
    config.add_route('wiki_view', '/')
    config.add_route('wikipage_add', '/add')
    config.add_route('wikipage_view', '/{uid}')
    config.add_route('wikipage_edit', '/{uid}/edit')
    config.add_static_view('deform_static', 'deform:static/')
    config.scan('.views')
    return config.make_wsgi_app()

To have acccess to your application configuration in another script say some_script.py as well use methods from pyramid.paster to read settings and init logging from settings as well.

from sqlalchemy import engine_from_config

from pyramid.paster import (
    get_appsettings,
    setup_logging,
    )

from .models import (
    DBSession,
    Base,
    )

def do_your_stuff(settings)
    "your custom script logic that extracts a certain settings and does something"




def main(argv=sys.argv):
    config_uri = argv[1]
    setup_logging(config_uri)
    settings = get_appsettings(config_uri)
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)
    Base.metadata.create_all(engine)
    do_your_stuff(settings)

To wire up everything you need to add an entry point for a command-line script in your setup.py. Read carefully the console_script section. You define a name for script and point to 'main' function of your some_script.py. This is want you need to customize for every application and script.

from setuptools import setup

requires = [
    'pyramid',
    'pyramid_chameleon',
    'deform',
    'sqlalchemy',
    'pyramid_tm',
    'zope.sqlalchemy'
]

setup(name='tutorial',
      install_requires=requires,
      entry_points="""\
      [paste.app_factory]
      main = tutorial:main
      [console_scripts]
      initialize_db = yourwebapp.some_script:main
      """,
)

Because your changed setup.py you need to run the command below to create the console script that you will find in 'bin' folder (same folder where you call pserve from). I take for granted that are running a virtualenv.

$ $VENV/bin/python setup.py develop

Afterwards you can run you script with your configuration file

$ $VENV/bin/initialize_db development.ini

In production take another configuration file. That's the beauty.

$ $VENV/bin/initialize_db production.ini

Several third-party libraries offer special helper function (factories) that are driven by paster configuration files. Examples are sqlalchemy, pyramid.zodbconn usually have methods with names like *_from_config(settings).

References

I tried to make it a bit shorter for you. Watchout for PasteDeploy topics and pyramid.paster stuff in other pyramid apps.

他のヒント

This page's solution uses def main(global_config, **settings):, but that makes no sense to me at all

From http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/startup.html:

Note that an augmented version of the values passed as **settings to the Configurator constructor will be available in Pyramid view callable code as request.registry.settings. You can create objects you wish to access later from view code, and put them into the dictionary you pass to the configurator as settings. They will then be present in the request.registry.settings dictionary at application runtime.

Meaning variables set in [app:main] within the used ini file are accessible in the app via the request.registry.settings dict.

http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html#adding-a-custom-setting

You may use «get_settings()»

There is an example with "mongo_uri" in settings

settings/development.ini:

[app:main]
use = egg:gps_tracker
mongo_uri = mongodb://localhost:27017/gps

db.py:

from urllib.parse import urlparse
import pymongo

def includeme(config):
    settings = config.get_settings()
    mongo_db_url = urlparse(settings['mongo_uri'])
    settings['mongo_db_url'] = mongo_db_url
    settings['mongo_db_name'] = mongo_db_url.path[1:]
    settings['mongo_hostname'] = mongo_db_url.hostname
    settings['mongo_port'] = int(mongo_db_url.port or 27017)

    connection = pymongo.MongoClient(host=mongo_db_url.hostname,
                                     port=mongo_db_url.port)
    config.registry.mongo_connection = connection

view in context

import ConfigParser
config = ConfigParser.ConfigParser()
config.read("development.ini")

dConfig = config.__dict__['_sections'].copy()

url = dConfig['app:main']['some.url']
infoA = dConfig['other_thing']['info.partA']
infoB = dConfig['other_thing']['info.partB']

is now equal to

url = some_url
infoA = some_info
infoB = some_other_info

if the thing is in development.ini or production.ini and in [app:main], then:

info = self.request.registry.settings["info"]

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top