新しいリリースへのアップグレード—フラスコのドキュメント

提供:Dev Guides
< FlaskFlask/docs/1.0.x/upgrading
移動先:案内検索

新しいリリースへのアップグレード

Flask自体は、他のソフトウェアが時間とともに変化しているように変化しています。 ほとんどの変更は素晴らしい種類であり、新しいリリースから利益を得るためにコード内で何も変更する必要がない種類です。

ただし、コードの変更が必要な変更や、Flaskの新機能を利用して独自のコード品質を向上させることができる変更がときどきあります。

ドキュメントのこのセクションでは、リリースごとのFlaskのすべての変更と、コードを変更して簡単に更新できるようにする方法を列挙しています。

pip コマンドを使用して、--upgradeパラメーターを指定することにより、既存のFlaskインストールをアップグレードします。

$ pip install --upgrade Flask

バージョン0.12

send_fileへの変更

filenameは、ファイルのようなオブジェクトから自動的に推測されなくなりました。 これは、次のコードが自動的にX-Sendfileのサポート、etag生成、またはMIMEタイプの推測を行わなくなることを意味します。

response = send_file(open('/path/to/file.txt'))

次のいずれも機能的に同等です。

fname = '/path/to/file.txt'

# Just pass the filepath directly
response = send_file(fname)

# Set the MIME-type and ETag explicitly
response = send_file(open(fname), mimetype='text/plain')
response.set_etag(...)

# Set `attachment_filename` for MIME-type guessing
# ETag still needs to be manually set
response = send_file(open(fname), attachment_filename=fname)
response.set_etag(...)

これは、ファイルのようなオブジェクトの中には、無効または誤解を招くname属性を持っているものがあるためです。 このような場合にエラーを黙って飲み込むことは、満足のいく解決策ではありませんでした。

さらに、application/octet-streamへのフォールバックのデフォルトが制限されています。 Flaskが推測できないか、ユーザーが提供しなかった場合、ファイル名情報が提供されていないと関数は失敗します。


バージョン0.11

0.11は、1.0リリースであると想定されていたため、Flaskリリースサイクルの奇妙なリリースです。 ただし、リリースまでのリードタイムが非常に長いため、移行を容易にするためにいくつかの変更を削除して、最初に0.11リリースをプッシュすることにしました。 1.0であったマスターブランチを追跡している場合、予期しない変更が発生する可能性があります。

マスターブランチを追跡した場合、 Flask --app が削除されていることに気付くでしょう。 アプリケーションを指定するには、環境変数を使用する必要があります。

デバッグ

Flask 0.11は、Flaskアプリケーションからdebug_log_format属性を削除しました。 代わりに、新しいLOGGER_HANDLER_POLICY構成を使用して、デフォルトのログハンドラーを無効にし、カスタムログハンドラーを設定できます。


エラー処理

エラーハンドラの動作が変更されました。 ハンドラーの優先順位は、それぞれerrorhandler()register_error_handler()の装飾/呼び出し順序に基づいていました。 現在、継承階層が優先され、より一般的な例外クラスではなく、より具体的な例外クラスのハンドラーが実行されます。 詳細については、エラーハンドラーを参照してください。

インスタンスにハンドラーを登録しようとすると、ValueErrorが発生するようになりました。

ノート

以前は、例外インスタンスに対してのみハンドラーを登録できる論理エラーがありました。 これは意図せず、明らかに間違っていたため、例外クラスとHTTPエラーコードのみを使用してハンドラーを登録するという意図された動作に置き換えられました。


テンプレート

render_template_string()関数は、デフォルトでテンプレート変数を自動エスケープするように変更されました。 これは、render_template()の動作とよりよく一致します。


拡張機能のインポート

flask.ext.foo形式の拡張機能のインポートは非推奨です。flask_fooを使用する必要があります。

古いフォームは引き続き機能しますが、Flaskは、古い方法でインポートした拡張機能ごとにflask.exthook.ExtDeprecationWarningを発行します。 また、 Flask-ext-migrate と呼ばれる移行ユーティリティも提供しています。これは、このためにインポートを自動的に書き換えることになっています。


バージョン0.10

0.9から0.10への最大の変更は、Cookieのシリアル化形式がpickleから特殊なJSON形式に変更されたことです。 この変更は、秘密鍵が漏洩した場合に攻撃者が与える可能性のある損害を回避するために行われました。 アップグレードすると、2つの大きな変更があります。アップグレード前に発行されたすべてのセッションが無効になり、セッションに保存できるタイプの数は限られています。 新しいセッションは、HTMLマークアップを使用したタプルと文字列に対して、いくつかの小さな拡張機能を備えたJSONのみを許可するように設計上はるかに制限されています。

