クイックスタート Quickstart

すぐ始めたいですか?このページはFlaskのイントロダクションに良いでしょう。Flaskはインストール済みと想定しています。もしまだならば、インストールセクションを確認してください。 Eager to get started? This page gives a good introduction to Flask. It assumes you already have Flask installed. If you do not, head over to the :ref:`installation` section.

最少のアプリケーション A Minimal Application

最少のFlaskアプリケーションは以下のようなものになります: A minimal Flask application looks something like this::

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

では、そのコードは何をしているのでしょうか? So what did that code do?

  1. 最初に、Flaskクラスをimportしています。このクラスのインスタンスはWSGI(訳注: Pythonで標準化されている、WebアプリとWebサーバ間のインタフェース)アプリケーションになります。 First we imported the :class:`~flask.Flask` class. An instance of this class will be our WSGI application.

  2. 次に、Flaskクラスのインスタンスを作成します。最初の引数はアプリケーションのモジュール(訳注: 簡単に言うと拡張子pyのPythonファイル)またはパッケージ(訳注: 簡単に言うとモジュールをまとめて格納したディレクトリ)の名前です。アプリケーションとして開始するかモジュールとしてimportするかによって名前が変化する('__main__'もしくは実際のimport名)ため、もし(この例のように)1つだけのモジュールを使っているときは、__name__を使うべきです。これはテンプレート、静的ファイルなどを探す場所をFlaskが知るために必要になります。さらなる情報については、Flaskのドキュメントを調べてください。 Next we create an instance of this class. The first argument is the name of the application's module or package. If you are using a single module (as in this example), you should use ``__name__`` because depending on if it's started as application or imported as module the name will be different (``'__main__'`` versus the actual import name). This is needed so that Flask knows where to look for templates, static files, and so on. For more information have a look at the :class:`~flask.Flask` documentation.

  3. それからroute()デコレータを使って、どのURLが関数をトリガーすべきかをFlaskに伝えます。 We then use the :meth:`~flask.Flask.route` decorator to tell Flask what URL should trigger our function.

  4. 関数には名前が与えられ、その名前は対応するURLを生成するときにも使用されます(訳注: 関数名がurl_for()で対応するURLを作成するときに使うエンドポイント名になることを指していると思います)。そして関数は、ユーザのブラウザに表示したいメッセージを返します。 The function is given a name which is also used to generate URLs for that particular function, and returns the message we want to display in the user's browser.

これをhello.pyのような名前で保存するだけです。Flask自身と衝突しないようにするため、自分のアプリケーションはflask.pyと名付けないように必ずしてください。 Just save it as :file:`hello.py` or something similar. Make sure to not call your application :file:`flask.py` because this would conflict with Flask itself.

アプリケーションを実行するには、flaskコマンドでもpythonの-mスイッチにFlaskを指定しても、どちらも使用できます。実行できるようにする前に、FLASK_APP環境変数をexportして、実行するアプリケーションを端末(訳注: Windowsでのコマンドプロンプト、Linuxでの端末、SSHログインしているときのPuTTYやTera Termなど、コマンドラインで操作している環境を指します)へ伝える必要があります。 To run the application you can either use the :command:`flask` command or python's ``-m`` switch with Flask. Before you can do that you need to tell your terminal the application to work with by exporting the ``FLASK_APP`` environment variable::

$ export FLASK_APP=hello.py
$ flask run
 * Running on http://127.0.0.1:5000/

Windows上では、環境変数の書き方はコマンドラインインタプリタに依存します。コマンドプロンプト上では: If you are on Windows, the environment variable syntax depends on command line interpreter. On Command Prompt::

C:\path\to\app>set FLASK_APP=hello.py

そしてPowerShell上では: And on PowerShell::

PS C:\path\to\app> $env:FLASK_APP = "hello.py"

違うやり方として、python -m flaskを使用できます: Alternatively you can use :command:`python -m flask`::

$ export FLASK_APP=hello.py
$ python -m flask run
 * Running on http://127.0.0.1:5000/

これはとてもシンプルな内蔵サーバを起動し、それはテスト用には十分ですが、おそらく本番環境では使用したくはならないでしょう。デプロイ(訳注: 実行環境への移行のような意味合い)のオプションについては、展開の選択肢(Deployment Options)を参照してください。 This launches a very simple builtin server, which is good enough for testing but probably not what you want to use in production. For deployment options see :ref:`deployment`.

それではhttp://127.0.0.1:5000/を見てください、あなたのhello worldを確認できるはずです。 Now head over to http://127.0.0.1:5000/, and you should see your hello world greeting.

外部から見えるサーバ Externally Visible Server

もしサーバを実行した場合、サーバは自分のコンピュータからだけアクセス可能で、他にはネットワークのどこからもアクセスできないことに気付くでしょう。デバッギングモードでは、アプリケーションのユーザがコンピュータ上で任意のPythonコードを実行可能になるために、これが標準設定になっています。 If you run the server you will notice that the server is only accessible from your own computer, not from any other in the network. This is the default because in debugging mode a user of the application can execute arbitrary Python code on your computer.

デバッギングを無効にしているか、ネットワーク上のユーザを信頼する場合、コマンドラインに--host=0.0.0.0を追加すれば、サーバへのアクセスを公開できます: If you have the debugger disabled or trust the users on your network, you can make the server publicly available simply by adding ``--host=0.0.0.0`` to the command line::

$ flask run --host=0.0.0.0

こうすると、全ての公開されているIP上でアクセスを受け付けるよう、OSへ伝えます。 This tells your operating system to listen on all public IPs.

サーバがスタートしない場合にするべきこと What to do if the Server does not Start

もしpython -m flaskが失敗するときやflaskコマンドが存在しないときは、その原因であるかもしれない理由がいくつかあります。まず最初に、エラーメッセージを調べる必要があります。 In case the :command:`python -m flask` fails or :command:`flask` does not exist, there are multiple reasons this might be the case. First of all you need to look at the error message.

古いバージョンのFlask Old Version of Flask

バージョン0.11以前のFlaskはアプリケーションを開始するときに別のやり方を使用していました。手短に言えば、flaskコマンドは存在せず、python -m flaskも使いませんでした。この場合には、2つの選択肢があります: Flaskを新しいバージョンへアップグレードするか、開発サーバドキュメントを調べて、サーバを実行する代わりのやり方を見つけてください。 Versions of Flask older than 0.11 use to have different ways to start the application. In short, the :command:`flask` command did not exist, and neither did :command:`python -m flask`. In that case you have two options: either upgrade to newer Flask versions or have a look at the :ref:`server` docs to see the alternative method for running a server.

