2013年2月4日月曜日

Bottleのレシピ


Bottleのレシピ

これは、コードスニペットと一般的なユースケースの例のコレクションです。

セッションの追跡

(マイクロフレームワークで)それをする正しい方法はありませんので、ありませんセッションのサポートを内蔵しています。 要件や環境によっては、フィッティングエンドとビーカーのミドルウェアを使用するか、自分でそれを実装することができます。ここでは、ファイルベースのバックエンドを持つビーカーセッションの例は、次のとおりです。
import bottle
from beaker.middleware import SessionMiddleware

session_opts = {
    'session.type': 'file',
    'session.cookie_expires': 300,
    'session.data_dir': './data',
    'session.auto': True
}
app = SessionMiddleware(bottle.app(), session_opts)

@bottle.route('/test')
def test():
  s = bottle.request.environ.get('beaker.session')
  s['test'] = s.get('test',0) + 1
  s.save()
  return 'Test counter: %d' % s['test']

bottle.run(app=app)

スタイルでのデバッグ:デバッグミドルウェア

ボトルは、クラッシュからWSGIサーバを防ぐために、あなたのアプリケーションコード内で発生したすべての例外をキャッチします。組み込みのdebug()モードでは十分ではありませんし、デバッグのミドルウェアに伝播する例外が必要な場合は、この動作をオフにすることができます。
import bottle
app = bottle.app()
app.catchall = False #Now most exceptions are re-raised within bottle.
myapp = DebuggingMiddleware(app) #Replace this with a middleware of your choice (see below)
bottle.run(app=myapp)
今、ボトルだけで独自の例外をキャッチ(HTTPError、HttpResponseとBottleException)とミドルウェアが残りを処理することができます。
非常に強力なデバッグWSGIミドルウェアとwerkzeug&ペーストライブラリが両方同梱されています。 ペーストのwerkzeugとpaste.evalexception.middleware.EvalExceptionためwerkzeug.debug.DebuggedApplicationを見てみましょう。 それら両方はスタックを検査を行うことができ、さらに、スタックのコンテキスト内でのpythonコードを実行するので 、生産にそれらを使用しないでください。

ユニット·テスト·ボトルアプリケーション

ユニット·テストは通常、WSGI環境を実行せずにWebアプリケーションで定義されているメソッドに対して実行されます。
単純な例では、Noseを使用して:
import bottle

@bottle.route('/')
def index():
    return 'Hi!'

if __name__ == '__main__':
    bottle.run()
Test script:
import mywebapp

def test_webapp_index():
    assert mywebapp.index() == 'Hi!'
例では、Bottleのroute()メソッドが実行されることはありません - index()はテストされています。

機能テストボトルアプリケーション

任意のHTTPベースのテストシステムは、実行中のWSGIサーバで使用されますが、いくつかのテストフレームワークがWSGIとより緊密に連携し、トレースバック機能とデバッグツールを駆使して制御された環境でコールWSGIアプリケーションを提供することができます。 WSGIのテストツールは良い出発点です。
from webtest import TestApp
import mywebapp

def test_functional_login_logout():
    app = TestApp(mywebapp.app)

    app.post('/login', {'user': 'foo', 'pass': 'bar'}) # log in and get a cookie

    assert app.get('/admin').status == '200 OK'        # fetch a page successfully

    app.get('/logout')                                 # log out
    app.reset()                                        # drop the cookie

    # fetch the same page, unsuccessfully
    assert app.get('/admin').status == '401 Unauthorized'

他のWSGIアプリを埋め込む

これは、おすすめの方法(あなたがこれを行うには、ボトルの前で、ミドルウェアを使用する必要があります)ではありませんが、あなたのボトルのアプリ内から他のWSGIアプリケーションを呼び出して、擬似ミドルウェアとしてボトルの行為をさせることができます。次に例を示します。
from bottle import request, response, route
subproject = SomeWSGIApplication()

@route('/subproject/:subpath#.*#', method='ALL')
def call_wsgi(subpath):
    new_environ = request.environ.copy()
    new_environ['SCRIPT_NAME'] = new_environ.get('SCRIPT_NAME','') + '/subproject'
    new_environ['PATH_INFO'] = '/' + subpath
    def start_response(status, headerlist):
        response.status = int(status.split()[0])
        for key, value in headerlist:
            response.add_header(key, value)
    return app(new_environ, start_response)
繰り返しますが、これはサブプロジェクトを実装するためのお勧めの方法ではありません。多くの人々は、このために要請し、WSGIにどのようにボトルの地図を表示するので、ここだけです。

末尾のスラッシュを無視する

