イベントの使用

イベント は、アプリケーションのライフタイムにおける興味深いポイントで Pyramid フレームワークによって通知されるオブジェクトです。 ほとんどの Pyramid アプリケーションでは、その作成においてイベントを使う 必要はありませんが、多少なりとも高度な操作を行ないたい場合、それらは 有用です。例えば、イベントの通知を受け取ることによって、すべての新しい リクエストの結果としてあるコードを実行したりすることができます。

Pyramid において、イベントはフレームワークによって常に通知されます。 しかし、それらは subscriber を登録する場合にのみ有用になります。 subscriber は event という名前の単一の引数を受け取る関数です:

1
2
def mysubscriber(event):
    print event

上記は、呼び出されると単にコンソールにイベントを表示する subscriber です。

しかし、 subscriber 関数が単に存在するだけでは、それが呼び出されるように なるのに十分ではありません。subscriber が呼び出されるようにするために、 pyramid.config.Configurator.add_subscriber() メソッドを使用するか、 あるいは pyramid.events.subscriber() デコレータを使用して scan によって検索される関数をデコレートする必要があります。

イベントリスナーを命令的に設定する

あるイベントタイプに対して呼ばれる subscriber 関数を add_subscriber() メソッドによって 命令的に設定することができます (Configurator も参照):

1
2
3
4
5
6
7
8
from pyramid.events import NewRequest

from subscribers import mysubscriber

# "config" below is assumed to be an instance of a
# pyramid.config.Configurator object

config.add_subscriber(mysubscriber, NewRequest)

add_subscriber() に対する第1引数は subscriber 関数 (あるいは subscriber callable を指す dotted Python name) です; 第2引数はイベントタイプです。

デコレータを使用してイベントリスナーを設定する

あるイベントタイプに対して呼ばれる subscriber 関数を pyramid.events.subscriber() 関数によって設定することができます。

1
2
3
4
5
6
from pyramid.events import NewRequest
from pyramid.events import subscriber

@subscriber(NewRequest)
def mysubscriber(event):
        event.request.foo = 1

subscriber() デコレータが使用される場合、 デコレータが効果も発揮するために、デコレートされた関数を含むパッケージに 対して scan が行なわれなければなりません。

上記どちらの登録例でも、 Pyramid フレームワークが pyramid.events.NewRequest インターフェースを提供するイベント オブジェクトを emit するときは常に mysubscriber 関数が event オブジェクトを伴って呼ばれるようになります。

見て分かるように、 subscriber の登録は (pyramid.events.NewResponse のような) クラス の観点からなされます。 subscriber のもとへ送られた イベントオブジェクトは常に interface を所有するオブジェクトに なります。 pyramid.events.NewResponse については、その インタフェースは pyramid.interfaces.INewResponse です。 インタフェースのドキュメントは、イベントオブジェクトの利用可能な属性と メソッドに関する情報を提供しています。

subscriber 関数の戻り値は無視されます。同じイベントタイプに対する複数の subscriber が、お互いに対して相対的になんらかの特定の順番で呼ばれること は保証されません。

すべての具体的な Pyramid イベントタイプは、 pyramid.events API ドキュメンテーションの中で文書化されます。

アプリケーション内の subscribers.py ファイルに、次のように イベントリスナー関数を作成する場合:

1
2
3
4
5
def handle_new_request(event):
    print 'request', event.request

def handle_new_response(event):
    print 'response', event.response

アプリケーションの初期設定部に次のコードを加えることにより、 これらの関数が適切なタイミングで呼ばれるように設定することができます:

1
2
3
4
5
6
# config is an instance of pyramid.config.Configurator

config.add_subscriber('myproject.subscribers.handle_new_request',
                      'pyramid.events.NewRequest')
config.add_subscriber('myproject.subscribers.handle_new_response',
                      'pyramid.events.NewResponse')

どちらのメカニズムも subscribers.py の中の関数をイベント subscriber として登録します。この設定の下でアプリケーションが実行された 場合、新しいリクエストまたはレスポンスが検知されるごとにコンソールに メッセージが表示されるようになります。

これらの subscriber 関数は、 event オブジェクトを受け取ってイベント オブジェクトの属性を表示します。これは次の質問を避けています: 特定の イベントがどんな属性を持っているか、どのようにして知ることができますか。

pyramid.events.NewRequest イベントオブジェクトが request 属性を持っていることを私たちは知っています。それは request オブジェクトです。なぜなら pyramid.interfaces.INewRequest で インタフェースがそのように定義されているからです。同様に、 pyramid.interfaces.NewResponse のイベントが response 属性を 持っていることを私たちは知っています。それはアプリケーションによって 構築されたレスポンスオブジェクトです。なぜなら pyramid.interfaces.INewResponse でインタフェースがそのように 定義されているからです (pyramid.events.NewResponse オブジェクトは request も持っています)。