間違った名前のimport Invalid Import Name

FLASK_APP環境変数はflask runでimportするモジュールの名前になります。モジュール名が正確でない場合には、スタートしようとしたとき(もしくは、もしデバッグを有効にしていた場合はアプリケーションへアクセスしようとしたとき)にimport errorが発生するでしょう。import errorは、何をimportしようとして、なぜ失敗したかを示しているでしょう。 The ``FLASK_APP`` environment variable is the name of the module to import at :command:`flask run`. In case that module is incorrectly named you will get an import error upon start (or if debug is enabled when you navigate to the application). It will tell you what it tried to import and why it failed.

最もありがちな(サーバ起動失敗の)理由は、typoか、appオブジェクトを実際に作成してはいないためです。 The most common reason is a typo or because you did not actually create an ``app`` object.

デバッグモード Debug Mode

(ただ、errorやstack traceをログに記録したいだけですか?その場合はアプリケーションのエラーを確認してください) (Want to just log errors and stack traces? See :ref:`application-errors`)

flaskスクリプトはローカルの開発サーバをスタートするには便利ですが、コードを変更するたびに手動で再起動が必要になるでしょう。それはあまり便利ではなく、そしてFlaskはもっと便利に使えます。もしデバッグサポートを有効にすれば、コードを変更したときにサーバは自分自信で再読み込み(reload)するようになり、さらに、もし問題が起きた場合には役に立つデバッガも提供するようにもなります。 The :command:`flask` script is nice to start a local development server, but you would have to restart it manually after each change to your code. That is not very nice and Flask can do better. If you enable debug support the server will reload itself on code changes, and it will also provide you with a helpful debugger if things go wrong.

すべての(デバッグモードも含めた)開発機能を有効にするために、サーバの実行前に環境変数FLASK_ENVdevelopmentに設定してエクスポートできます: To enable all development features (including debug mode) you can export the ``FLASK_ENV`` environment variable and set it to ``development`` before running the server::

$ export FLASK_ENV=development
$ flask run

(Windowsでは、exportの代わりにsetを使う必要があります) (On Windows you need to use ``set`` instead of ``export``.)

これは以下のことを行います: This does the following things:

  1. デバッガを有効にします it activates the debugger

  2. 自動再読み込みを有効にします it activates the automatic reloader

  3. Flaskアプリケーションのデバッグモードを有効にします。 it enables the debug mode on the Flask application.

環境(訳注: FLASK_ENVの設定とほぼ同じ意味合い)とは別に、FLASK_DEBUG=1をexportしてもデバッグモードを制御できます。 You can also control debug mode separately from the environment by exporting ``FLASK_DEBUG=1``.

開発サーバのドキュメントでより多くのパラメータを説明しています。 There are more parameters that are explained in the :ref:`server` docs.

注意 Attention

たとえforkした環境(訳注: デバッガを使った作業参照、外部デバッガを使用したい場合にFlaskではforkした環境というものを設定可能)ではインタラクティブなデバッガが動かない(それによって本番環境のサーバでは内蔵デバッガが殆ど使用不可能になります)としても、それでも(デバッグモードや外部デバッガの使用は)任意のコードを実行できるようにします。これは深刻なセキュリティ上のリスクであり、従って本番環境のマシンでは決して使用してはいけません Even though the interactive debugger does not work in forking environments (which makes it nearly impossible to use on production servers), it still allows the execution of arbitrary code. This makes it a major security risk and therefore it **must never be used on production machines**.

実行中のデバッガのスクリーンショット: Screenshot of the debugger in action:

screenshot of debugger in action

デバッガ使用に関するさらなる情報はWerkzeugドキュメントで見つけることができます。 More information on using the debugger can be found in the `Werkzeug documentation`_.

他のデバッガを考えていますか?デバッガを使った作業を確認してください。 Have another debugger in mind? See :ref:`working-with-debuggers`.

経路設定(Routing) Routing

最近のwebアプリケーションは、ユーザに役立つような意味のあるURLを使用します。もし、ページへ直接訪れるために記憶し直接指定できる意味のあるURLを使用していれば、ユーザはそのページをより好きになり、再訪問するようになるでしょう。 Modern web applications use meaningful URLs to help users. Users are more likely to like a page and come back if the page uses a meaningful URL they can remember and use to directly visit a page.

関数とURLを結び付け(bind)したいときは、route()デコレータを使用します。 Use the :meth:`~flask.Flask.route` decorator to bind a function to a URL. ::

@app.route('/')
def index():
    return 'Index Page'

@app.route('/hello')
def hello():
    return 'Hello, World'

もっとできることがあります!URLの一部を動的に変化させたり、複数のルールを関数に付与することも可能です。 You can do more! You can make parts of the URL dynamic and attach multiple rules to a function.

変数のルール Variable Rules

<variable_name>のように一部へ目印をつけることで、URLに変数のセクションを追加することができます。こうすると、関数は<variable_name>をキーワード引数のように受け取るようになります。必須ではないですが、引数のタイプを指定するために、<converter:variable_name>のようにすればコンバータを使用できます。 You can add variable sections to a URL by marking sections with ``<variable_name>``. Your function then receives the ``<variable_name>`` as a keyword argument. Optionally, you can use a converter to specify the type of the argument like ``<converter:variable_name>``. ::

@app.route('/user/<username>')
def show_user_profile(username):
    # show the user profile for that user
    return 'User %s' % escape(username)

@app.route('/post/<int:post_id>')
def show_post(post_id):
    # show the post with the given id, the id is an integer
    return 'Post %d' % post_id

@app.route('/path/<path:subpath>')
def show_subpath(subpath):
    # show the subpath after /path/
    return 'Subpath %s' % escape(subpath)

コンバータの種類: Converter types:

string

(標準設定)スラッシュ(/)以外の全てのテキストを受け付けます (default) accepts any text without a slash

int

正の整数を受け付けます accepts positive integers

float

正の浮動小数点の値を受け付けます accepts positive floating point values

path

stringに似ていますが、スラッシュ(/)を受け付けます like ``string`` but also accepts slashes

