着信リクエストデータをFlaskで処理する方法
序章
Webアプリケーションでは、ユーザーからの着信要求データを処理する必要があることがよくあります。 このペイロードは、クエリ文字列、フォームデータ、JSONオブジェクトの形をとることができます。 Flask は、他のWebフレームワークと同様に、リクエストデータにアクセスできます。
このチュートリアルでは、クエリ文字列、フォームデータ、またはJSONオブジェクトのいずれかを受け入れる3つのルートを使用してFlaskアプリケーションを構築します。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- このプロジェクトでは、Pythonをローカル環境にインストールする必要があります。
- このプロジェクトでは、 Pipenv を使用します。これは、Pythonの世界にすべてのパッケージングの世界の最高のものをもたらすことを目的とした、本番環境に対応したツールです。 Pipfile、pip、およびvirtualenvを1つのコマンドに利用します。
- APIエンドポイントをテストするには、Postmanなどのツールをダウンロードしてインストールする必要があります。
このチュートリアルは、Pipenv v2020.11.15、Python v3.9.0、およびFlaskv1.1.2で検証されました。
プロジェクトの設定
リクエストのさまざまな使用方法を示すには、Flaskアプリを作成する必要があります。 サンプルアプリはビュー関数とルートに簡略化された構造を使用していますが、このチュートリアルで学習したことは、クラスベースのビュー、ブループリント、Flask-Viaなどの拡張機能などのビューを整理するあらゆる方法に適用できます。
まず、プロジェクトディレクトリを作成する必要があります。 ターミナルを開き、次のコマンドを実行します。
- mkdir flask_request_example
次に、新しいディレクトリに移動します。
- cd flask_request_example
次に、Flaskをインストールします。 ターミナルを開き、次のコマンドを実行します。
- pipenv install Flask
The pipenv
コマンドは、このプロジェクトのvirtualenv、Pipfileを作成し、インストールします flask
、およびPipfile.lock。
プロジェクトのvirtualenvをアクティブ化するには、次のコマンドを実行します。
- 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
:
# 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)
次に、ターミナルを開き、次のコマンドでアプリを起動します。
- 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.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
ブラウザに次のメッセージが表示されます。
OutputThe 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
ブラウザに次のメッセージが表示されます。
OutputThe 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
:
OutputThe 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
:
Outputwerkzeug.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リクエストの両方を受け入れ、フォームを返すには:
# 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
フォーム入力の属性。 この場合、 language
と framework
は入力の名前なので、アプリ内の入力にアクセスできます。
ビュー関数内で、リクエストメソッドがGETかPOSTかを確認する必要があります。 GETリクエストの場合は、フォームを表示できます。 それ以外の場合、それがPOST要求である場合は、受信データを処理する必要があります。
を変更します form-example
ルートイン 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
. 次に、送信を押します。
ブラウザに次のメッセージが表示されます。
OutputThe 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.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データ構造に変換する方法を理解する必要があります。
- オブジェクトであるものはすべてPythondictに変換されます。
{"key" : "value"}
JSONではに対応しますsomedict['key']
、Pythonで値を返します。 - JSONの配列は、Pythonのリストに変換されます。 構文は同じなので、リストの例を次に示します。
[1,2,3,4,5]
- JSONオブジェクトの引用符内の値は、Pythonでは文字列になります。
- ブール値
true
とfalse
なるTrue
とFalse
Pythonで。 - 最後に、引用符で囲まれていない数字は、Pythonでは数字になります。
次に、着信JSONデータを読み取るためのコードに取り組みましょう。
まず、JSONオブジェクトから変数にすべてを割り当てましょう request.get_json()
.
request.get_json()
JSONオブジェクトをPythonデータに変換します。 着信要求データを変数に割り当て、次の変更を加えて変数を返します。 json-example
ルート:
# 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関数でアクセスされるキーがない場合、リクエストは失敗します。 キーが存在しないときに失敗したくない場合は、キーにアクセスする前に、キーが存在するかどうかを確認する必要があります。
# 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リクエストを送信します。 応答では、次の出力が得られます。
OutputThe 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トピックページで演習とプログラミングプロジェクトを確認してください。