Pyramid イントロダクション

Pyramid は、汎用的なオープンソースの Python ウェブアプリケーション 開発 フレームワーク です。その主目的は Python 開発者がウェブアプリケー ションを作成することをより簡単にすることです。

Pyramid は、これらの設計とエンジニアリングの原則に従うよう努めます:

簡潔性

Pyramid は、 「使った分だけお支払い」 アプローチを取ります。 Pyramid について部分的な理解だけしか持っていなくても結果を得る ことができます。 Pyramid はアプリケーションを生成するために特別な技術 の使用を強制しません。私たちは、理解する必要のある概念のコアセットを 最小に維持しようとしています。

ミニマリズム

Pyramid は、ウェブアプリケーション作成の根本問題だけを解決しよ うとします: URL からコードへのマッピング、テンプレート、セキュリティ、 静的 asset の表示。私たちは、これらをほぼすべてのウェブアプリケーション に共通のコア活動と考えます。

ドキュメンテーション

Pyramid のミニマリズムは、完全で最新のドキュメンテーションを維持する ことがより簡単であることを意味します。私たちのゴールは、 Pyramid の どの側面も文書化されている、という状態です。

スピード

Pyramid は、テンプレート処理や単純なレスポンス生成のような共通 タスクのために、顕著に高速な実行速度を提供することを目指しています。 確かに「ハードウェアは安い」ですが、非常に多数のマシンを管理する責任 を持つことになると、このアプローチの限界はひどく明らかになります。

信頼性

Pyramid は保守的に開発されており、徹底的にテストされています。 Pyramid のソースコードに関して、私たちのモットーは次の通りです: 「テストされていないものは壊れている」

オープン性

Python と同じように、 Pyramid ソフトウェアは 寛容なオープンソース ライセンス の下で配布されます。

Pyramid のユニークな点

当然ながら、人々は通常 squishy (感傷的) なエンジニアリング原則が聞きたいのではなく、 自分たちの問題を解決する具体的な事柄に関して聞くことを望みます。それを 念頭において、なぜ今日利用可能な他の多くのウェブフレームワークに代わって Pyramid を使用するのでしょうか。Pyramid のユニークな点は何でしょうか。

これは答えることが困難な質問です。多くの優れた選択肢があり、特に Python ウェブフレームワーク業界では、間違った選択を行なうことは実際にまったく 困難なためです。しかし、1つの合理的な回答がこれです: Pyramid をあまり よく知らなくても、非常に小さなアプリケーションを書くことができます。 「え?」とあなたは言うでしょう。「それは別にユニークな特徴なんかじゃない。 他の多くのウェブフレームワークでもできるよ!」ええ、それは正しいです。 しかし、他の多くのシステムと異なり、もう少し学習すれば、さらに Pyramid で非常に大きなアプリケーションを書くことができます。 Pyramid は、あな たが素早く生産的になることを可能にし、あなたと共に成長します; アプリケーションが小さい場合、 Pyramid はあなたを制約しません。また、 アプリケーションが大きくなる場合、それはあなたのやり方を邪魔しません。 「なるほど、それは素晴らしい」とあなたは言います。「でも他の多くの フレームワークでも大きなアプリケーションを書くことはできるよ」 もちろんです。しかし、他の Python ウェブフレームワークでは、両方を シームレスに行うことができません。それらは、オーバーラップしない2つの カテゴリに分類されるように見えます:「小さなアプリケーション」用のフレーム ワークと「大きなアプリケーション」用のフレームワークというように。「小さなアプリ」 フレームワークは、典型的には「大きなアプリ」の特徴を犠牲にしていて、 その逆も然りです。

私たちは、「小さなフレームワーク」で「小さなアプリケーション」を書き、 「大きなフレームワーク」で「大きなアプリケーション」を書く、というのは 普遍的な合理的提案ではないと思います。すべてのアプリケーションが最終的 にどれだけのサイズに成長するかを実際に知ることはできません。以前は小さな アプリケーションだったものを、それが「大きく」なりすぎた場合に別のフレーム ワークで書き直さなければならない、なんてことは全然望んでいません。 私たちは、大小のアプリケーションに対してフレームワークが二分されている 現状はまったく誤りであると信じます; 良く設計されたフレームワークは、 両方に対して優れているはずです。 Pyramid はその種のフレームワークになる ように努力します。

この目的のために、 Pyramid は1セットの特徴を提供します(それらの組み合わせは、 Python ウェブフレームワークの中でユニークです)。他の多くのフレームワークは、 これらの特徴の特定の組み合わせを含んでいます; Pyramid は、もちろんそれらの 特徴のうちの多くのものを実際に他のフレームワークから盗みました。しかし、 Pyramid はそれらすべてを適切な文書化とともに一ヶ所に持つただ一つの フレームワークです。それはフルコースに対する必然的な支払いを必要としない 便利なアラカルト (一品料理) です。これらは以下に詳述されます。

単一ファイルアプリケーション