uuid

UUID文字列を受け付けます accepts UUID strings

URLと転送(Redirection)のユニークな振舞 Unique URLs / Redirection Behavior

最後のスラッシュ(/)の使い方が、以下の2つのルールでは異なっています。: The following two rules differ in their use of a trailing slash. ::

@app.route('/projects/')
def projects():
    return 'The project page'

@app.route('/about')
def about():
    return 'The about page'

projectsエンドポイントの正規化(訳注: 記法の揺らぎを統一するような意味合い)されたURLでは、最後にスラッシュがあります。これはファイルシステムでのフォルダに似ています。もし最後のスラッシュなしでURLへアクセスした場合、Flaskは最後にスラッシュのある正規化されたURLへ転送(redirect)します。 The canonical URL for the ``projects`` endpoint has a trailing slash. It's similar to a folder in a file system. If you access the URL without a trailing slash, Flask redirects you to the canonical URL with the trailing slash.

aboutエンドポイントの正規化されたURLでは、最後にスラッシュがありません。これはファイルシステムでのファイルのパス名に似ています。もし最後にスラッシュを付けたURLへアクセスしたときは404の「Not Found」エラーが発生します。こうすると、これらのリソースに対するURLを唯ひとつに保てるため、検索エンジンが同じページを重複して登録することを防ぐ手助けになります。 The canonical URL for the ``about`` endpoint does not have a trailing slash. It's similar to the pathname of a file. Accessing the URL with a trailing slash produces a 404 "Not Found" error. This helps keep URLs unique for these resources, which helps search engines avoid indexing the same page twice.

URLの構築 URL Building

ある特定の関数に対応するURLを構築するには、url_for()関数を使用します。それは関数名を最初の引数に受け付けて、さらに、URLルールの変数部分に対応する、好きな数だけのキーワード引数を受け付けます。不明な変数パートはqueryパラメータとしてURLの後ろ(訳注: ?key=valueの部分)に付けられます。 To build a URL to a specific function, use the :func:`~flask.url_for` function. It accepts the name of the function as its first argument and any number of keyword arguments, each corresponding to a variable part of the URL rule. Unknown variable parts are appended to the URL as query parameters.

URLをテンプレートへハードコーディングする代わりに、(関数名から)URLへと逆変換するurl_for()関数を使ってURLを構築する方が、なぜ好ましいのでしょうか?(訳注: テンプレートの中でリンクなどがあったとき、そこへURLを直接記述するのではなく、リンク先で使いたい関数名からURLへ変換する処理を記述した方がなぜ好ましいか、という意味合い) Why would you want to build URLs using the URL reversing function :func:`~flask.url_for` instead of hard-coding them into your templates?

  1. URLをハードコーディングするよりもURLへ逆変換する方が、分かり易いことが多いためです。 Reversing is often more descriptive than hard-coding the URLs.

  2. (URLを変更するとき)ハードコーディングされた(複数の場所に埋め込まれているかもしれない)URLを忘れずに手作業で変更する必要がある代わりに、(関数とURLを対応付けている箇所で)一気に変更することができます。 You can change your URLs in one go instead of needing to remember to manually change hard-coded URLs.

  3. URLを構築する処理では、特殊文字とユニコードのデータのエスケープ処理を透過的に扱います。 URL building handles escaping of special characters and Unicode data transparently.

  4. 生成されたパスは常に絶対パスであり、相対パスによるブラウザ上での予想外の振舞を回避します。 The generated paths are always absolute, avoiding unexpected behavior of relative paths in browsers.

  5. もしアプリケーションがURLのroot以外、例えば、/の代わりに/myapplicationへ置かれたときでも、url_for()は適切に処理します。 If your application is placed outside the URL root, for example, in ``/myapplication`` instead of ``/``, :func:`~flask.url_for` properly handles that for you.

以下の例ではurl_for()を試すためにtest_request_context()メソッドを使っています。test_request_context()はFlaskに、Pythonシェルを使っている場合であってもリクエスト(訳注: HTTPなどの通信リクエスト)をを処理しているかのように振る舞うよう伝えます。コンテキストの局所的オブジェクト(Context Locals)を参照ください。 For example, here we use the :meth:`~flask.Flask.test_request_context` method to try out :func:`~flask.url_for`. :meth:`~flask.Flask.test_request_context` tells Flask to behave as though it's handling a request even while we use a Python shell. See :ref:`context-locals`.

from flask import Flask, escape, url_for

app = Flask(__name__)

@app.route('/')
def index():
    return 'index'

@app.route('/login')
def login():
    return 'login'

@app.route('/user/<username>')
def profile(username):
    return '{}\'s profile'.format(escape(username))

with app.test_request_context():
    print(url_for('index'))
    print(url_for('login'))
    print(url_for('login', next='/'))
    print(url_for('profile', username='John Doe'))
/
/login
/login?next=/
/user/John%20Doe

HTTPメソッド HTTP Methods

webアプリはURLへアクセスするときに異なるHTTPメソッドを使用します。Flaskで作業するときは、HTTPメソッドに親しんでおいた方が良いでしょう。標準設定の経路(route)は、GETメソッドにだけ応答します。異なるHTTPメソッドを処理するために、route()デコレータのmethod引数を使用できます。 Web applications use different HTTP methods when accessing URLs. You should familiarize yourself with the HTTP methods as you work with Flask. By default, a route only answers to ``GET`` requests. You can use the ``methods`` argument of the :meth:`~flask.Flask.route` decorator to handle different HTTP methods. ::

from flask import request

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        return do_the_login()
    else:
        return show_the_login_form()

もしGETが(method引数の中に)存在する場合、Flaskは自動的にHEADメソッドのサポートを追加して、HTTP RFCに従って ``HEAD``リクエストを処理します。同様に、あなたにとって良いように、OPTIONSも自動的に実装されます。 If ``GET`` is present, Flask automatically adds support for the ``HEAD`` method and handles ``HEAD`` requests according to the `HTTP RFC`_. Likewise, ``OPTIONS`` is automatically implemented for you.

静的ファイル Static Files