人々のセッションを中断しないために、 Flask-OldSessions 拡張機能を使用して古いセッションシステムを引き続き使用することができます。

また、Flaskは、 flask.g オブジェクトをリクエストコンテキストではなくアプリケーションコンテキストに保存し始めました。 この変更は透過的である必要がありますが、リクエストコンテキストがまだなく、アプリケーションコンテキストがある場合でも、gオブジェクトに保存できるようになりました。 古いflask.Flask.request_globals_class属性はflask.Flask.app_ctx_globals_classに名前が変更されました。


バージョン0.9

関数からタプルを返す動作が単純化されました。 タプルを返すと、作成している応答オブジェクトの引数が定義されなくなり、常に(response, status, headers)の形式のタプルになり、少なくとも1つのアイテムを指定する必要があります。 古い動作に依存している場合は、Flaskをサブクラス化することで簡単に追加できます。

class TraditionalFlask(Flask):
    def make_response(self, rv):
        if isinstance(rv, tuple):
            return self.response_class(*rv)
        return Flask.make_response(self, rv)

以前に _request_ctx_stack を使用していた拡張機能を維持している場合、拡張機能に意味がある場合は、 _app_ctx_stack に変更することを検討してください。 たとえば、アプリのコンテキストスタックは、データベースに接続する拡張機能にとって意味があります。 リクエストコンテキストスタックの代わりにアプリコンテキストスタックを使用すると、拡張機能がリクエスト以外のユースケースをより簡単に処理できるようになります。


バージョン0.8

Flaskは新しいセッションインターフェースシステムを導入しました。 また、セッションを実装するモジュールflask.sessionとグローバルセッションオブジェクトである flask.session の間に名前の衝突があったことにも気づきました。 その導入により、セッションシステムの実装の詳細をflask.sessionsという新しいモジュールに移動しました。 以前に文書化されていないセッションサポートを使用した場合は、アップグレードすることをお勧めします。

無効なJSONデータが送信された場合、Flaskは、デフォルトのValueErrorをバブルアップさせる代わりに、BadRequest例外を発生させるようになりました。 これには、内部サーバーエラーがユーザーに表示されないようにするために、そのエラーを処理する必要がなくなるという利点があります。 過去にValueErrorとして明示的にこれをキャッチしていた場合は、これを変更する必要があります。

テストクライアントのバグのため、テストクライアントがwithステートメントで使用された場合、Flask0.7はティアダウンハンドラーをトリガーしませんでした。 これは修正されたためですが、この動作に依存している場合は、テストスイートでいくつかの変更が必要になる可能性があります。


バージョン0.7

Flask 0.7では、コードベースを内部的に大幅にクリーンアップし、Flaskを使用してより大きなアプリケーションを実装しやすくするために、後方互換性のない変更をいくつか行いました。 アップグレードをできるだけ簡単にしたいので、移行を容易にするスクリプトを提供することで、これらの変更から生じる問題に対処しようとしました。

スクリプトはアプリケーション全体をスキャンし、安全に適用できると想定する変更を加えた統一された差分を生成します。 ただし、これは自動化されたツールであるため、すべてのユースケースを見つけることができず、一部を見逃す可能性があります。 アップグレードできなかったコードを簡単に見つけられるように、社内で多くの非推奨の警告を広めました。

生成されたパッチファイルを手作業で確認し、見栄えの良いチャンクのみを適用することを強くお勧めします。

プロジェクトのバージョン管理システムとしてgitを使用している場合は、path -p1 < patchfile.diffでパッチを適用してから、インタラクティブなコミット機能を使用して、見栄えの良いチャンクのみを適用することをお勧めします。

アップグレードスクリプトを適用するには、次の手順を実行します。

  1. スクリプトをダウンロードします: flask-07-upgrade.py

  2. アプリケーションのディレクトリで実行します。

    python flask-07-upgrade.py > patchfile.diff
  3. 生成されたパッチファイルを確認します。

  4. パッチを適用します。

    patch -p1 < patchfile.diff
  5. モジュールごとのテンプレートフォルダを使用していた場合は、いくつかのテンプレートを移動する必要があります。 以前は、adminという名前のブループリントの横にtemplatesという名前のフォルダーがある場合、templates/index.htmlという名前のテンプレートファイルの暗黙的なテンプレートパスは自動的にadmin/index.htmlでした。 これはもはや当てはまりません。 次に、テンプレートにtemplates/admin/index.htmlという名前を付ける必要があります。 ツールはこれを検出しないため、自分で行う必要があります。

Python 2.7以降、非推奨の警告はデフォルトで無効になっていることに注意してください。 発生する可能性のある非推奨の警告を確認するには、warningsモジュールで警告を有効にする必要があります。

