Pylons でアプリケーションを設定する方法は主に 2 つあります:
config ディレクトリのファイルはアプリケーションの振る舞いに関する特 定の側面を変更します。 ウェブ管理者がデプロイの際に変えることのできるど んなオプションも設定ファイルで指定されるべきです。
Tip
あるオプションが config ディレクトリのコードと設定ファイルのど ちらで設定されるべきかということに関する良い指標は、そのオプション がアプリケーションの機能に必要であるかどうかということです。アプリ ケーションがその設定なしには機能しないなら、それは適切な config/ に置かれるべきです。もしそのオプションがデプロイに よって変わりうるなら 実行時設定 に含まれます。
アプリケーションの config/ ディレクトリは以下のファイルを含んで います:
これらそれぞれのファイルによって、開発者はアプリケーションの振る舞いに 関する重要な側面を変えることができます。
新しいプロジェクトが作られるとき、プロジェクトのファイルの 1 つとして development.ini と呼ばれる設定ファイルのサンプルが自動的に生成 されます。このデフォルトの設定ファイルは開発のために使用するのに適切な オプションを含んでいます。例えば、 Pylons アプリケーションの開発中は、 エラーが発生する度にデバッグレポートを見ることができると非常に便利です。 development.ini ファイルはデバッグモードを有効にするオプション を含んでいるので、このようなエラーが表示されます。
どのアプリケーションを実行するかを決定するために設定ファイルが使われる ので、複数の設定ファイルを使用することで簡単にオプションのセットを切り 換えることができます。典型的に、開発者はテスト (訳注: 開発) のための development.ini 設定ファイルと paster make-config コマン ドで生成された production.ini ファイルを使います。 production.ini ファイルは paster make-config コマンドが 適切なプロダクション用ファイルを生成することをテストするために使用され ます。また、 test.ini 設定は、テスト専用のオプションのためにプ ロジェクトに含まれています。
アプリケーションを実行するときに使用する設定ファイルを指定するには、 paster serve の最後の部分に必要な設定ファイルを含めるように 変えてください:
$ paster serve production.ini
See also
設定ファイルのフォーマット とオプション は、 Paste Deploy documentation で丹念に説明されて います。
設定ファイルからのすべての情報は pylons.config オブジェクトで利用可 能です。 また、 pylons.config はプロジェクトの config.environment モジュールで定義されたアプリケーション設定を 含んでいます。
from pylons import config
pylons.config は辞書のように振る舞います。例えば設定ファイルの [app:main] ブロックの中に以下のエントリがある場合:
cache_dir = %(here)s/data
プロジェクトコードではこれを次のようにして読み込むことができます:
from pylons import config
cache_dir = config['cache_dir']
あるいは現在のデバッグ状態については:
debug = config['debug']
デフォルトでは、設定ファイルのすべての値は文字列であるとみなされます。 ブール値をより簡単に扱えるようにするために、 Paste ライブラリは true と false を適切な Python ブール値へと変換する関数を提供し ています:
from paste.deploy.converters import asbool
debug = asbool(config['debug'])
この関数は、既にデフォルトプロジェクトの ミドルウェア の中 で、開発モード (debug で表される) が true にセットされているときだ け使用されるミドルウェアを切り換えるために使用されています。
アプリケーションをデプロイするときに使用される設定 INI ファイルのデフォ ルトを変えるには、 config/deployment.ini_tmpl ファイルを編集し てください。このファイルはデプロイの際にテンプレートとして使用されて、 デプロイを行う人にとってアプリケーションに設定する必要のある最小限のオ プションの出発点となります。
deployment ini で設定される中で最も重要なオプションの 1 つは、 debug = true という設定です。アプリケーションエラーが発生した場合に適切な開 発者またはウェブ管理者にメールが送られるように、メールオプションがセッ トアップされるべきです。
プロジェクトの config/deployment.ini_tmpl から production.ini を生成するには、それを最初に egg として、または開発モードでイン ストールしなければなりません。 Pylons アプリケーションの名前が helloworld であるとすると、以下を実行してください:
$ paster make-config helloworld production.ini
Note
このコマンドは、開発中のプロジェクトの中からでも実行できます。
ウェブ管理者が paster make-config コマンドを使用したときに適切なデ フォルト設定値が存在することを保証するのは、開発者の責任です。
Warning
常に Pylons アプリケーションをデプロイするときは、確実に debug を false に設定するようにしてください。
config/environment.py モジュールは、アプリケーションを実行する のに必要とされる基本的な Pylons 環境変数をセットアップします。アプリケー ション全体のために一度だけセットアップされるオブジェクトは、ここか、も しくは lib/app_globals の __init__() メソッドでセットアッ プすべきです。
それはまた、 URL がどのように コントローラ とマッチされるかをセッ トアップする URL 設定 関数を呼び出します。そして app_globals オブジェクトを作り、どのモジュールが h とし て参照できるようになるかを設定します。さらに、テンプレートエンジンがセッ トアップされる場所でもあります。
SQLAlchemy を使用するとき、このモジュールで SQLAlchemy エンジンをセット アップすることが推奨されます。 Pylons のデフォルトの SQLAlchemy 設定で はここでエンジンが作成されます。そのエンジンは後に model/__init__.py で使用されます。
Routes と呼ばれる Python ライブラリが、 URL からコントローラとそのメソッ ド (Routes はそれを action と呼びます) へのマッピングを扱います。 デフォルトで、 Pylons は以下の route をセットアップします (それ らは config/routing.py で見つかります):
map.connect('/{controller}/{action}')
map.connect('/{controller}/{action}/{id}')
.. Prior to Routes 1.9, all map.connect statements required
.. variable parts to begin with a ``:`` like
.. ``map.connect(':controller/:action')``. This syntax is now
.. optional, and the new ``{}`` syntax is recommended.
Changed in version 0.9.7: Routes 1.9 より前は、 map.connect(':controller/:action') のよう に、すべての map.connect 文が : で始まる可変部分を必要としてい ました。現在この構文はオプションであり、新しい {} 構文が推奨さ れます。
すべての中括弧の内側のパス部分は、その ‘部分’ が URL 内のどんなテキスト にもマッチする変数 (可変部分) です。 URLの ‘部分’ とは、 2つのスラッ シュの間のテキストのことです。 URL のすべての部分が route にマッ チしなければ、 404 が返されます。
上記の route は、高性能な URL マッチングのために Routes ライブラリによっ て正規表現に変換されます。デフォルトで、すべての可変部分は、 ({controller} の特別な場合を除いて) スラッシュ以外の全ての文字とマッ チするように [^/]+ という正規表現になります。これは簡単に変えること ができて、例えば {id} が数字だけにマッチするようにするには、このよ うにします:
map.connect('/{controller}/{action}/{id:\d+}')
正規表現が {} を含んでいるなら、それを可変部分とは別に指定しなけれ ばなりません。 {id} が 2-4 桁の数字にしかマッチしないように制限する ためには:
map.connect('/{controller}/{action}/{id}', requirements=dict(id='\d{2,4}'))
また、キーワード引数としてコントローラとアクションを指定することができ、 その場合にはそれらが URL に含まれている必要はありません:
# Archives by 2 digit year -> /archives/08
map.connect('/archives/{year:\d\d}', controller='articles', action='archives')
map.connect 文における可変部分、またはキーワード引数は、アクション の中で利用することが可能です。上の route の場合、 article コントロー ラに解決されます:
class ArticlesController(BaseController):
def archives(self, year):
...
year とマッチした URL 部分は、関数引数の中で名前によって参照できます。
Note
Routes は、 URLの ‘最小化’ 機能も含んでいます。 この振舞いは一般に 直感的でなく、 Pylons 0.9.7 からは map.minimization=False 設定 によって、デフォルトでオフになっています。
デフォルトのマッピングは、あらゆるコントローラのあらゆるアクションにマッ チします。これは以下の URL がマッチすることを意味します:
/hello/index >> controller: hello, action: index
/entry/view/4 >> controller: entry, action: view, id:4
/comment/edit/2 >> controller: comment, action: edit, id:2
複雑な URL が必要でない場合、この簡単な方法は大規模なアプリケーションに さえ適していることがあります。
また、コントローラをディレクトリにまとめることができます。例えば管理画 面用に別の comments コントローラが必要なら:
$ paster controller admin/comments
これにより admin ディレクトリの下に適切な comments コントローラ が作成されます。 comments コントローラに到達するために:
/admin/comments/index >> controller: admin/comments, action: index
Note
{controller} マッチは特別です。というのも、次のスラッシュ (/) で常に停止するわけではないからです。上記の例が示すように、 それはディレクトリの下に入れ子になったコントローラとマッチします。
map.connect() 文において、生の URL がマッチするのと同時に、コント ローラとアクションを直接指定することができます:
map.connect('/', controller='main', action='index')
これにより、 / が main コントローラの index メソッドで扱わ れるようになります。
Note
デフォルトでは、 プロジェクトの静的 (public/ ディレクトリの 中の) ファイルはコントローラよりも優先されます。新しい Pylons プロ ジェクトは / URL で表示されるウェルカムページ (public/index.html) を含んでいるので、ルーティング設定をす る前にこのファイルを取り除いた方が良いでしょう。
URL は callable な routes.util.URLGenerator オブジェクトを通し て生成されます。Pylons は pylons.url でこの特別なオブジェクトの インスタンスを提供します。このオブジェクトはキーワード引数として route で定義されたコントローラ、アクション、および追加の変数を受け取ります。
# generates /content/view/2
url(controller='content', action='view', id=2)
現在のリクエストにマッチする route の URL を生成するには、 routes.util.URLGenerator.current() をこのように呼んでください:
# Generates /content/view/3 during a request for /content/view/3
url.current()
routes.util.URLGenerator.current() は url() と同じ引数を受け 取ります。これは、関連するすべての引数を指定することなく現在の URL に対 する小さな変更を生成するために Routes memory を使用します。
# Generates /content/view/2 during a request for /content/view/3
url.current(id=2)
See also
Routes manual 完全な詳細とソースコード。
プロジェクト WSGI スタックは config/middleware.py モジュールで セットアップされます。観念的に、このファイルは必要とするミドルウェアを インポートして、 make_app 関数でそれをセットアップします。
Pylons アプリケーションのためのセットアップであるデフォルトスタックは WSGI ミドルウェア で詳細に説明されます。
デフォルトミドルウェアスタック:
# The Pylons WSGI app
app = PylonsApp()
# Routing/Session/Cache Middleware
app = RoutesMiddleware(app, config['routes.map'])
app = SessionMiddleware(app, config)
app = CacheMiddleware(app, config)
# CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
if asbool(full_stack):
# Handle Python exceptions
app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
# Display error documents for 401, 403, 404 status codes (and
# 500 when debug is disabled)
if asbool(config['debug']):
app = StatusCodeRedirect(app)
else:
app = StatusCodeRedirect(app, [400, 401, 403, 404, 500])
# Establish the Registry for this application
app = RegistryManager(app)
if asbool(static_files):
# Serve static files
static_app = StaticURLParser(config['pylons.paths']['static_files'])
app = Cascade([static_app, app])
return app
それぞれのミドルウェアはそれより前のものをラップするので、スタックはそ れが呼ばれる順の逆順で組み立てられる必要があります。 すなわち、 WSGI Application をラップする最後のミドルウェアは、サーバによって最初に呼ば れます。
スタックの中のミドルウェアの最後の断片は Cascade と呼ばれ、開発の間、静 的な内容ファイルを返すのに使用されます。最高の性能のためには、設定ファ イルの中で static_files = false と設定することで Cascade ミドルウェ アを無効にすることを考慮してください。そして、ウェブサーバあるいは CDN が静的なファイルを返します。
Warning
ミドルウェアを変更するかどうか自信がなければ、 変更しないでくださ い 。ミドルウェアの順番は Pylons アプリケーションが適切に機能する ために重要であり、必要でない場合には変更するべきではありません。
カスタムミドルウェアは config/middleware.py のコメントマーカー のところに追加します:
# CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
例えば、 MyMiddleware というミドルウェア・コンポーネントを加える場合、 config/middleware.py でそれを含めてください:
# The Pylons WSGI app
app = PylonsApp()
# Routing/Session/Cache Middleware
app = RoutesMiddleware(app, config['routes.map'])
app = SessionMiddleware(app, config)
app = CacheMiddleware(app, config)
# CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
app = MyMiddleware(app)
app オブジェクトは単にパラメタとして MyMiddleware ミドルウェアに渡さ れ、それは順次ラップされた WSGI アプリケーションを返します。
カスタムミドルウェアをどの層の中に置くか決めるときは注意が必要です。 多 くの場合、ミドルウェアは Pylons WSGI アプリケーションとそれをサポートす る Routes/Session/Cache ミドルウェアの前に置かれるべきですが、そのミド ルウェアが CacheMiddleware の 後に 実行すべきなら、このようにします:
# Routing/Session/Cache Middleware
app = RoutesMiddleware(app, config['routes.map'])
app = SessionMiddleware(app, config)
# MyMiddleware can only see the cache object, nothing *above* here
app = MyMiddleware(app)
app = CacheMiddleware(app, config)
Pylons iniファイル (development.ini または production.ini) では、このブロックで full_stack フラグが true にセットされているか false にセットされているかを調べます:
[app:main]
use = egg:app_name
full_stack = true
full_stack フラグは、ミドルウェアをラップするプロセスの中に ErrorHandler とStatusCodeRedirect が層として含まれているかどうか決定し ます。このオプションが false に設定される唯一の状況は、複数の Pylons アプリケーションが走っていて、他の場所で適切なミドルウェアによってラッ プされる場合です。
Pylons を使用するプロジェクトに関して、言及されることのある ‘アプリケー ション・セットアップ’ には 2 種類あります。
プロジェクトの新しいインスタンスをより簡単にセットアップできるように、 基本的なデータベース・スキーマをセットアップしたり、必要なデフォルト値 を生成したりといった、セットアップ・スクリプトを作成できます。
Pylons プロジェクトでは、実行されるセットアップ・スクリプトはプロジェク トの websetup.py ファイルに配置されています。アプリケーション・ セットアップ手順をより簡単に書けるように、デフォルトのスクリプトはプロ ジェクト設定を読み込みます:
import logging
from helloworld.config.environment import load_environment
log = logging.getLogger(__name__)
def setup_app(command, conf, vars):
"""Place any commands to setup helloworld here"""
load_environment(conf.global_conf, conf.local_conf)
Note
プロジェクトが作成される際に SQLAlchemy を使用するように設定された なら、このファイルはより簡単にデータベースのテーブルをセットアップ できるように、データベース接続をセットアップするいくつかのコマンド を含むでしょう。
開発設定を使用してセットアップ・スクリプトを実行するには:
$ paster setup-app development.ini
Pylons を用いて新たに作成されたプロジェクトは標準の Python パッケージで す。 Python パッケージなので、パッケージのメタ情報を記録する setup.py ファイルがあります。そのオプションの大部分はかなり一目 瞭然ですが、最も重要なオプションは ‘install_requires’ です:
install_requires=[
"Pylons>=0.9.7",
],
これらの行は、アプリケーションの適切な機能のためにどんなパッケージが必 要かを表し、必要に応じてそれらをアップデートすべきであることを表します。 新しい依存性のために setup.py 行を再解析するには:
$ python setup.py develop
このコマンドは、依存性の要求が満たされるように必要に応じてパッケージを アップデートすることに加えて、パッケージがシステムで確実にアクティブに なるようにします (伝統的な python setup.py install を必要と せずに)。
See also