既存の Python マイクロフレームワークと同じく、単一の Python ファイルの 中だけで完結する Pyramid アプリケーションを書くことができます。これは、 1回限りのプロトタイピングや、バグの再現、非常に小さなアプリケーション には有益です。アプリケーションに関するすべての情報が一つの場所にまとまって いるので、これらのアプリケーションは理解するのが簡単です。また、 Python の配布やパッケージングに関して多くのことを理解する必要なしに それらをデプロイすることができます。実際のところ Pyramid はマイクロフレーム ワークとして世に出されているわけではありませんが、マイクロフレームワークと 呼ばれているような他のフレームワークが提供することはほとんどすべて、 良く似た方法で実現できます。

from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response


def hello_world(request):
    return Response('Hello %(name)s!' % request.matchdict)

if __name__ == '__main__':
    config = Configurator()
    config.add_route('hello', '/hello/{name}')
    config.add_view(hello_world, route_name='hello')
    app = config.make_wsgi_app()
    server = make_server('0.0.0.0', 8080, app)
    server.serve_forever()
   

Creating Your First Pyramid Application も参照してください。

デコレータベースの設定

フレームワークの設定が関連するコードのすぐ近くにあり、したがって新しい コードを追加する場合にフレームワーク設定を参照するためにファイル間で絶えず 切り替える必要がない、というアイデアが好きなら、設定を局所化するために Pyramid デコレータを使用することができます。例えば:

from pyramid.view import view_config
from pyramid.response import Response

@view_config(route_name='fred')
def fred_view(request):
    return Response('fred')

しかし、他のいくつかのシステムとは異なり、 Pyramid 設定にデコレータを 利用することはアプリケーションの拡張、テスト、再利用を困難にしません。 例えば、 view_config デコレータは、デコレートする 関数の入出力を実際には 変更 しません。したがって、そのテストは 「WYSIWYG」な操作です; 自分のコードをテストするためにフレームワークを 理解する必要はありません。単にあたかもそこにデコレータが存在しないかの ように振る舞えば良いのです。さらに、 Pyramid がいくつかのデコレータを無視 するようにしたり、ビューを追加するためにデコレータの代わりに完全に命令 的な設定を使用することもできます。 Pyramid デコレータは積極的 (eager) ではなく消極的 (inert) です。 scan によってそれらを検知し活性化 します。

例: Adding View Configuration Using the @view_config Decorator

URL 生成

Pyramid は、リソース、ルートおよび静的 asset 用に URL を生成することが できます。その URL 生成 API は使いやすく柔軟です。 URL を生成するために Pyramid の様々な API を使用すれば、多数のウェブページ中で一つのリンク 切れも起こす心配なしに設定を任意に変更することができます。

例: Generating Route URLs

静的ファイルサーバ

Pyramid はそれ自体で静的ファイルを返す完全な機能を持ちます。そのため 外部のウェブサーバを使用する必要はありません。さらに、 1 つの Pyramid ウェブアプリケーションで複数の静的ファイルの集合を返すことができます (例えば /static/static2)。さらに、任意で、ファイルを外部 ウェブサーバに置き、 Pyramid がそれらのファイルへの URL を生成するように できます。したがって、コードも一切変更することなく、開発時には Pyramid の内部ファイルサーバを使い、プロダクション環境ではより高速な静的ファイル サーバを使用することができます。

例: Serving Static Assets

デバッグツールバー

Pyramid scaffold を使用した場合、 Pyramid のデバッグツールバーが有効に なった状態でプロジェクトが作成されます。このツールバーは、ブラウザ内で アプリケーションを覆って、フレームワークデータへのアクセスを与え ます: 設定されたルート、最後のレンダリング結果、現在インストールされて いるパッケージ一覧、 SQLAlchemy クエリ実行、ログデータ、および他の 様々な情報。例外が生じた場合、例外の原因を特定するためにブラウザの中で 色々とつつき回るために対話型デバッガを使用することができます。それは手軽です。

例: The Debug Toolbar

デバッグ設定

Pyramid にはデバッグ設定があり、物事が期待した通りに動作していない場合 に Pyramid ランタイム情報をコンソールに表示することができます。例えば、 “debug_notfound” を有効にすると、 URL がビューと一致しない場合はいつで もコンソールに通知メッセージを表示するようになります。 “debug_authorization” を有効にすることで、なぜビュー実行が許可または禁 止されたをコンソールにメッセージ表示することで知らせます。これらの特徴 は、これらの WTF 時に役立ちます (訳注: What the fuck = 「なんてこった」の意味?)。

さらに、システムの設定を調査するために Pyramid 環境内で実行できる数々の コマンドがあります: proutes は、アプリケーション用に設定されたルートを マッチに際してそれらが評価される順番ですべて示します; pviews は、 所定の URL に対して設定されたビューをすべて表示します。これらはまた、 いくつかの状況で WTF-crushers (訳注: デバッグに便利、というような意味か?) です。

例: Debugging View Authorization Failures, Command-Line Pyramid

アドオン

