開発者ドキュメント

着信リクエストデータをFlaskで処理する方法

序章

Webアプリケーションでは、ユーザーからの着信要求データを処理する必要があることがよくあります。 このペイロードは、クエリ文字列、フォームデータ、JSONオブジェクトの形をとることができます。 Flask は、他のWebフレームワークと同様に、リクエストデータにアクセスできます。

このチュートリアルでは、クエリ文字列、フォームデータ、またはJSONオブジェクトのいずれかを受け入れる3つのルートを使用してFlaskアプリケーションを構築します。

前提条件

このチュートリアルを完了するには、次のものが必要です。

このチュートリアルは、Pipenv v2020.11.15、Python v3.9.0、およびFlaskv1.1.2で検証されました。

プロジェクトの設定

リクエストのさまざまな使用方法を示すには、Flaskアプリを作成する必要があります。 サンプルアプリはビュー関数とルートに簡略化された構造を使用していますが、このチュートリアルで学習したことは、クラスベースのビュー、ブループリント、Flask-Viaなどの拡張機能などのビューを整理するあらゆる方法に適用できます。

まず、プロジェクトディレクトリを作成する必要があります。 ターミナルを開き、次のコマンドを実行します。

  1. mkdir flask_request_example

次に、新しいディレクトリに移動します。

  1. cd flask_request_example

次に、Flaskをインストールします。 ターミナルを開き、次のコマンドを実行します。

  1. pipenv install Flask

The pipenv コマンドは、このプロジェクトのvirtualenv、Pipfileを作成し、インストールします flask、およびPipfile.lock。

プロジェクトのvirtualenvをアクティブ化するには、次のコマンドを実行します。

  1. pipenv shell

Flaskの受信データにアクセスするには、 request 物体。 The request オブジェクトは、リクエストからのすべての着信データを保持します。これには、mimetype、リファラー、IPアドレス、生データ、HTTPメソッド、ヘッダーなどが含まれます。

すべての情報が request オブジェクトの保持は便利な場合があります。この記事では、エンドポイントの呼び出し元から通常直接提供されるデータに焦点を当てます。

Flaskのリクエストオブジェクトにアクセスするには、Flaskライブラリからリクエストオブジェクトをインポートする必要があります。

from flask import request

その後、任意のビュー機能で使用できるようになります。

コードエディタを使用して、 app.py ファイル。 輸入 Flask そしてその request 物体。 また、 query-example, form-example、 と json-example:

app.py
# import main Flask class and request object
from flask import Flask, request

# create the Flask app
app = Flask(__name__)

@app.route('/query-example')
def query_example():
    return 'Query String Example'

@app.route('/form-example')
def form_example():
    return 'Form Data Example'

@app.route('/json-example')
def json_example():
    return 'JSON Object Example'

if __name__ == '__main__':
    # run app in debug mode on port 5000
    app.run(debug=True, port=5000)

次に、ターミナルを開き、次のコマンドでアプリを起動します。

  1. python app.py

アプリはポート5000で起動するため、次のリンクを使用してブラウザで各ルートを表示できます。

http://127.0.0.1:5000/query-example (or localhost:5000/query-example)
http://127.0.0.1:5000/form-example (or localhost:5000/form-example)
http://127.0.0.1:5000/json-example (or localhost:5000/json-example)

コードは3つのルートを確立し、各ルートにアクセスすると、次のメッセージが表示されます。 "Query String Example", "Form Data Example"、 と "JSON Object Example" それぞれ。

クエリ引数の使用

クエリ文字列に追加するURL引数は、データをWebアプリに渡す一般的な方法です。 Webを閲覧しているときに、以前にクエリ文字列に遭遇した可能性があります。

クエリ文字列は次のようになります。

example.com?arg1=value1&arg2=value2

クエリ文字列は疑問符の後に始まります(?) キャラクター:

example.com?arg1=value1&arg2=value2

また、アンパサンドで区切られたキーと値のペアがあります(&) キャラクター:

example.com?arg1=value1&arg2=value2

ペアごとに、キーの後に等号(=)文字、次に値。

arg1 : value1
arg2 : value2

クエリ文字列は、ユーザーがアクションを実行する必要のないデータを渡す場合に役立ちます。 アプリのどこかでクエリ文字列を生成し、それをURLに追加して、ユーザーがリクエストを行うと、データが自動的に渡されるようにすることができます。 クエリ文字列は、メソッドとしてGETを持つフォームによって生成することもできます。

クエリ文字列をに追加しましょう query-example ルート。 この架空の例では、画面に表示されるプログラミング言語の名前を指定します。 のキーを作成します "language" との値 "Python":

http://127.0.0.1:5000/query-example?language=Python

アプリを実行してそのURLに移動すると、次のメッセージが表示されたままになります。 "Query String Example".

クエリ引数を処理する部分をプログラムする必要があります。 このコードは language いずれかを使用してキー request.args.get('language') また request.args['language'].

電話で request.args.get('language')、アプリケーションは次の場合に実行を継続します language キーがURLに存在しません。 その場合、メソッドの結果は次のようになります。 None.

電話で request.args['language']、アプリが400エラーを返す場合 language キーがURLに存在しません。

クエリ文字列を処理するときは、を使用することをお勧めします request.args.get() アプリが失敗するのを防ぐため。

読んでみましょう language キーを押して出力として表示します。

を変更します query-example ルートイン app.py 次のコードで:

app.py
@app.route('/query-example')
def query_example():
    # if key doesn't exist, returns None
    language = request.args.get('language')

    return '''<h1>The language value is: {}</h1>'''.format(language)

次に、アプリを実行して次のURLに移動します。

http://127.0.0.1:5000/query-example?language=Python

ブラウザに次のメッセージが表示されます。

Output
The language value is: Python

URLからの引数はに割り当てられます language 変数になり、ブラウザに返されます。

クエリ文字列パラメータをさらに追加するには、URLの末尾にアンパサンドと新しいキーと値のペアを追加できます。 のキーを作成します "framework" との値 "Flask":

http://127.0.0.1:5000/query-example?language=Python&framework=Flask

さらに必要な場合は、アンパサンドとキーと値のペアを追加し続けます。 のキーを作成します "website" との値 "DigitalOcean":

http://127.0.0.1:5000/query-example?language=Python&framework=Flask&website=DigitalOcean

これらの値にアクセスするには、引き続きいずれかを使用します request.args.get() また request.args[]. 両方を使用して、キーが欠落している場合に何が起こるかを示しましょう。 を変更します query_example 結果の値を変数に割り当ててから表示するためのルート:

@app.route('/query-example')
def query_example():
    # if key doesn't exist, returns None
    language = request.args.get('language')

    # if key doesn't exist, returns a 400, bad request error
    framework = request.args['framework']

    # if key doesn't exist, returns None
    website = request.args.get('website')

    return '''
              <h1>The language value is: {}</h1>
              <h1>The framework value is: {}</h1>
              <h1>The website value is: {}'''.format(language, framework, website)

次に、アプリを実行して次のURLに移動します。

http://127.0.0.1:5000/query-example?language=Python&framework=Flask&website=DigitalOcean

ブラウザに次のメッセージが表示されます。

Output
The language value is: Python The framework value is: Flask The website value is: DigitalOcean

を削除します language URLからのキー:

http://127.0.0.1:5000/query-example?framework=Flask&website=DigitalOcean

ブラウザは次のメッセージを表示する必要があります None 値が提供されていない場合 language:

Output
The language value is: None The framework value is: Flask The website value is: DigitalOcean

を削除します framework URLからのキー:

http://127.0.0.1:5000/query-example?language=Python&website=DigitalOcean

ブラウザは次の値を期待しているため、エラーが発生するはずです。 framework:

Output
werkzeug.exceptions.BadRequestKeyError werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand. KeyError: 'framework'