動的なwebアプリケーションでも静的ファイルを必要とします。普通は、静的ファイルはCSSとJavaScriptがもたらされるところです。webサーバがそれらを扱うように構成されていると理想的ですが、開発中はFlaskで同様な対応が可能です。パッケージの中またはモジュールの隣にstaticというフォルダを作成するだけで、アプリケーションから/staticで利用できるようになります。 Dynamic web applications also need static files. That's usually where the CSS and JavaScript files are coming from. Ideally your web server is configured to serve them for you, but during development Flask can do that as well. Just create a folder called :file:`static` in your package or next to your module and it will be available at ``/static`` on the application.

静的ファイルに対応するURLを生成するには、特別な'static'というエンドポイント名を使用します: To generate URLs for static files, use the special ``'static'`` endpoint name::

url_for('static', filename='style.css')

この例のファイルは、ファイルシステム上のstatic/style.cssに保管されている必要があります。 The file has to be stored on the filesystem as :file:`static/style.css`.

テンプレートの変換(Rendering) Rendering Templates

Pythonの中でHTMLを生成するのは楽しい作業ではなく、アプリケーションをセキュアに保つためにHTMLエスケープ処理を自分で行う必要があるために、実際にとても煩わしいものです。そのような理由から、FlaskはJinja2テンプレートエンジンを自動的に組み込んでいます。 Generating HTML from within Python is not fun, and actually pretty cumbersome because you have to do the HTML escaping on your own to keep the application secure. Because of that Flask configures the `Jinja2 <http://jinja.pocoo.org/>`_ template engine for you automatically.

テンプレートを変換するにはrender_template()メソッドを使用できます。あなたがしなければならないことは、テンプレート名と、キーワード引数としてテンプレートエンジンに渡したい変数の提供だけです。テンプレートをどのように変換するかの単純な例は以下のとおりです: To render a template you can use the :func:`~flask.render_template` method. All you have to do is provide the name of the template and the variables you want to pass to the template engine as keyword arguments. Here's a simple example of how to render a template::

from flask import render_template

@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
    return render_template('hello.html', name=name)

Flaskはテンプレートをtemplatesフォルダの中から探します。もしアプリケーションがモジュールなら、そのフォルダはモジュールの隣にあり、もしパッケージなら、そのフォルダは実際にはパッケージの中にあります: Flask will look for templates in the :file:`templates` folder. So if your application is a module, this folder is next to that module, if it's a package it's actually inside your package:

ケース 1: モジュール: **Case 1**: a module::

/application.py
/templates
    /hello.html

ケース 2: パッケージ: **Case 2**: a package::

/application
    /__init__.py
    /templates
        /hello.html

テンプレートではJinja2テンプレートの力を全て使うことができます。より詳細な情報はJinja2テンプレートドキュメントを確認してください。 For templates you can use the full power of Jinja2 templates. Head over to the official `Jinja2 Template Documentation <http://jinja.pocoo.org/docs/templates/>`_ for more information.

これはテンプレートの例です: Here is an example template:

<!doctype html>
<title>Hello from Flask</title>
{% if name %}
  <h1>Hello {{ name }}!</h1>
{% else %}
  <h1>Hello, World!</h1>
{% endif %}