Pyramid には、 Pyramid コアそれ自体と同じ品質水準を持つ広範囲なアドオン のセットがあります。アドオンは Pyramid コアが提供しない機能を提供する パッケージです。電子メールを簡単に送ったり、Jinja2テンプレートシステム を使用したり、 XML-RPC あるいは JSON-RPC を使用したり、jQuery Mobile と 統合したりするアドオンパッケージは既に存在します。

例: http://docs.pylonsproject.org/docs/pyramid.html#pyramid-add-on-documentation

クラスベースと関数ベースのビュー

Pyramid には view callable という構造化された統一的な概念があり ます。ビュー callable は、関数、クラスのメソッド、あるいはインスタンス です。新しいビュー callable を加える場合、それを関数あるいはクラスの メソッドのどちらにするか選択することができます; いずれの場合も Pyramid はそれを大部分は同じ方法で扱います。もし後で気が変わっても、クラスの メソッドと関数の間でコードを移動させることができます。類似したビュー callable のコレクションは、メソッドとして単一のクラスに取り付けることが できます。好みに応じて、必要なら初期化コードを共有することもできます。 すべての種類のビューは、理解して使用するのが簡単で、かつ同様に作動します。 それらの間に偽りの区別はありません; それらは同じ目的のために使用できます。

これは関数として定義したビュー callable です:

1
2
3
4
5
6
from pyramid.response import Response
from pyramid.view import view_config

@view_config(route_name='aview')
def aview(request):
    return Response('one')

これは代わりにクラスのメソッドとして定義したビュー callable です:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from pyramid.response import Response
from pyramid.view import view_config

class AView(object):
    def __init__(self, request):
        self.request = request

    @view_config(route_name='view_one')
    def view_one(self):
        return Response('one')

    @view_config(route_name='view_two')
    def view_two(self):
        return Response('two')

@view_config Placement も参照してください。

asset 仕様

asset 仕様は、例えば MyPackage:static/index.html のように Python パッケージ名とファイルまたはディレクトリ名の両方を含む文字列です。 この仕様は Pyramid の中のほとんどあらゆる場所で使われています。 asset 仕様は、テンプレート、翻訳ディレクトリ、あるいは他のパッケージに 結合された静的なリソースを指すことができます。これは Pyramid 上に構築された システムを拡張可能にします。なぜなら、ファイルを指し示すためにグローバル 変数 (「static ディレクトリ」) や、検索スキーム (「テンプレートディレクトリ の順序集合」) に頼る必要がないからです。必要に応じてファイルを移動する ことができ、システムのテンプレートや静的ファイルを共有することができない 他のパッケージを衝突することなくインクルードすることができます。

asset 仕様は Pyramid の中で極度に使用されているので、ユーザ が asset をオーバーライドできるようにする方法も提供されています。仮にあなたが誰か 他の人によって Pyramid で作成されたシステムを気に入って、それを改良するために 「ある1つのテンプレート」だけを変更する必要があるとします。アプリケーション をフォークする必要はありません。ラッパー内部でそのテンプレート用の asset 仕様をあなた自身のもので単にオーバーライドしてください。それだけ でうまくいきます。

例: Understanding Asset Specifications, Overriding Assets

拡張可能なテンプレート

Pyramid には「レンダラー」のプラグ可能性を実現するための構造化 API があります。 Mako, Genshi, Chameleon, Jinja2 のようなテンプレートシステムをレンダラー として扱うことができます。これらすべてのテンプレートシステムのための レンダラーバインディングは Pyramid で使用するために既に存在しています。 しかし、あなたがもし別のテンプレートシステムを使用したかったとしても、 それは大したことではありません。既存のレンダラーパッケージからコードを 単にコピーして、好きなテンプレートシステムをプラグインしてください。 そうすれば、ちょうど「内蔵の」テンプレートシステムを使用するのと同じように、 Pyramid の内部からそのテンプレートシステムを使用することが できるようになります。

Pyramid では単一のテンプレートシステムを排他的に使用する必要はありません。 同じプロジェクトの中でも多数のテンプレートシステムを使用することができます。

例: Using Templates Directly

レンダリングされるビューは辞書を返すことができる

renderer を使用していれば、ビューから特別な種類の「Web 特有」の Response オブジェクトを返す必要はありません。代わりに辞書を返すことが できます。すると Pyramid は、代わりにテンプレートを使用してその辞書をレスポ ンスに変換する世話をします。これはビューをテストすることをより簡単にします。 テストで HTML を解析する必要がないからです; 代わりに、単にビューが「正しい値」 を含んだ辞書を返すという assertion をしてください。あなたのビューすべてを 機能的にテストする代わりに、「本物の」ユニットテストを書くことができます。

例えば、こうする代わりに:

1
2
3
4
5
 from pyramid.renderers import render_to_response

 def myview(request):
     return render_to_response('myapp:templates/mytemplate.pt', {'a':1},
                               request=request)

このようにすることができます:

1
2
3
4
5
 from pyramid.view import view_config

 @view_config(renderer='myapp:templates/mytemplate.pt')
 def myview(request):
     return {'a':1}