Windowsで作業していて、patchコマンドラインユーティリティがない場合は、cygwin、msysgit、ming32などのWindows用のさまざまなUnixランタイム環境の一部として入手できます。 また、svn、hg、gitなどのソース管理システムには、ツールによって生成された統合差分を適用するためのサポートが組み込まれています。 詳細については、バージョン管理システムのマニュアルを確認してください。

リクエストローカルのバグ

以前の実装のバグにより、リクエストローカルプロキシは、バインドされていないときにAttributeErrorではなくRuntimeErrorを発生させるようになりました。 以前にAttributeErrorでこれらの例外をキャッチした場合は、今すぐRuntimeErrorでキャッチする必要があります。

さらに、Flask 0.11で削除される機能に依存している場合、send_file()関数が非推奨の警告を発行するようになりました。 以前は、ファイルオブジェクトが渡されたときにetagとmimetypeを使用することが可能でした。 これは信頼性が低く、いくつかのセットアップで問題が発生しました。 非推奨の警告が表示された場合は、アプリケーションを更新して、そこにあるファイル名で動作するようにするか、etag添付を無効にして自分で添付してください。

古いコード:

return send_file(my_file_object)
return send_file(my_file_object)

新しいコード:

return send_file(my_file_object, add_etags=False)

新しい分解処理へのアップグレード

リクエスト処理のためのコールバックの動作を合理化しました。 応答を変更するものについては、after_request()デコレータは引き続き期待どおりに機能しますが、リクエストの最後に絶対に発生しなければならないものについては、新しいteardown_request()デコレータを導入しました。 残念ながら、その変更により、エラー状態ではアフターリクエストの動作も異なります。 例外が発生した場合に一貫してスキップされるわけではありませんが、以前はリクエストの最後に確実に実行されるように2回呼び出されていた可能性があります。

次のようなデータベース接続コードがある場合:

@app.after_request
def after_request(response):
    g.db.close()
    return response

代わりにこれを使用することをお勧めします。

@app.teardown_request
def after_request(exception):
    if hasattr(g, 'db'):
        g.db.close()

利点として、この変更により、内部コードフローが大幅に改善され、ディスパッチとエラー処理のカスタマイズが容易になります。 これにより、データベース接続の閉鎖をしばらく防ぐことができるため、単体テストの記述がはるかに簡単になります。 応答コンテキストがスタックから削除されたときにティアダウンコールバックが呼び出されるという事実を利用できるため、テストは要求の処理後にデータベースにクエリを実行できます。

with app.test_client() as client:
    resp = client.get('/')
    # g.db is still bound if there is such a thing

# and here it's gone

手動エラーハンドラーの添付

エラーハンドラーをFlask.error_handlersにアタッチすることは可能ですが、アタッチすることは推奨されておらず、実際には非推奨です。 一般に、任意の例外クラスとブループリントをサポートするためのより複雑な内部処理のため、基になるディクショナリに割り当てを介してアタッチするカスタムエラーハンドラーは推奨されなくなりました。 詳細については、Flask.errorhandler()を参照してください。

適切なアップグレードは、これを変更することです。

app.error_handlers[403] = handle_error

これに:

app.register_error_handler(403, handle_error)

または、デコレータを使用して関数をアタッチする必要があります。

@app.errorhandler(403)
def handle_error(e):
    ...

register_error_handler()はFlask0.7の新機能であることに注意してください)


ブループリントのサポート

ブループリントは、Flaskの「モジュール」の以前の概念を置き換えます。 これらは、さまざまな機能に対してより優れたセマンティクスを提供し、大規模なアプリケーションでより適切に機能します。 提供されている更新スクリプトは、アプリケーションを自動的にアップグレードできるはずですが、アップグレードに失敗する場合があります。 何が変わったの?

  • ブループリントには明示的な名前が必要です。 モジュールには、モジュールの短縮名がインポートモジュールの最後の部分から取得された自動名前推測スキームがありました。 アップグレードスクリプトはその名前を推測しようとしますが、この情報は実行時に変更される可能性があるため、失敗する可能性があります。
  • ブループリントは、url_for()に対して逆の動作をします。 以前、.foourl_for()に、アプリケーションでエンドポイントfooを探す必要があると伝えていました。 今では「現在のモジュールと比較して」という意味です。 スクリプトは、url_for()へのすべての呼び出しを自動的に取り消します。 これは非常に熱心な方法で行われるため、モジュールを使用していない場合は、コードに不要な先頭のドットが表示される可能性があります。
  • ブループリントは、静的フォルダーを自動的に提供しません。 また、場所の横にあるtemplatesというフォルダーからテンプレートを自動的にエクスポートすることもなくなりましたが、コンストラクターから有効にすることができます。 静的ファイルの場合と同じです。静的ファイルの提供を継続する場合は、コンストラクターに静的フォルダーへのパス(ブループリントのモジュールパスからの相対パス)を明示的に指示する必要があります。
  • テンプレートのレンダリングが簡素化されました。 これで、ブループリントは、一般的なテンプレート検索パスに追加されるテンプレートフォルダーを提供できます。 これは、テンプレート名としてblueprintname/template.htmlが必要な場合は、ブループリントの名前を持つ別のサブフォルダーをそのフォルダーに追加する必要があることを意味します。