テンプレートの中では、get_flashed_messages()関数と同様に、request, session, g 1オブジェクトにもアクセスできます。 Inside templates you also have access to the :class:`~flask.request`, :class:`~flask.session` and :class:`~flask.g` [#]_ objects as well as the :func:`~flask.get_flashed_messages` function.

継承を使うとテンプレートは非常に便利です。テンプレートがどのように働くか知りたいときはTemplate Inheritanceパターンのドキュメントを確認してください。基本的にテンプレートの継承は(ヘッダ、ナビゲーション、フッタのように)ある要素を各ページで保持できるようにします。 Templates are especially useful if inheritance is used. If you want to know how that works, head over to the :ref:`template-inheritance` pattern documentation. Basically template inheritance makes it possible to keep certain elements on each page (like header, navigation and footer).

自動エスケープが有効なので、もしnameがHTMLを含んでいた場合は、自動的にエスケープされます。もし変数を信頼できて、それが安全なHTMLであると分かっている(例えばwikiのマークアップをHTMLへ変換するモジュールから来ているなど)場合は、Markupクラスを使うか、|safeフィルタ(訳注: ここのフィルタはjinja2テンプレートエンジンの機能のひとつ)をテンプレートの中で使って、安全だと印を付けることができます。さらなる例はJinja2ドキュメントを確認してください。 Automatic escaping is enabled, so if ``name`` contains HTML it will be escaped automatically. If you can trust a variable and you know that it will be safe HTML (for example because it came from a module that converts wiki markup to HTML) you can mark it as safe by using the :class:`~jinja2.Markup` class or by using the ``|safe`` filter in the template. Head over to the Jinja 2 documentation for more examples.

Markupクラスがどう働くかの基礎的なイントロダクションは以下のとおりです: Here is a basic introduction to how the :class:`~jinja2.Markup` class works::

>>> from flask import Markup
>>> Markup('<strong>Hello %s!</strong>') % '<blink>hacker</blink>'
Markup(u'<strong>Hello &lt;blink&gt;hacker&lt;/blink&gt;!</strong>')
>>> Markup.escape('<blink>hacker</blink>')
Markup(u'&lt;blink&gt;hacker&lt;/blink&gt;')
>>> Markup('<em>Marked up</em> &raquo; HTML').striptags()
u'Marked up \xbb HTML'
Changelog

バージョン 0.5 で変更: 自動エスケープは全てのテンプレートで有効というわけではなくなっています。テンプレートが以下の拡張子であるときは、自動エスケープをトリガーします:.html, .htm, .xml, .xhtml。文字列から読み込まれたテンプレートでは、自動エスケープは無効になります。

1

gオブジェクトが何なのか不確かですか?それは、独自のニーズのために必要に応じて情報を格納できるものであり、より詳細な情報はそのオブジェクト(g)とUsing SQLite 3 with Flaskのドキュメントをチェックしてください。 Unsure what that :class:`~flask.g` object is? It's something in which you can store information for your own needs, check the documentation of that object (:class:`~flask.g`) and the :ref:`sqlite3` for more information.

リクエストデータへのアクセス Accessing Request Data

webアプリでは、クライアントがサーバへ送信したデータへ反応することが非常に重要です。Flaskでは、その情報(クライアントがサーバへ送信したデータ)はグローバルなrequestオブジェクトで提供されます。もしPython経験が多少あるならば、そのオブジェクトがグローバルでありながらスレッドセーフでもあるように、Flaskがどうやって管理しているのか、不思議に思うかもしれません。その答えはコンテキストの局所的オブジェクト(context locals)です: For web applications it's crucial to react to the data a client sends to the server. In Flask this information is provided by the global :class:`~flask.request` object. If you have some experience with Python you might be wondering how that object can be global and how Flask manages to still be threadsafe. The answer is context locals:

コンテキストの局所的オブジェクト(Context Locals) Context Locals

内部情報 Insider Information

もしcontext localsがどのように作用し、context localsを使ってどうやってテストできるかを理解したい場合は、このセクションを読み、そうでない場合は飛ばしてください。 If you want to understand how that works and how you can implement tests with context locals, read this section, otherwise just skip it.

いくつかのFlaskのオブジェクトはグローバルなオブジェクトですが、普通の種類のものではありません。それらのオブジェクトは実際には、ある特定のコンテキストに対して局所的なオブジェクトへのプロキシになります。長ったらしい説明ですが、実際には、理解するのは非常に簡単です。 Certain objects in Flask are global objects, but not of the usual kind. These objects are actually proxies to objects that are local to a specific context. What a mouthful. But that is actually quite easy to understand.

コンテキストを処理中のスレッドだと想像してください。リクエストがやって来て、webサーバが新規スレッド(もしくは別のなにか、スレッド以外で並列処理を扱える土台となるオブジェクト)を作成する決定をします。Flaskが内部のリクエスト処理を開始するとき、Flaskはそのときのスレッドが活動中(active)のコンテキストであることを理解し、そのときのアプリケーションおよびWSGI環境とそのコンテキスト(スレッド)との結び付け(bind)をします。Flaskは、あるアプリケーションを起動しながら別のアプリケーションは壊さないような、賢いやり方でそれを実施します。 Imagine the context being the handling thread. A request comes in and the web server decides to spawn a new thread (or something else, the underlying object is capable of dealing with concurrency systems other than threads). When Flask starts its internal request handling it figures out that the current thread is the active context and binds the current application and the WSGI environments to that context (thread). It does that in an intelligent way so that one application can invoke another application without breaking.

それでは、これはあなたにとって何を意味するのでしょうか?ユニットテストのようなことを行おうとしていない限り、基本的には完全に無視して構いません。(ユニットテストのようなことを行っているときは)リクエストオブジェクトが存在しないために、リクエストオブジェクトに依存しているコードが突然止まることに気付くでしょう。解決方法は、自分でリクエストオブジェクトを作成してコンテキストに結び付けることです。ユニットテストのための最も簡単な解決方法はコンテキストマネージャ(訳注: Pythonの仕様にある、with文と組み合わせて特別な処理をする仕組みで、ここの「コンテキスト」はHTTPリクエストとは関係ないか、またはHTTPリクエストのコンテキストとPython仕様にあるコンテキストの両者をかけた意味合い)のtest_request_context()を使用することです。with文と組み合わせると、テスト用のリクエストとやり取りできるように、テスト用リクエストとコンテキストとを結び付けます。以下はその例です: So what does this mean to you? Basically you can completely ignore that this is the case unless you are doing something like unit testing. You will notice that code which depends on a request object will suddenly break because there is no request object. The solution is creating a request object yourself and binding it to the context. The easiest solution for unit testing is to use the :meth:`~flask.Flask.test_request_context` context manager. In combination with the ``with`` statement it will bind a test request so that you can interact with it. Here is an example::

from flask import request

with app.test_request_context('/hello', method='POST'):
    # now you can do something with the request until the
    # end of the with block, such as basic assertions:
    assert request.path == '/hello'
    assert request.method == 'POST'

別の可能なやり方は、WSGI環境全体をrequest_context()メソッドへ渡すことです。 The other possibility is passing a whole WSGI environment to the :meth:`~flask.Flask.request_context` method::

from flask import request

with app.request_context(environ):
    assert request.method == 'POST'

リクエストオブジェクト The Request Object

リクエストオブジェクトはAPIセクションにドキュメントがあり、ここでは詳細は網羅しません(詳細はRequestを確認してください)。ここでは、最もよくある操作のいくつかについて概観します。まず最初に、flaskモジュールをimportする必要があります: The request object is documented in the API section and we will not cover it here in detail (see :class:`~flask.Request`). Here is a broad overview of some of the most common operations. First of all you have to import it from the ``flask`` module::

from flask import request

その時点のリクエストのメソッドはmethod属性を使えば利用可能です。formのデータ(POSTまたはPUTリクエストで送信されるデータ)へアクセスするには、form属性を使用できます。以下は言及した2つの属性についての不足のない(どちらの用法も示した)例です: The current request method is available by using the :attr:`~flask.Request.method` attribute. To access form data (data transmitted in a ``POST`` or ``PUT`` request) you can use the :attr:`~flask.Request.form` attribute. Here is a full example of the two attributes mentioned above::

@app.route('/login', methods=['POST', 'GET'])
def login():
    error = None
    if request.method == 'POST':
        if valid_login(request.form['username'],
                       request.form['password']):
            return log_the_user_in(request.form['username'])
        else:
            error = 'Invalid username/password'
    # the code below is executed if the request method
    # was GET or the credentials were invalid
    return render_template('login.html', error=error)

form属性にキーが存在しない場合はどうなるでしょうか?そのような場合は特別なKeyErrorを発生させます。それを標準のKeyErrorのようにcatchすることもできますし、そうしない場合には、代わりにHTTP 400Bad Requestのエラーページが表示されます。従って多くの場面では、その問題を特に処理する必要はないでしょう。 What happens if the key does not exist in the ``form`` attribute? In that case a special :exc:`KeyError` is raised. You can catch it like a standard :exc:`KeyError` but if you don't do that, a HTTP 400 Bad Request error page is shown instead. So for many situations you don't have to deal with that problem.

URLの中(?key=valueの部分)で与えられるパラメータへのアクセスにはargs属性を使用できます: To access parameters submitted in the URL (``?key=value``) you can use the :attr:`~flask.Request.args` attribute::

searchword = request.args.get('key', '')

ユーザはURLを変更することがあり、そのたびに400 bad requestのページを表示することはユーザにとって親切ではないので、URLパラメータはgetでアクセスするか、KeyErrorをcatchすることを推奨します。 We recommend accessing URL parameters with `get` or by catching the :exc:`KeyError` because users might change the URL and presenting them a 400 bad request page in that case is not user friendly.

リクエストオブジェクトの全てのメソッドと属性のリストは、Requestドキュメントを確認してください。 For a full list of methods and attributes of the request object, head over to the :class:`~flask.Request` documentation.

ファイルのアップロード File Uploads

Flaskではアップロードされたファイルを容易に処理できます。自分のHTMLのformで、enctype="multipart/form-data"属性の設定だけは忘れず確実にしてください。そうしないと、そもそもブラウザがファイルを送信しないでしょう。 You can handle uploaded files with Flask easily. Just make sure not to forget to set the ``enctype="multipart/form-data"`` attribute on your HTML form, otherwise the browser will not transmit your files at all.

アップロードされたファイルはメモリ中かファイルシステムの一時的な場所に格納されます。それらのファイルはリクエストオブジェクトのfiles属性を調べることでアクセスできます。アップロードされた各ファイルは、そのdictionaryに格納されます。それはPython標準のfileオブジェクトのように振る舞いますが、サーバのファイルシステムへそのファイルを格納できるようにするsave()メソッドも持っています。以下は、それがどのように働くかを示す簡単な例です: Uploaded files are stored in memory or at a temporary location on the filesystem. You can access those files by looking at the :attr:`~flask.request.files` attribute on the request object. Each uploaded file is stored in that dictionary. It behaves just like a standard Python :class:`file` object, but it also has a :meth:`~werkzeug.datastructures.FileStorage.save` method that allows you to store that file on the filesystem of the server. Here is a simple example showing how that works::

from flask import request

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        f = request.files['the_file']
        f.save('/var/www/uploads/uploaded_file.txt')
    ...

アップロードされる前にクライアント側でどのようなファイル名であったかを知りたい場合は、filename属性にアクセスできます。しかし、その値は偽装される可能性があり決して信頼はできないことは覚えておいてください。クライアント側のファイル名を使用してサーバ側でファイルを格納したい場合は、Werkzeugが提供するsecure_filename()関数を通過させてください: If you want to know how the file was named on the client before it was uploaded to your application, you can access the :attr:`~werkzeug.datastructures.FileStorage.filename` attribute. However please keep in mind that this value can be forged so never ever trust that value. If you want to use the filename of the client to store the file on the server, pass it through the :func:`~werkzeug.utils.secure_filename` function that Werkzeug provides for you::

from flask import request
from werkzeug.utils import secure_filename

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        f = request.files['the_file']
        f.save('/var/www/uploads/' + secure_filename(f.filename))
    ...

もっと良い例については、Uploading Filesパターンを調べてください。 For some better examples, checkout the :ref:`uploading-files` pattern.

クッキー(Cookies) Cookies

クッキーへアクセスするにはcookies属性が使用できます。クッキーを設定するには、レスポンスオブジェクトのset_cookieメソッドを使用できます。リクエストオブジェクトのcookies属性はクライアントが送信する全てのクッキーのdictionaryです。セッションを使用したい場合は、クッキーを直接使うのではなく、クッキーの上にいくらかセキュリティーを追加した、Flaskのセッションを代わりに使用してください。 To access cookies you can use the :attr:`~flask.Request.cookies` attribute. To set cookies you can use the :attr:`~flask.Response.set_cookie` method of response objects. The :attr:`~flask.Request.cookies` attribute of request objects is a dictionary with all the cookies the client transmits. If you want to use sessions, do not use the cookies directly but instead use the :ref:`sessions` in Flask that add some security on top of cookies for you.

クッキーの読取: Reading cookies::

from flask import request

@app.route('/')
def index():
    username = request.cookies.get('username')
    # use cookies.get(key) instead of cookies[key] to not get a
    # KeyError if the cookie is missing.

クッキーの格納: Storing cookies::

from flask import make_response

@app.route('/')
def index():
    resp = make_response(render_template(...))
    resp.set_cookie('username', 'the username')
    return resp

クッキーはレスポンスオブジェクトに設定されていることに注目してください。通常はview関数からはただ文字列を返すだけなので、あなたにとって良いように、Flaskはそれら(訳注: view関数の戻り値、クッキーなど)をレスポンスオブジェクトへと変換します。もしそれを自分で明示的に実行したい場合は、make_response()関数を使用して、それ(レスポンスオブジェクト)を変更できます。 Note that cookies are set on response objects. Since you normally just return strings from the view functions Flask will convert them into response objects for you. If you explicitly want to do that you can use the :meth:`~flask.make_response` function and then modify it.

ときには、レスポンスオブジェクトがまだ存在しない時点でクッキーを設定したいこともあるでしょう。これはDeferred Request Callbacksパターンを活用すれば可能です。 Sometimes you might want to set a cookie at a point where the response object does not exist yet. This is possible by utilizing the :ref:`deferred-callbacks` pattern.

これについてはレスポンスについても確認してください。 For this also see :ref:`about-responses`.

転送(Redirects)とエラー Redirects and Errors

ユーザを別のエンドポイントへリダイレクトするには、redirect()関数を使用します; リクエストを早い段階でエラーコードと一緒に異常終了させるには、abort()関数を使用します: To redirect a user to another endpoint, use the :func:`~flask.redirect` function; to abort a request early with an error code, use the :func:`~flask.abort` function::

from flask import abort, redirect, url_for

@app.route('/')
def index():
    return redirect(url_for('login'))

@app.route('/login')
def login():
    abort(401)
    this_is_never_executed()

これは、ユーザをindexページからアクセスできないページ(401はアクセス拒否を意味します)へとリダイレクトするため、いくぶんポイントを捉えていない例ですが、上記の関数がどのように機能するかを示しています。 This is a rather pointless example because a user will be redirected from the index to a page they cannot access (401 means access denied) but it shows how that works.

標準設定では各エラーコードに対して白黒のエラーページを表示します。もしエラーページをカスタマイズしたい場合、errorhandler()デコレータを使用できます: By default a black and white error page is shown for each error code. If you want to customize the error page, you can use the :meth:`~flask.Flask.errorhandler` decorator::

from flask import render_template

@app.errorhandler(404)
def page_not_found(error):
    return render_template('page_not_found.html'), 404

render_template()呼び出し後の``404``に注目してください。これは、そのページのステータスコードはnot foundを意味する404にするべきであることを、Flaskに伝えます。標準設定では200が想定されており、それは次のように翻訳されます: すべてうまく行きました。 Note the ``404`` after the :func:`~flask.render_template` call. This tells Flask that the status code of that page should be 404 which means not found. By default 200 is assumed which translates to: all went well.

より詳細はエラー処理器(Error handlers)を確認してください。 See :ref:`error-handlers` for more details.

レスポンスについて About Responses

view関数からの戻り値は自動的にレスポンスオブジェクトに変換されます。もし戻り値がstringの場合、stringをレスポンスのbodyに、ステータスコードを200 OKに、そしてmimeタイプをtext/htmlにしたレスポンスオブジェクトへ変換されます。もし戻り値がdictの場合、レスポンスを作成するためにjsonify()が呼び出されます。Flaskが(view関数の)戻り値をレスポンスへ変換するロジックは以下のとおりです: The return value from a view function is automatically converted into a response object for you. If the return value is a string it's converted into a response object with the string as response body, a ``200 OK`` status code and a :mimetype:`text/html` mimetype. If the return value is a dict, :func:`jsonify` is called to produce a response. The logic that Flask applies to converting return values into response objects is as follows:

  1. もし適切なタイプのレスポンスオブジェクトが返された場合は、それがviewから直接返されます。 If a response object of the correct type is returned it's directly returned from the view.

  2. もしstringであれば、レスポンスオブジェクトはそのデータと標準設定のパラメータとを使用して作成されます。 If it's a string, a response object is created with that data and the default parameters.

  3. もしdictであれば、レスポンスオブジェクトはjsonify()を使用して作成されます。 If it's a dict, a response object is created using ``jsonify``.

  4. もしtupleが返された場合は、tuple内のアイテムは追加情報を提供できます。そのようなtupleは(response, status), (response, headers), または(response, status, headers)という形式でなければいけません。statusの値はステータスコードを上書きし、そしてheadersは追加ヘッダの値であるlistかdictionaryが可能です。 If a tuple is returned the items in the tuple can provide extra information. Such tuples have to be in the form ``(response, status)``, ``(response, headers)``, or ``(response, status, headers)``. The ``status`` value will override the status code and ``headers`` can be a list or dictionary of additional header values.

  5. もし上記のいずれも機能しない場合、戻り値は妥当なWSGIアプリケーションであるとFlaskは仮定し、それをレスポンスオブジェクトへ変換します。 If none of that works, Flask will assume the return value is a valid WSGI application and convert that into a response object.

もし結果となるレスポンスオブジェクトをviewの内側で捉えたい場合は、make_response()関数を使用できます。 If you want to get hold of the resulting response object inside the view you can use the :func:`~flask.make_response` function.

以下のようなviewがあると想像してください: Imagine you have a view like this::

@app.errorhandler(404)
def not_found(error):
    return render_template('error.html'), 404

必要なことは、make_response()でreturnの式を囲み、変更するためにレスポンスオブジェクトを取得し、それからそのレスポンスオブジェクトを返すだけです。 You just need to wrap the return expression with :func:`~flask.make_response` and get the response object to modify it, then return it::

@app.errorhandler(404)
def not_found(error):
    resp = make_response(render_template('error.html'), 404)
    resp.headers['X-Something'] = 'A value'
    return resp

JSONを使ったAPIs APIs with JSON

APIを書いているときによくあるレスポンスのフォーマットにJSONがあります。FlaskでそのようなAPIの作成を始めることは簡単です。もしdictをviewから返した場合、それはJSONのレスポンスへ変換されます。 A common response format when writing an API is JSON. It's easy to get started writing such an API with Flask. If you return a ``dict`` from a view, it will be converted to a JSON response.

@app.route("/me")
def me_api():
    user = get_current_user()
    return {
        "username": user.username,
        "theme": user.theme,
        "image": url_for("user_image", filename=user.image),
    }

APIの設計によっては、JSONのレスポンスをdict以外のタイプでも作成したくなるかもしれません。そのような場合は、サポートされているJSONのデータタイプのシリアライズ(訳注: この場合ネットワークで通信可能な形式にするような意味合い)をするjsonify()関数を使用します。もしくは、より複雑なアプリケーションをサポートする、コミュニティのFlask拡張を調べてください。 Depending on your API design, you may want to create JSON responses for types other than ``dict``. In that case, use the :func:`~flask.json.jsonify` function, which will serialize any supported JSON data type. Or look into Flask community extensions that support more complex applications.

@app.route("/users")
def users_api():
    users = get_all_users()
    return jsonify([user.to_json() for user in users])

セッション Sessions

リクエストオブジェクトに加えて、あるユーザに特有の情報をひとつのリクエストから次のリクエストへと格納できるようにする、sessionと呼ばれる2番目のオブジェクトもあります。これはクッキー上に実装されていて、クッキーに暗号学的な署名をします。これが意味することは、ユーザは自分のクッキーの内容を見ることはできますが、署名に使われた秘密鍵を知らないかぎり、変更はできないということです。 In addition to the request object there is also a second object called :class:`~flask.session` which allows you to store information specific to a user from one request to the next. This is implemented on top of cookies for you and signs the cookies cryptographically. What this means is that the user could look at the contents of your cookie but not modify it, unless they know the secret key used for signing.

セッションを使用するためには、秘密鍵を設定しなければなりません。セッションがどのように働くかは、以下のとおりです: In order to use sessions you have to set a secret key. Here is how sessions work::

from flask import Flask, session, redirect, url_for, escape, request

app = Flask(__name__)

# Set the secret key to some random bytes. Keep this really secret!
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'

@app.route('/')
def index():
    if 'username' in session:
        return 'Logged in as %s' % escape(session['username'])
    return 'You are not logged in'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('index'))
    return '''
        <form method="post">
            <p><input type=text name=username>
            <p><input type=submit value=Login>
        </form>
    '''