このビュー callable が Pyramid によって呼ばれる時、辞書 {'a':1} が あなたの代わりにレスポンスに与えられるでしょう。上記の renderer= と して渡された文字列は asset specification です。それは packagename:directoryname/filename.ext の形式です。この場合、それは myapp Python パッケージ内の templates ディレクトリにある mytemplate.pt ファイルを指します。 asset 仕様は Pyramid において 広範に使用されます: 詳細は asset 仕様 を参照してください。

例: Renderers

イベントシステム

Pyramid はそのリクエスト処理ライフサイクル中に イベント を送出します。 これらのイベントに任意の数のリスナを登録することができます。例えば、 新しいリクエストについて通知を受けるために、 NewRequest イベントに 登録することができます。テンプレートをレンダリングする直前で通知を受け るために、 BeforeRender イベントに登録することができます。などなど。 ハードコードされたフックポイントの代わりに、フレームワーク通知機能として イベント公開システムを使用することは、そのフレームワークに基づくシステム をより壊れにくくする傾向があります (訳注: この文の意味は良く分からない)。

さらに、自分のイベントを送るために Pyramid のイベントシステムを使用する ことができます。例えば、それ自体がフレームワークであるようなシステムを 構築していて、ドキュメントがたった今インデックス化されたことを受信者に 通知したければ、自分のイベントタイプ (恐らく DocumentIndexed) を 作成して Pyramid 経由でイベントを送ることができます。そうすればこの フレームワークのユーザは、 Pyramid 自体によって通常送られるイベントと 同じように、あなたのイベントに登録することができます。

例: Using Events, Event Types.

組み込みの国際化機能

Pyramid はコアの中に国際化関連の機能を備えています: ローカライゼーション、 複数形変換、およびソースファイルとテンプレートからのメッセージカタログの作成。 Pyramid は翻訳ドメインの使用によって複数のメッセージカタログを考慮します: 他のドメインの他の翻訳と衝突することなくそれ自身の翻訳を持つシステムを 作成することができます。

例: Internationalization and Localization

HTTP キャッシュ

Pyramid はビューと HTTP キャッシングポリシーを関連付ける簡単な方法を 提供しています。 http_cache を付けてビューを設定すれば、残りは Pyramid が面倒を見てくれます:

@view_config(http_cache=3600) # 60 minutes
def myview(request): ....

Pyramid は、このビューが起動された時に生成されるレスポンスに 適切な Cache-Control および Expires ヘッダーを追加します。

詳細については add_view() メソッドの http_cache ドキュメンテーションを参照してください。

セッション

Pyramid は内蔵の HTTP セッション管理を持っています。これは、それ以外の 点では匿名のユーザにリクエスト間でデータを関連付けることを可能にします。 多くのシステムがこの機能を持っています。しかし、 Pyramid はさらに、文書化された インターフェースに適合する多少のコードを作成することで、あなた自身 のセッション管理システムをプラグインすることができます。現在、まさに これを行っているサードパーティの Beaker セッションシステムのための バインディングパッケージが存在します。しかし、特別なニーズ (例えば MongoDB にセッションデータを格納したい等) を持っていれば、それも可能です。 さらに、アプリケーションコードを変更せずにセッション管理の実装を切り替える こともできます。

例: Sessions

スピード

Pyramid コアは、私たちが知る限り、少なくとも他のどの既存の Python ウェブ フレームワークよりも多少は高速です。 Pyramid は最初から速度のために エンジニアリングされました。 Pyramid は、仕事の完了を依頼 された時に絶対的に必要な分の量の仕事だけをします。外部の関数呼び出し や最適でないアルゴリズムは、コアコードパス中では避けられています。 例えば、デュアルコアのコモディティなラップトップハードウェアと適切な WSGI サーバ (mod_wsgi または gunicorn) 上で、単純な Pyramid ビューで 毎秒 3500〜4000 リクエストを得ることは現実的です。いずれにしても、必要条件 とゴールなしではパフォーマンス統計は大して役に立ちませんが、 あなたが速度を必要とした場合に Pyramid はほぼ確実に アプリケーションのボトルネックにはなりません; 少なくとも、 Python が ボトルネックになる以上には。

例: http://blog.curiasolutions.com/the-great-web-framework-shootout/

例外ビュー

例外は起こります。プロダクション環境でユーザに表示される可能性のある 例外をアドホックな方法で扱うのではなく、 Pyramid は exception view を登録することができます。例外ビューは通常の Pyramid ビューに 似ていますが、例外が Pyramid 自体に「bubble up」する場合にのみ起動 されます。例えば、 Exception 例外に対する例外ビューを登録した とすると、それは すべての 例外を捕捉して、きれいな「おや、これは困った」 ページを表示します。あるいは、アプリケーションに特有の特定の種類の例外 だけに対する例外ビューを登録することもできます。例えばファイルが 見つからない場合に起こる例外や、またはユーザが何かをする許可を持たない ためにアクションを行なうことができない場合に起こる例外などです。 前者の場合、きれいな「Not Found」ページを表示することができます; 後者の場合には、ログインフォームを表示するかもしれません。

例: カスタム例外ビュー

シングルトン不要

