velruse使ってみる. ini.fileを2つに分けると良いと思った

velruseは,oauth系の認証を一手に引き受けてくれるライブラリ

対応しているprovider

現時点でpypiに上がっているバージョンはsqlite3の対応に難が合った

直接githubから開発版をインストールすると良い。

easy_install -U https://github.com/bbangert/velruse/tarball/master

リポジトリの中にサンプルアプリがあるので、これを参考にする。

と、ここまでは前置き。

consumer secretの管理とか面倒。

話したいのはここから先。oauthなどでログイン処理を書くとき、アプリ毎にconsumer keyやconsumer secretを取得する必要がある。
当然velruseにもそれらの値を渡して挙げる必要がある。これは以下のように書く(例えばdevelopment.iniに)。

velruse.providers =
 velruse.providers.twitter
 velruse.providers.facebook
velruse.twitter.consumer_key = XXXxXxxxxXXXxxxXxxXXxx
velruse.twitter.consumer_secret = xxXXXxXxXxXxxXxXXxxXXxXxxxxXxXXXxxxXxxxX

普通に開発する分には、develop.iniなどの設定ファイルに直接書けば良いけれど、githubなどに挙げる時、見えてしまうのはあまり良くない。
そんなわけで隠したいと思うのだけれど、コミット毎の変更などは面倒。

設定ファイルを2つに分ける(my.ini)

秘密の情報を管理しておく設定ファイル(my.ini)を作成し、それを.gitignoreに登録しておくことにした。
そうすれば、upされたリポジトリはconsumer secretなどの情報を含んでいない。

$ ls | grep .ini
development.ini
my.ini
production.ini

実際の設定内容

.gitignoreにmy.iniを追加

#.gitignore
my.ini

development.iniに"my.velruse.secret.file"という値を設定した

# developemt.ini
my.velruse.secret.file = %(here)s/my.ini

my.iniに"velruse.providers"に対応するsection名で値を列挙した。

[velruse.providers.twitter]
velruse.twitter.consumer_key = XXXxXxxxxXXXxxxXxxXXxx
velruse.twitter.consumer_secret = xxXXXxXxXxXxxXxXXxxXXxXxxxxXxXXXxxxXxxxX
アプリの__init__.pyでmy.iniから設定を読み込む処理を追加した

以下のような感じ。setup_via_secret_iniという関数を作ってここでconsumer secret などの情報を取得している。

def setup_via_secret_ini(settings):
    """ update settings dict from settings["my.velruse.secret.file"].
        e.g. 
        [velruse.providers.twitter]
        velruse.twitter.consumer_key = XXXxXxxxxXXXxxxXxxXXxx
        velruse.twitter.consumer_secret = xxXXXxXxXxXxxXxXXxxXXxXxxxxXxXXXxxxXxxxX
    """
    import os
    import ConfigParser
    secret_ini = settings.get("my.velruse.secret.file")
    if secret_ini is None:
        return
    if not os.path.exists(secret_ini) and os.path.isfile(secret_ini):
        raise ConfigurationError("secret ini: %s is not found")

    config = ConfigParser.ConfigParser()
    config.read([secret_ini])

    for section in settings["velruse.providers"].lstrip().split("\n"):
        settings.update(config.items(section))
    return settings
    
def main(global_config, **settings):
    """ This function returns a WSGI application.
    """
    setup_via_secret_ini(settings)
    engine = engine_from_config(settings, 'sqlalchemy.')
    get_root = appmaker(engine)
    ## ..以下続く