@app.route('/logout')
def logout():
    # remove the username from the session if it's there
    session.pop('username', None)
    return redirect(url_for('index'))

ここで言及されているescape()は、(この例のように)テンプレートエンジンを使用していない場合にエスケープ処理をします。 The :func:`~flask.escape` mentioned here does escaping for you if you are not using the template engine (as in this example).

良い秘密鍵の生成のしかた How to generate good secret keys

秘密鍵はできるだけでたらめなものにするべきです。暗号学的にでたらめであるデータの生成装置に基づいた、非常にでたらめなデータを生成する方法がオペレーティングシステムにはあります。手早くFlask.secret_key(もしくはSECRET_KEY)の値を生成するには、以下のコマンドを使用してください: A secret key should be as random as possible. Your operating system has ways to generate pretty random data based on a cryptographic random generator. Use the following command to quickly generate a value for :attr:`Flask.secret_key` (or :data:`SECRET_KEY`)::

$ python -c 'import os; print(os.urandom(16))'
b'_5#y2L"F4Q8z\n\xec]/'

クッキーに基づいたセッションについての注意: Flaskはsessionオブジェクトに置かれた値を取り上げ、クッキーへシリアライズします。もしも複数のリクエストを跨いだ持続をしていない値が(sessionで)見つかり、実際にクッキーは有効であり、そして明確なエラーメッセージを得られないときは、ページのレスポンスにあるクッキーのサイズをチェックし、webブラウザによってサポートされているサイズと比較してください。 A note on cookie-based sessions: Flask will take the values you put into the session object and serialize them into a cookie. If you are finding some values do not persist across requests, cookies are indeed enabled, and you are not getting a clear error message, check the size of the cookie in your page responses compared to the size supported by web browsers.