Pyramid は、「シングルトン」データ構造を正確に一つも持たないことを アプリケーションに要求するような方法で書かれています。あるいは、別の言い方を すれば Pyramid は「書き換え可能なグローバル変数」を構築することを一切 要求しません。また別の言い方をすれば、 Pyramid アプリケーションのインポートは 「インポート時の副作用」を持ちません。これは深淵なテーマの ように聞こえますが、あなたがこれまでに Django の “settings.py” ファイル を同じアプリケーションの複数のインストールに対してパラメータ化しようとしたり、 あるフレームワーク内で固定的に書かれたコードをあなたのユースケースに対して適切 に動作させるためにモンキーパッチを当てる必要があったり、システムをデプロイ するために非同期サーバーを使用しようとしたことがあれば、最終的に この特徴を評価するでしょう。それはまったく問題になりません。さらに、 ある Pyramid アプリケーションの類似しているけれど同じではない設定の 複数のコピーを同じ Python プロセス内で実行することができます。これは 共有ホスティング環境には適しています (そのような環境で RAM は貴重です)。

ビュー述語と、1つのルートに複数のビュー

他の多くのシステムと異なり、 Pyramid は1つのルートに複数のビューを関連 付けることができます。例えば、パターン /items に対してルートを作り、 ルートがマッチしたときに、リクエストメソッドが GET だったらリクエストを あるビューにディスパッチし、リクエストメソッドが POST だったら別の ビューにディスパッチするといったことができます。「ビュー述語」として知られ ているシステムがこれを実現します。リクエストメソッドのマッチはビュー述語で できる最も基礎的なことです。さらに、クエリ文字列中の要素、 Accept ヘッダー、そのリクエストが XHR リクエストかどうか、あるいはその他多くの リクエストパラメータにビューを関連付けることができます。この特徴によって、 個々のビューを「クリーン」に保つことができます; それらはあまり条件付きの ロジックを必要としないでしょう。したがって、それらはより簡単にテストする ことができます。

例: View Configuration Parameters

トランザクション管理

Pyramid の scaffold システムは、 Zope から取られた トランザクション 管理 システムを含むプロジェクトを生成します。このトランザクション管理 システムを使用すると、あなたはもはやデータをコミットすることに責任を 持たなくなります。代わりに Pyramid がコミットの面倒を見ます: それはリクエストの終わりにコミットするか、あるいは例外がある場合に アボートします。なぜそれが良いものなのでしょうか。トランザクション管理 のための中心的な場所を持つことは素晴らしいことです。もし、中心的な場所 でトランザクションを管理する代わりに、アプリケーションロジック自体の中に session.commit 呼び出しをまき散らせば、悪い結果に行き着くでしょう。 データベースに手動でデータをコミットしているところならどこでも、他の コードのうちの一部はそのコミットの 後で 実行されます。コミットした 後でコードが他の重要なことをして、後のコードの中でエラーが起こる場合、 非常に注意深くしなければ、容易にデータの不整合を引き起こします。恐らく 書き出されるべきでないデータがデータベースに書かれているでしょう。中心的な コミットポイントを持っていることで、これに関して考える必要がなくなります; それは、さらにデータの一貫性に関心がある怠惰な人々にとっても素晴らしい ものです。リクエストは成功裡に完了して変更がすべてコミットされるか、 コミットされずにすべての変更がアボートされるかのいずれかです。

さらに、 Pyramid のトランザクション管理システムは複数のデータベース間で コミットを同期することを可能にします。そして、トランザクションがコミット する場合に条件付きで電子メールを送り、そうでなければ何もしないといった ことができるようになります。

例: SQLAlchemy + URLディスパッチ Wiki チュートリアル (アプリケーションコードのどこにも コミット文がないことに注目してください)。

矛盾する設定の検知

システムが小さいうちは、それをすべて頭の中に入れておくことはそれほど 難しくありません。しかし、システムが大きくなると、ビューの追加やルートの 追加を行う設定ステートメントが何百、あるいは何千になることがあります。 Pyramid の設定システムは、あなたの設定ステートメントを追跡します。 そして、同一の設定を誤って何度も追加しようとしたり、両方のステートメント を同時に有効にすることの意味を Pyramid が理解できない場合、スタートアップ 時に派手に文句を言うでしょう。しかしながら、それは愚かではありません: 設定 include() システムを使えば、 矛盾する設定ステートメントを自動的に解決してくれます: 「ローカルな」ステートメントは「ローカルでない」ものより優先されます。 これは、賢い方法で大規模なシステムをより小さなシステムの要素として 含めることを可能にします。

例: 衝突検知

設定の拡張可能性