これで、クエリ文字列の処理について理解できました。 次のタイプの受信データに進みましょう。

フォームデータの使用

フォームデータは、POSTリクエストとしてルートに送信されたフォームから取得されます。 そのため、URLのデータを表示する代わりに(フォームがGETリクエストで送信された場合を除く)、フォームデータはバックグラウンドでアプリに渡されます。 渡されたフォームデータを簡単に確認することはできませんが、アプリはそれを読み取ることができます。

これを示すために、 form-example ルートイン app.py GETリクエストとPOSTリクエストの両方を受け入れ、フォームを返すには:

app.py
# allow both GET and POST requests
@app.route('/form-example', methods=['GET', 'POST'])
def form_example():
    return '''
              <form method="POST">
                  <div><label>Language: <input type="text" name="language"></label></div>
                  <div><label>Framework: <input type="text" name="framework"></label></div>
                  <input type="submit" value="Submit">
              </form>'''

次に、アプリを実行して次のURLに移動します。

http://127.0.0.1:5000/form-example

ブラウザは、2つの入力フィールドを持つフォームを表示する必要があります。 language と1つ framework -そして送信ボタン。

このフォームについて知っておくべき最も重要なことは、フォームを生成したのと同じルートに対してPOSTリクエストを実行することです。 アプリで読み取られるキーはすべて、 name フォーム入力の属性。 この場合、 languageframework は入力の名前なので、アプリ内の入力にアクセスできます。

ビュー関数内で、リクエストメソッドがGETかPOSTかを確認する必要があります。 GETリクエストの場合は、フォームを表示できます。 それ以外の場合、それがPOST要求である場合は、受信データを処理する必要があります。

を変更します form-example ルートイン app.py 次のコードで:

app.py
# allow both GET and POST requests
@app.route('/form-example', methods=['GET', 'POST'])
def form_example():
    # handle the POST request
    if request.method == 'POST':
        language = request.form.get('language')
        framework = request.form.get('framework')
        return '''
                  <h1>The language value is: {}</h1>
                  <h1>The framework value is: {}</h1>'''.format(language, framework)

    # otherwise handle the GET request
    return '''
           <form method="POST">
               <div><label>Language: <input type="text" name="language"></label></div>
               <div><label>Framework: <input type="text" name="framework"></label></div>
               <input type="submit" value="Submit">
           </form>'''

次に、アプリを実行して次のURLに移動します。

http://127.0.0.1:5000/form-example

記入してください language の値を持つフィールド Python そしてその framework の値を持つフィールド Flask. 次に、送信を押します。

ブラウザに次のメッセージが表示されます。

Output
The language value is: Python The framework value is: Flask

これで、フォームデータの処理について理解できました。 次のタイプの受信データに進みましょう。

JSONデータの使用

JSONデータは通常、ルートを呼び出すプロセスによって構築されます。

JSONオブジェクトの例は次のようになります。

{
    "language" : "Python",
    "framework" : "Flask",
    "website" : "Scotch",
    "version_info" : {
        "python" : "3.9.0",
        "flask" : "1.1.2"
    },
    "examples" : ["query", "form", "json"],
    "boolean_test" : true
}

この構造により、クエリ文字列やフォームデータとは対照的に、はるかに複雑なデータを渡すことができます。 この例では、ネストされたJSONオブジェクトとアイテムの配列が表示されます。 Flaskは、この形式のデータを処理できます。

を変更します form-example ルートイン app.py POSTリクエストを受け入れ、GETなどの他のリクエストを無視するには:

app.py
@app.route('/json-example', methods=['POST'])
def json_example():
    return 'JSON Object Example'

クエリ文字列やフォームデータに使用されるWebブラウザーとは異なり、この記事では、JSONオブジェクトを送信するために、Postmanを使用してカスタムリクエストをURLに送信します。

:リクエストのためにPostmanインターフェースをナビゲートするための支援が必要な場合は、公式ドキュメントを参照してください。