クライアント側に基づいた標準的なセッションに加えて、もしサーバ側で代わりにセッションを処理したい場合、これをサポートするFlask拡張がいくつかあります。 Besides the default client-side based sessions, if you want to handle sessions on the server-side instead, there are several Flask extensions that support this.

メッセージのフラッシュ表示 Message Flashing

良いアプリケーションおよびユーザインタフェースとは、すべてフィードバック次第です。もしユーザが十分なフィードバックを得られない場合、おそらくアプリケーションを嫌いになって終わりです。Flaskはフラッシュ表示の仕組み(flashing system)によって、ユーザへフィードバックを与える非常にシンプルな方法を提供します。フラッシュ表示の仕組みは、リクエストの最後にメッセージを記録し、次の(ただ次だけの)リクエストでアクセスできるようにします。これは、普通はメッセージを表示するレイアウトのテンプレートと組み合わされます。 Good applications and user interfaces are all about feedback. If the user does not get enough feedback they will probably end up hating the application. Flask provides a really simple way to give feedback to a user with the flashing system. The flashing system basically makes it possible to record a message at the end of a request and access it on the next (and only the next) request. This is usually combined with a layout template to expose the message.

メッセージをフラッシュ表示させるにはflash()メソッドを使用し、メッセージを捉えるには、テンプレートでも利用可能なget_flashed_messages()が使用できます。不足のない(どちらの用法も示した)例についてはMessage Flashingを調べてください。 To flash a message use the :func:`~flask.flash` method, to get hold of the messages you can use :func:`~flask.get_flashed_messages` which is also available in the templates. Check out the :ref:`message-flashing-pattern` for a full example.