他のシステムと異なり、 Pyramid は構造化された「インクルード」メカニズムを 提供します (include() を参照)。 それは複数の Python パッケージからアプリケーションを構成することを可能 にします。ビューやルート、 (イベントの) サブスクライバー、および認証と認可ポリシーの追加など、 「メイン」 Pyramid アプリケーションで行なうことができるすべての設定 ステートメントはインクルードされたパッケージでも行なうことができます。 別のアプリケーションの設定をあなたのアプリケーションにインクルードして、 オーバーライドしたり新しいビューやルートを追加したりすることで、さらに 既存のアプリケーションを拡張またはオーバーライドすることができます。 これには、大きなアプリケーションを他の多くのより小さなアプリケーション から構成できる可能性があります。例えば、既に沢山のルートを持つ既存の アプリケーションを再利用したければ、単純に route_prefix を付けて include ステートメントを使用することができます; 新しいアプリケーション はあなたのアプリケーション内の URL プリフィックスで動作するようになります。 それはたいしたことではなく、事前の技術的努力をほとんど必要としません。

例えば:

1
2
3
4
5
6
7
from pyramid.config import Configurator

if __name__ == '__main__':
   config = Configurator()
   config.include('pyramid_jinja2')
   config.include('pyramid_exclog')
   config.include('some.other.guys.package', route_prefix='/someotherguy')

外部ソースからの設定インクルード拡張可能なアプリケーションを構築するためのルール も 参照してください。

柔軟な認証と認可

Pyramid は柔軟でプラグイン可能な認証と認可のシステムを含んでいます。 ユーザデータがどこに保存されるか、ユーザがデータにアクセスするのを許可 するためにどんなスキームを使用するかに関わらず、カスタムの認証と認可の コードをプラグインするためにあらかじめ定義された Pyramid プラグポイント を使用することができます。後になってこれらのスキームを変更したければ、 コードのあちこちではなく、たった1ヶ所を変更するだけで済みます。さらに、 Pyramid には構築済みの十分テストされた認証および認可スキームが 最初から付属しています。でも、もし万が一 Pyramid の内蔵のシステムを 使いたくないとしたら? それを使う必要はありません。他のシステムでするように あなた自身の特注のセキュリティコードを書くことができます。

例: Enabling an Authorization Policy

トラバーサル

TraversalZope から盗まれた概念です。それは各々の リソースが 複数の URL から参照されるリソースツリーを作成することを可能 にします。各々のリソースはそれに関連付けられた複数の ビュー を持つこと ができます。データが自然にはツリーのようでない場合 (あるいは、データの ツリー状の表現を作成したくない場合)、トラバーサルは非常に有用であるとは感じ られないかもしれません。しかし、任意に拡張可能である必要のあるサイトで は、トラバーサルは間違いなく fantastic です: ツリーにノードを加えるのは、 ルートを他のルートの順序付きリストに押し込めたり、一部門をサービスする のにアプリケーション全体の別のインスタンスを作成して異種のアプリケーション がデータを共有するためのグルーコードを作成することよりも、ずっと簡単です。 それは、コンテンツ管理システムやドキュメント管理システムのような、 本質的に部門の階層の変更が発生しがちなサイトには非常に適しています。 トラバーサルは、さらに非常に細かい粒度のセキュリティ(「ボブはドキュメント を編集することができる」に対して「ボブは この ドキュメントを編集する ことができる」)を要求するシステムにも向いています

例: Hello Traversal WorldMuch Ado About Traversal

Tweens

Pyramid には、 “tween” と呼ばれる任意のアドオンによってフックすること ができる一種の内部 WSGI ミドルウェア的なパイプラインがあります。 デバッグ ツールバーは “tween” です。 pyramid_tm トランザクション管理もそうです。 tween は Pyramid 自身のコンテキスト内で実行されるので、いくつかの状況 で WSGI ミドルウェアより有用です。これは、テンプレートと他のレンダラー、 「本物の」 request オブジェクトや、その他の細々したものにアクセスできる ことを意味しています。

例: “tween” の登録

ビューレスポンスアダプタ

様々なフレームワークで、ビュー callable からどんな 種類 のオブジェクト を返すことが認められるかに関する哲学から多くのことが作られています。 このドキュメントの前のセクションでは、 renderer を使用すれば 通常はビュー callable から完全な Response オブジェクトの代わりに 辞書を返すことができることを示しました。しかし、いくつかのフレームワーク では、ビュー callable から文字列またはタプルを返すことができます。 フレームワークがこれを許している場合、必要なインポートがより少なくなるので コードはわずかにきれいに見えます。また、コード量は少なくなります。 例えば、これと:

1
2
def aview(request):
    return "Hello world!"

これを比較してください:

1
2
3
4
from pyramid.response import Response

def aview(request):
    return Response("Hello world!")

前者の方が「きれい」です。そうですね。

初期状態では、 Pyramid で前者のビュー callable (単に文字列を返すもの) を定義すると実行時に例外が発生します。これは、「暗黙的より明示的な方が 良い」という理由です。ほとんどの場合、そしてデフォルトでは、 Pyramid は ビュー callable から Response オブジェクトが返されることを期待 します。これは、レスポンスオブジェクトには通常単なるボディよりもずっと 多くの情報が含まれているからです。しかし、あなたがそのような美学を評価する タイプの人なら、この種のことを可能にする簡単な方法があります:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from pyramid.config import Configurator
from pyramid.response import Response

def string_response_adapter(s):
    response = Response(s)
    response.content_type = 'text/html'
    return response