Postmanで、URLを追加し、タイプをPOSTに変更します。 本文タブで、 raw に変更し、ドロップダウンからJSONを選択します。

これらの設定は、PostmanがJSONデータを適切に送信できるようにするために必要です。これにより、FlaskアプリはJSONを受信していることを認識します。

POST http://127.0.0.1:5000/json-example
Body
raw JSON

次に、前のJSONの例をテキスト入力にコピーします。

リクエストを送信すると、次のようになります "JSON Object Example" 応答として。 これはかなり反気候的ですが、JSONデータ応答を処理するためのコードがまだ記述されていないため、予想されます。

データを読み取るには、FlaskがJSONデータをPythonデータ構造に変換する方法を理解する必要があります。

次に、着信JSONデータを読み取るためのコードに取り組みましょう。

まず、JSONオブジェクトから変数にすべてを割り当てましょう request.get_json().

request.get_json() JSONオブジェクトをPythonデータに変換します。 着信要求データを変数に割り当て、次の変更を加えて変数を返します。 json-example ルート:

app.py
# GET requests will be blocked
@app.route('/json-example', methods=['POST'])
def json_example():
    request_data = request.get_json()

    language = request_data['language']
    framework = request_data['framework']

    # two keys are needed because of the nested object
    python_version = request_data['version_info']['python']

    # an index is needed because of the array
    example = request_data['examples'][0]

    boolean_test = request_data['boolean_test']

    return '''
           The language value is: {}
           The framework value is: {}
           The Python version is: {}
           The item at index 0 in the example list is: {}
           The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)

トップレベルにない要素にアクセスする方法に注意してください。 ['version']['python'] ネストされたオブジェクトを入力しているために使用されます。 と ['examples'][0] examples配列の0番目のインデックスにアクセスするために使用されます。

リクエストとともに送信されたJSONオブジェクトに、view関数でアクセスされるキーがない場合、リクエストは失敗します。 キーが存在しないときに失敗したくない場合は、キーにアクセスする前に、キーが存在するかどうかを確認する必要があります。

app.py
# GET requests will be blocked
@app.route('/json-example', methods=['POST'])
def json_example():
    request_data = request.get_json()

    language = None
    framework = None
    python_version = None
    example = None
    boolean_test = None

    if request_data:
        if 'language' in request_data:
            language = request_data['language']

        if 'framework' in request_data:
            framework = request_data['framework']

        if 'version_info' in request_data:
            if 'python' in request_data['version_info']:
                python_version = request_data['version_info']['python']

        if 'examples' in request_data:
            if (type(request_data['examples']) == list) and (len(request_data['examples']) > 0):
                example = request_data['examples'][0]

        if 'boolean_test' in request_data:
            boolean_test = request_data['boolean_test']

    return '''
           The language value is: {}
           The framework value is: {}
           The Python version is: {}
           The item at index 0 in the example list is: {}
           The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)

アプリを実行し、Postmanを使用してサンプルのJSONリクエストを送信します。 応答では、次の出力が得られます。

Output
The language value is: Python The framework value is: Flask The Python version is: 3.9 The item at index 0 in the example list is: query The boolean value is: false

これで、JSONオブジェクトの処理について理解できました。

結論

この記事では、クエリ文字列、フォームデータ、またはJSONオブジェクトのいずれかを受け入れる3つのルートを使用してFlaskアプリケーションを構築しました。

また、すべてのアプローチで、キーが欠落しているときに正常に失敗するという繰り返しの考慮事項に対処する必要があったことを思い出してください。

警告:この記事で取り上げられなかったトピックの1つは、ユーザー入力のサニタイズでした。 ユーザー入力をサニタイズすることで、アプリケーションによって読み取られたデータによって予期しない障害が発生したり、セキュリティ対策が回避されたりすることがなくなります。

Flaskの詳細については、Flaskトピックページで演習とプログラミングプロジェクトを確認してください。

モバイルバージョンを終了