ログ機能(Logging) Logging

Changelog

バージョン 0.3 で追加.

ときには、修正すべきであるにもかかわらず修正されていないデータを処理する状況におかれるかもしれません。例えば、明らかに適切でない形式のHTTPリクエストをサーバへ送信するクライアント側のコードがあるかもしれません。これは、ユーザのデータ改ざんや、クライアントのコードの失敗によって引き起こされるかもしれません。その状況では殆どの場合は400 Bad Requestを返せば大丈夫ですが、ときにはそれでは通用せず、コードを動かし続けなければならないことがあります。 Sometimes you might be in a situation where you deal with data that should be correct, but actually is not. For example you may have some client-side code that sends an HTTP request to the server but it's obviously malformed. This might be caused by a user tampering with the data, or the client code failing. Most of the time it's okay to reply with ``400 Bad Request`` in that situation, but sometimes that won't do and the code has to continue working.

起きてしまったそのようなうさんくさい何かをログしたいことがあるかもしれません(You may still want to log that something fishy happened)。これはloggerを重宝する状況です。Flask 0.3以降は、loggerが使用できるように事前設定されています。 You may still want to log that something fishy happened. This is where loggers come in handy. As of Flask 0.3 a logger is preconfigured for you to use.

以下はログを呼び出すいくつかの例です: Here are some example log calls::

app.logger.debug('A value for debugging')
app.logger.warning('A warning occurred (%d apples)', 42)
app.logger.error('An error occurred')

付与されているloggerはPython標準のロギングのLoggerなので、さらなる情報は公式のloggingドキュメントを確認してください。 The attached :attr:`~flask.Flask.logger` is a standard logging :class:`~logging.Logger`, so head over to the official :mod:`logging` docs for more information.

さらに、アプリケーションのエラーも読んでください。 Read more on :ref:`application-errors`.

WSGIミドルウェア内でのフック Hooking in WSGI Middlewares

アプリケーションにWSGIのミドルウェアを追加したい場合は、内部のWSGIアプリケーションをラップできます。例えば、lighttpdのバグへ対処するためにWerkzeugパッケージにあるミドルウェアのひとつを使いたい場合、以下のように実施できます: If you want to add a WSGI middleware to your application you can wrap the internal WSGI application. For example if you want to use one of the middlewares from the Werkzeug package to work around bugs in lighttpd, you can do it like this::

from werkzeug.contrib.fixers import LighttpdCGIRootFix
app.wsgi_app = LighttpdCGIRootFix(app.wsgi_app)

Flask拡張の使用 Using Flask Extensions

(Flask)拡張は、よくあるタスクを達成する手助けをするパッケージです。例えば、Flask-SQLAlchemyはSQLAlchemyのサポートを提供し、シンプルかつ容易にSQLAlchemyをFlaskと一緒に使用できるようにします。 Extensions are packages that help you accomplish common tasks. For example, Flask-SQLAlchemy provides SQLAlchemy support that makes it simple and easy to use with Flask.

Flask拡張についてさらには、Extensionsを調べてください。 For more on Flask extensions, have a look at :ref:`extensions`.

webサーバへのデプロイ Deploying to a Web Server

新しいFlaskアプリをデプロイする準備ができましたか?展開の選択肢(Deployment Options)へ進んでください。 Ready to deploy your new Flask app? Go to :ref:`deployment`.