if __name__ == '__main__':
    config = Configurator()
    config.add_response_adapter(string_response_adapter, basestring)

あなたの Pyramid アプリケーションでスタートアップ時にそれを一度してくだ さい。すると、任意のビュー callable から文字列を返すことができます。 例えば:

1
2
3
4
5
def helloview(request):
    return "Hello world!"

def goodbyeview(request):
    return "Goodbye world!"

おっと! もしカスタムなコンテントタイプを指定したかったら どうしますか? カスタムなステータスコードは? 心配ありません。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from pyramid.config import Configurator

def tuple_response_adapter(val):
    status_int, content_type, body = val
    response = Response(body)
    response.content_type = content_type
    response.status_int = status_int
    return response

def string_response_adapter(body):
    response = Response(body)
    response.content_type = 'text/html'
    response.status_int = 200
    return response

if __name__ == '__main__':
    config = Configurator()
    config.add_response_adapter(string_response_adapter, basestring)
    config.add_response_adapter(tuple_response_adapter, tuple)

一旦これが終われば、これらのビュー callable は両方とも動くでしょう:

1
2
3
4
5
def aview(request):
    return "Hello world!"

def anotherview(request):
    return (403, 'text/plain', "Forbidden")

それが最も一般に有用なので、Pyramid はデフォルトでは明示的に振る舞いますが、 Pyramid はフレームワークを局所的な審美的要望に適応させるためのフックを提供します。

Pyramid がビューレスポンスを扱う方法の変更 も参照してください。

「グローバル」レスポンスオブジェクト

「ビュー callable でレスポンスオブジェクトを構築するなんて雑用はたくさん! それに、前のセクションのようにレスポンスアダプタを登録するのも面倒」 とあなたは言います。よろしい。そのようにしてください:

1
2
3
4
5
def aview(request):
    response = request.response
    response.body = 'Hello world!'
    response.content_type = 'text/plain'
    return response

Varying Attributes of Rendered Responses も参照してください。

反復的設定の自動化

Pyramid の configurator だけでできることがあったとして、少し挑戦的に、 もっと冗長でないことを望みますか? あるいは、ある手軽な設定機能を Pyramid を 変更することを要求せずに他の Pyramid ユーザに届けたいですか? Pyramid Configurator を拡張して自分のディレクティブを追加することができます。 例えば、 pyramid.config.Configurator.add_view() を 繰り返し呼んでいることに気づいたとします。通常、既存のショートカットを 使用することにより退屈な作業を取り除くことができます。しかし、これが 退屈な作業を取り除くために既存のショートカットが働かないような場合で あるとしましょう:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from pyramid.config import Configurator

config = Configurator()
config.add_route('xhr_route', '/xhr/{id}')
config.add_view('my.package.GET_view', route_name='xhr_route',
                xhr=True,  permission='view', request_method='GET')
config.add_view('my.package.POST_view', route_name='xhr_route',
                xhr=True, permission='view', request_method='POST')
config.add_view('my.package.HEAD_view', route_name='xhr_route',
                xhr=True, permission='view', request_method='HEAD')

かなり退屈ですよね? この単調な作業のうちのいくらかを自動化するために Pyramid configurator にディレクティブを加えることができます:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from pyramid.config import Configurator

def add_protected_xhr_views(config, module):
    module = config.maybe_dotted(module)
    for method in ('GET', 'POST', 'HEAD'):
        view = getattr(module, 'xhr_%s_view' % method, None)
        if view is not None:
            config.add_view(view, route_name='xhr_route', xhr=True,
                           permission='view', request_method=method)

config = Configurator()
config.add_directive('add_protected_xhr_views', add_protected_xhr_views)

それが一旦終われば、たった今追加したディレクティブをConfigurator オブジェクトのメソッドとして呼ぶことができます:

1
2
config.add_route('xhr_route', '/xhr/{id}')
config.add_protected_xhr_views('my.package')

以前の反復的な設定行は、今や1行に変形しました。

設定コードをパッケージにして、他のユーザがあなたのコードに対する include() メソッドを使用する時に 呼ばれる関数の内部で add_directive() を 呼ぶことにより、この方法で設定コードを他人と共有することもできます。

add_directive による Configurator へのメソッドの追加 も参照してください。

テスト

Pyramid のすべてのリリースは、ユニットテストと統合テストによって 100% のステートメントカバレッジを持ちます。これは PyPI で入手可能な coverage ツールによって測定されています。さらに、 PyPI で利用可能な instrumental ツールによる測定で 95% 以上の decision/condition カバレッジを持ちます。それは GitHub リポジトリのそれぞれのコミットの後で Jenkins ツールによって Python 2.6, Python 2.7, Python 3.2, PyPy 上で 自動的にテストされます。公式の Pyramid アドオンは同様のテスト基準に 保たれます。 Pyramid およびその公式アドオンには今もバグが見つかりますが、 私たちは良いテストを行う regime (体制) を持たない他のプロジェクトで働いている間に、 バグがより多く見つかることに気づきました。

例: http://jenkins.pylonsproject.org/

サポート