ボトル/exampleと/example/ 2つの異なる経路である[1]。両方のURLを同じに扱うためには、2つの@ルートデコレータを追加することができます。
@route('/test')
@route('/test/')
def test(): return 'Slash? no?'
またはWSGIミドルウェアを追加してすべてのURLから末尾のスラッシュをストリップ。
class StripPathMiddleware(object):
  def __init__(self, app):
    self.app = app
  def __call__(self, e, h):
    e['PATH_INFO'] = e['PATH_INFO'].rstrip('/')
    return self.app(e,h)

app = bottle.app()
myapp = StripPathMiddleware(app)
bottle.run(app=myapp)
脚注 [1]それらはあるので。 <http://www.ietf.org/rfc/rfc3986.txt>を参照してください。

キープアライブ要求

注意

詳細な説明については、非同期アプリケーションへの入門を参照してください。
マルチXHRのようないくつかの"Push"メカニズムは、レスポンスヘッダと一緒に接続を閉じずに、応答データを書き込む機能が必要"Connection: keep-alive"。 WSGIは、この動作を容易に自分自身を貸すわけではありませんが、gevent非同期フレームワークを使用して、ボトルでそうすることも可能です。ここでgevent HTTPサーバまたはペーストHTTPサーバ(これは他の人と動作する可能性がありますが、私は試していません)のいずれかで動作するサンプルです。単にサーバーを変更するserver='gevent'とserver='paste'とユーザが貼り付けたサーバーを使用する:
from gevent import monkey; monkey.patch_all()

import time
from bottle import route, run

@route('/stream')
def stream():
    yield 'START'
    time.sleep(3)
    yield 'MIDDLE'
    time.sleep(5)
    yield 'END'

run(host='0.0.0.0', port=8080, server='gevent')
あなたがhttp://localhost:8080/streamを参照する場合、あなたは、"START" "MIDDLE"、と'END'の時間(むしろ一度にすべてを見るために8秒を待っているよりも)少なくとも一つを表示されるはずです。

ボトルのgzip圧縮

注意

詳細については、圧縮を参照してください。
要求時に静的リソース(CSSやJSファイルなど)を圧縮することで、サイトをスピードアップGzip圧縮をサポートするために、ボトルに共通の機能要求である。
Gzip圧縮をサポートするには、コーナー·ケースの数は頻繁にその作物アップのために単純な命題ではありません。適切なGzipでの実装を行う必要があります。
  • オンザフライで圧縮し、高速そうすることができます。
  • それをサポートしていないブラウザのために圧縮されません。
  • (画像、ビデオ)は、既に圧縮されているファイルを圧縮しないでください。
  • 動的なファイルを圧縮しないでください。
  • サポート2つ(GZIPおよびDeflate)圧縮アルゴリズムを異なっていた。
  • 頻繁に変更されませんキャッシュの圧縮ファイル。
  • いずれかのファイルが変更された場合はとにかくキャッシュを非検証します。
  • キャッシュが大きいに到達しないことを確認してください。
  • シークディスクがオンザフライ圧縮よりも長くかかるため、小さなファイルをキャッシュしません。
これらの要件から、それはgzip圧縮が最高のWSGIサーバのボトルの上で動作によって処理されているボトルプロジェクトの勧告です。そのようなCherryPyはなどのWSGIサーバはこれを達成するために使用することができGzipFilterミドルウェアを提供しています。

フックプラグインを使用して

あなたのURLのすべてによって返されたコンテンツのクロスオリジンリソースの共有を許可する場合たとえば、あなたはフックデコレータを使用してコールバック関数を設定することができます。
from bottle import hook, response, route

@hook('after_request')
def enable_cors():
    response.headers['Access-Control-Allow-Origin'] = '*'

@route('/foo')
def say_foo():
    return 'foo!'

@route('/bar')
def say_bar():
    return {'type': 'friendly', 'content': 'Hi!'}
また、すべての関数が呼び出される前にアクションを取ることbefore_callbackを使用することができます。

Herokuのとボトルを使用して

Herokuの、人気の高いクラウド·アプリケーション·プラットフォームは、今ではinfastructureでPythonアプリケーションを実行するためのサポートを提供しています。
このレシピは置き換えボトル固有のコードで、Herokuのクイックスタートに基づいていますHeroku/シーダーガイドのPython入門のあなたのアプリケーションのセクションを記述します。
import os
from bottle import route, run

@route("/")
def hello_world():
        return "Hello World!"

run(host="0.0.0.0", port=int(os.environ.get("PORT", 5000)))
Herokuのアプリのスタックは、アプリケーションがos.environ辞書を使用して、要求をlistenするために必要なポートを渡します。

0 件のコメント:

コメントを投稿