非推奨のModuleオブジェクトを引き続き使用すると、Flaskは以前の動作を可能な限り良好に復元します。 ただし、ブループリントを複数回アタッチする機能、ブループリント固有のエラーハンドラーなど、多くの有用な改善が提供されるため、新しいブループリントにアップグレードすることを強くお勧めします。


バージョン0.6

Flask 0.6には、アフターリクエストハンドラーの順序に影響を与える後方互換性のない変更が付属しています。 以前は登録順に呼び出されていましたが、現在は逆の順序で呼び出されています。 この変更は、Flaskが期待どおりに動作するように、また他のシステムがリクエストの前処理と後処理を処理する方法に合わせて行われました。 ポストリクエスト機能の実行順序に依存する場合は、必ず順序を変更してください。

下位互換性を損なうもう1つの変更は、コンテキストプロセッサがテンプレートレンダリング関数に直接渡される値を上書きしなくなることです。 たとえば、requestが変数としてテンプレートに直接渡される場合、デフォルトのコンテキストプロセッサはそれを現在のリクエストオブジェクトでオーバーライドしません。 これにより、後でコンテキストプロセッサを拡張して、既存のテンプレートを予期せずに壊すことなく、追加の変数を挿入することが容易になります。


バージョン0.5

Flask 0.5は、単一のモジュールではなくPythonパッケージとして提供される最初のリリースです。 内部リファクタリングがいくつかあったため、文書化されていない内部の詳細に依存している場合は、おそらくインポートを調整する必要があります。

次の変更は、アプリケーションに関連している可能性があります。

  • すべてのテンプレートで自動エスケープが発生しなくなりました。 代わりに、.html.htm.xml、および.xhtmlで終わるファイルでのみ発生するように構成されています。 拡張子が異なるテンプレートがある場合は、select_jinja_autoescape()メソッドをオーバーライドする必要があります。
  • このリリースでは、Flaskはzip形式のアプリケーションをサポートしなくなりました。 この機能に対する需要がある場合、この機能は将来のリリースで復活する可能性があります。 このサポートを削除すると、Flaskの内部コードが理解しやすくなり、デバッグが必要以上に難しくなるいくつかの小さな問題が修正されます。
  • create_jinja_loader機能はなくなりました。 今すぐJinjaローダーをカスタマイズする場合は、代わりにcreate_jinja_environment()メソッドを使用してください。


バージョン0.4

アプリケーション開発者にとって、コードの変更を必要とする変更はありません。 ただし、Flask拡張機能で開発していて、その拡張機能にunittest-modeがある場合は、そのモードのアクティブ化を新しいTESTINGフラグにリンクすることをお勧めします。


バージョン0.3

Flask 0.3では、構成のサポートとロギング、およびフラッシュメッセージのカテゴリが導入されています。 これらはすべて100%下位互換性のある機能ですが、それらを利用することをお勧めします。

構成のサポート

構成サポートにより、ある種の構成を必要とするあらゆる種類のアプリケーションを簡単に作成できます。 (これは、そこにあるすべてのアプリケーションに当てはまる可能性が最も高いです)。

以前に次のようなコードがあった場合:

app.debug = DEBUG
app.secret_key = SECRET_KEY

これを行う必要はなくなりました。代わりに、構成を構成オブジェクトにロードするだけです。 これがどのように機能するかは、構成処理で概説されています。


ロギング統合

Flaskは、いくつかの基本的で便利なデフォルトを使用してロガーを構成するようになりました。 アプリケーションを本番環境で実行していて、自動エラーロギングを利用したい場合は、適切なログハンドラーをアタッチすることをお勧めします。 また、適切な場合は、警告とエラーをロガーに記録し始めることができます。 詳細については、アプリケーションエラーを参照してください。


フラッシュメッセージのカテゴリ

Flashメッセージにカテゴリを添付できるようになりました。 これにより、たとえば、エラー、警告、または通常のメッセージを異なる方法でレンダリングできます。 これはオプトイン機能です。コードを再考する必要があるためです。

メッセージ点滅パターンでそれについてすべて読んでください。