私たちのゴールは、答えられない Pyramid に関する質問がないことです。 IRC や Pylons-discuss メーリングリスト、あるいは StackOverflow のいずれか で質問をしても、合理的に迅速なレスポンスが得られるでしょう。私たちは、 “support trolls” あるいは様々な公式のサポートチャンネルにおいて仲間の ユーザを非難することに喜びを見い出すような人々を許容しません。 私たちは、そこを well-lit (明るく照らされた)、新規ユーザーに優しい場所に保とうとしています。

例: irc://freenode.net#pyramid (IRC クライアント中では irc.freenode.net の #pyramid チャンネル) や pylons-discuss メーリング リスト http://groups.google.com/group/pylons-discuss/ を訪ねてください。

ドキュメント

それは絶え間ない努力です。しかし、私たちは公式の narrative Pyramid ドキュメンテーションの中で完全性と新規ユーザーフレンドリーの間のバランスを 維持しようとします (それはそれとして、具体的な改善提案は常に感謝されます)。 さらに、私たちはレシピの「クックブック」も維持します。それらは通常、よく ある統合シナリオのデモンストレーションで、公式 narrative ドキュメントに 追加するには特殊すぎるものです。どんな場合も、 Pyramid ドキュメンテーション は包括的です。

例: このドキュメントの残りとクックブック http://docs.pylonsproject.org/projects/pyramid_cookbook/dev/

Pylons プロジェクトとは?

Pyramid は Pylons プロジェクトの下で公開されたソフトウェアコレク ションのメンバーです。Pylons ソフトウェアは、貢献者が緩く結合したコミュ ニティーによって書かれています。 Pylons プロジェクトのウェブサイト には、 Pyramid と Pylons プロジェクト の関係についての詳細があります。

Pyramid と他のウェブフレームワーク

Pyramid の前身 (repoze.bfg という名前) の最初のリリースは 2008 年の 7 月に行われました。 2010 年の終わりに、私たちは repoze.bfg の名前を Pyramid に変更しました。そしてその年の 11 月に Pyramid として Pylons プロジェクトへと合併されました。

Pyramid は、 Zope, Pylons (バージョン 1.0), Django にインスパイアされました。その結果、 Pyramid は 各々からいくつかの概念や機能を借りると同時にそれらを組み合わせて ユニークなウェブフレームワークになっています。

Pyramid の多くの特徴は、その起源を Zope までさかのぼるこ とができます。 Zope アプリケーションと同様、 Pyramid アプリケー ションは容易に拡張することができます: ある制約に従って作れば、あなたの アプリケーションをサードパーティの開発者が元のアプリケーションをフォー クすることなく、再利用したり、修正したり、再統合したり、拡張したりする ことができます。 Pyramid の中の traversal および宣言的な セキュリティの概念は、Zopeの中で最初に開拓されました。

PyramidURL dispatch 概念は、 Pylons バージョン 1.0 で使用される Routes システムによってインスパイアされました。 Pylons バージョン 1.0 のように、 Pyramid はほぼポリシーフリーです。 それは、どのデータベースを使用すべきといった主張をせず、内蔵のテンプレート 機能は利便性のためにのみ含まれています。本質的には、それは単に URL を view コードにマッピングするためのメカニズムと、それらのビューを 呼び出すための規約一式を提供します。アプリケーションの中であなたのニーズに 合ったサードパーティのコンポーネントを自由に使用することができます。

Pyramid によって使用される view の概念は、ほとんど Django のそれと同じです。 Pyramid には Zope よりもむしろ Django のような ドキュメンテーション文化があります。

Pylons バージョン 1.0 のように、しかし Zope とは違い、 Pyramid アプリケーション開発者は、ビューやルートを追加するような よくあるフレームワーク設定タスクを行なうために完全に命令的なコードを 使用することができます。Zope では、同様の目的のために典型的に ZCML が必要です。 Grok という Zope に基づくウェブフレーム ワークの中では、この目的のために decorator オブジェクトとクラス レベル宣言が使用されます。初期状態で、 Pyramid は命令的な設定とデコレータ に基づいた設定をサポートします; ZCMLpyramid_zcml という 名前のアドオンパッケージによって使用することができます。

Zope とは異なり、また Django のような他の「フルスタック」 のフレームワークと異なり、 Pyramid は、アプリケーションを構築す るためにどの永続化メカニズムを使用すべきかに関する前提を置きません。 Zope アプリケーションは、典型的に ZODB に依存しています; Pyramid を使って ZODB アプリケーションを構築することは できますが、 ZODB ソフトウェアに対する依存はありません。 同様に、 Django はアプリケーションのデータをリレーショナル データベースに格納すると仮定する傾向にありますが、 Pyramid は そのような仮定をしません; それは、あなたがリレーショナルデータベースを 使用することを可能にしますが、決定に賛成も反対もしません。

他の Python ウェブフレームワークは、 model-view-controller フレームワークと いう名前のウェブフレームワークのクラスのメンバーとして自己宣伝しています。 この用語がウェブフレームワークのクラスを表わすために主張される限りにおいて Pyramid も一般にこのクラスに入ります。