当サイトは、アフィリエイト広告を利用しています

【Flask】Flask-RESTfulのabort関数の使い方

作成日:2024月04月06日
更新日:2024年04月06日

flaskのREST APIを効率的に実装するためのライブラリである
「Flask-RESTful」のabort関数の使い方を調べたのでまとめておく

「Flask-RESTful」自体の使い方については下記記事でまとめています

Flask-RESTfulのabort関数とは?

abort関数は、エラーメッセージとHTTPステータスコードをクライアントに返すための
Flask-RESTfulの組み込み関数

特定のHTTPステータスコードとともにエラーレスポンスを直ちに送信するために使う。
要は条件が満たされない場合(エラー)にリクエストを直ちに終了させることができる。

Flaskのabort関数との違い

abort関数は

  • flaskのabort関数
  • Flask-RESTfulのabort関数

と2種類ある
今回はFlask-RESTfulのabort関数の使い方をまとめる

違いとしては、Flask-RESTfulのabort関数は
基本的にはflaskのabort関数と同じでHTTPエラーコードを指定してAPIエラーを発生させるために使用されるが
より詳細なエラーハンドリングやエラーメッセージのカスタマイズが可能で
エラーレスポンスをJSON形式で変えることができる

Flask-RESTfulを使う場合は、Flask-RESTfulのabort関数を使う方が
効率的に実装できる

abort関数のインストール

abort関数はflaskのflask_restfulに含まれているため
pipでflaskとflask_restfulをインストールする必要がある

pip
# インストール
pip install flask flask_restful
# 確認
pip show flask flask_restful
Name: Flask
Version: 3.0.2
Summary: A simple framework for building complex web applications.
Home-page:
Author:
Author-email:
License:
Location: /usr/local/lib/python3.12/site-packages
Requires: blinker, click, itsdangerous, Jinja2, Werkzeug
Required-by: Flask-Cors, Flask-RESTful
---
Name: Flask-RESTful
Version: 0.3.10
Summary: Simple framework for creating REST APIs
Home-page: https://www.github.com/flask-restful/flask-restful/
Author: Twilio API Team
Author-email: help@twilio.com
License: BSD
Location: /usr/local/lib/python3.12/site-packages
Requires: aniso8601, Flask, pytz, six
Required-by:
  • FlaskはVersion: 3.0.2、Flask-RESTfulはVersion: 0.3.10で動作を確認する

abort関数の基本と構文

abort関数はflask_restfulからimportして使う
そして、abort関数の基本構文は下記になる

abort関数
from flask_restful import abort
abort(400,status="404",message="not found",description="error")
  • 第一引数:HTTPステータスコードを指定。第一位引数のみ必須
  • 第二引数以降:任意の値を設定できる(何個でも)。設定した値はJSON形式で返却される。必須ではない

上記のレスポンスは下記になる

response
{
"status": "404",
"message": "not found",
"description": "error"
}

後述するがこれは「カスタムメッセージ」という使い方になる

abort関数の使い方

abort関数には下記の使い方ができる

  • デフォルト
  • カスタムエラーハンドリング

それぞれの使い方を整理する

デフォルト

デフォルトとはabort関数の第一引数のみ設定して使う使い方
Flask-RESTfulの内部で定義されているデフォルトメッセージが表示される

api.py
from flask import Flask, request
from flask_restful import Api, Resource,abort
import copy
# flaskインスタンス作成
api = Flask(__name__)
# flask_restfulのApiインスタンス作成
flask_api = Api(api)
# ディクショナリ
users = [
{"user_id": "1", "name": "tujimura", "age": 11},
{"user_id": "2", "name": "mori", "age": 20},
{"user_id": "3", "name": "shimada", "age": 50},
{"user_id": "4", "name": "kyogoku", "age": 70}]
# flask_restfulのルーティング
class UserAPI(Resource):
# 取得
# HTTPリクエストにクエリパラメータあり
# 全件取得 or ageフィルタリング
def get(self):
age = request.args.get('age')
if age:
result = list(filter(lambda user: user['age'] == int(age), users))
if result:
return result
else:
abort(404)
return users
# エンドポイントを設定
flask_api.add_resource(UserAPI, '/flaskRestful')
  • abort関数で第一引数のみ設定する

usersに存在しないage=99をクエリパラメータに指定してリクエストを送ると
デフォルトメッセージのみが返却される

response
{
"message": "The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."
}

カスタムエラーハンドリングその1

デフォルトとはabort関数の第一引数と第二引数以上を設定して使う使い方

api.py
from flask import Flask, request
from flask_restful import Api, Resource,abort
import copy
# flaskインスタンス作成
api = Flask(__name__)
# flask_restfulのApiインスタンス作成
flask_api = Api(api)
# ディクショナリ
users = [
{"user_id": "1", "name": "tujimura", "age": 11},
{"user_id": "2", "name": "mori", "age": 20},
{"user_id": "3", "name": "shimada", "age": 50},
{"user_id": "4", "name": "kyogoku", "age": 70}]
# flask_restfulのルーティング
class UserAPI(Resource):
# 取得
# HTTPリクエストにクエリパラメータあり
# 全件取得 or ageフィルタリング
def get(self):
age = request.args.get('age')
if age:
result = list(filter(lambda user: user['age'] == int(age), users))
if result:
return result
else:
abort(404, status=404, message=f'指定された年齢{age}歳のユーザーは存在しません',users=users)
return users
# エンドポイントを設定
flask_api.add_resource(UserAPI, '/flaskRestful')
  • abort関数で第一引数を設定する
  • abort関数で第二、三、四引数としてステータスとメッセージ、ディクショナリを設定する

usersに存在しないage=99をクエリパラメータに指定してリクエストを送る
と第二以降で指定したものがJSON形式で返却される

response
{
"status": 404,
"message": "指定された年齢99歳のユーザーは存在しません",
"users": [
{
"user_id": "1",
"name": "tujimura",
"age": 11
},
{
"user_id": "2",
"name": "mori",
"age": 20
},
{
"user_id": "3",
"name": "shimada",
"age": 50
},
{
"user_id": "4",
"name": "kyogoku",
"age": 70
}
]
}

カスタムエラーハンドリングその2~エラー関数にする~

エラーレスポンスの型が決まっているなら外部で定義した関数内で
abort関数を使ったほうが効率的になる

api.py
from flask import Flask, request
from flask_restful import Api, Resource,abort
import copy
# flaskインスタンス作成
api = Flask(__name__)
# flask_restfulのApiインスタンス作成
flask_api = Api(api)
# ディクショナリ
users = [
{"user_id": "1", "name": "tujimura", "age": 11},
{"user_id": "2", "name": "mori", "age": 20},
{"user_id": "3", "name": "shimada", "age": 50},
{"user_id": "4", "name": "kyogoku", "age": 70}]
# エラー関数
def make_error_message(code,status,message):
abort(code, status=status,message=message)
# flask_restfulのルーティング
class UserAPI(Resource):
# 取得
# HTTPリクエストにクエリパラメータあり
# 全件取得 or ageフィルタリング
def get(self):
age = request.args.get('age')
if age:
result = list(filter(lambda user: user['age'] == int(age), users))
if result:
return result
else:
make_error_message(404,status=404,message=f'指定された年齢{age}歳のユーザーは存在しません')
return users
# エンドポイントを設定
flask_api.add_resource(UserAPI, '/flaskRestful')
  • 外部定義したmake_error_message関数内でabort関数を使う

usersに存在しないage=99をクエリパラメータに指定してリクエストを送ると
第二以降で指定したものがJSON形式で返却される

response
{
"status": 404,
"message": "指定された年齢99歳のユーザーは存在しません"
}

カスタムエラーハンドリングその2~上書き~

カスタムエラーハンドリングにもう一パターンある
Flask-RESTfulの内部で定義されているデフォルトメッセージ自体を
上書きすることができる

api.py
from flask import Flask, request
from flask_restful import Api, Resource,abort
import copy
# flaskインスタンス作成
api = Flask(__name__)
# デフォルト上書き
errors={
"NotFound":{
'message':'指定されたユーザーは存在しません',
'status':404
},
"Conflict":{
'message':'重複しています',
'status':409
}
}
# flask_restfulのApiインスタンス作成
flask_api = Api(api,errors=errors)
# ディクショナリ
users = [
{"user_id": "1", "name": "tujimura", "age": 11},
{"user_id": "2", "name": "mori", "age": 20},
{"user_id": "3", "name": "shimada", "age": 50},
{"user_id": "4", "name": "kyogoku", "age": 70}]
# flask_restfulのルーティング
class UserAPI(Resource):
# 取得
# HTTPリクエストにクエリパラメータあり
# 全件取得 or ageフィルタリング
def get(self):
age = request.args.get('age')
if age:
result = list(filter(lambda user: user['age'] == int(age), users))
if result:
return result
else:
abort(404)
return users
# エンドポイントを設定
flask_api.add_resource(UserAPI, '/flaskRestful')
  • Apiインスタンス作成時にerrosとして渡すことで上書きできる

usersに存在しないage=99をクエリパラメータに指定してリクエストを送る
と上書きされたメッセージが表示される

response
{
"message": "指定されたユーザーは存在しません",
"status": 404
}

HTTPステータスコード名をキーにして紐づけているので、errorsディクショナリの「NotFound」が「Not Found」になってたりすると紐づけが失敗して
デフォルトメッセージがそのまま表示されるので注意

また一般的なHTTPステータスコード名の上書きしかできない
例えば下記のように自分で作ったカスタムメッセージなどは作ることができない

api.py
from flask import Flask, request
from flask_restful import Api, Resource,abort
import copy
# flaskインスタンス作成
api = Flask(__name__)
# デフォルト上書き
errors={
"NotFound":{
'message':'指定されたユーザーは存在しません',
'status':404
},
"Conflict":{
'message':'重複しています',
'status':409
},
"Error":{
'message':'エラー',
'status':444
}
}
# flask_restfulのApiインスタンス作成
flask_api = Api(api,errors=errors)
# ディクショナリ
users = [
{"user_id": "1", "name": "tujimura", "age": 11},
{"user_id": "2", "name": "mori", "age": 20},
{"user_id": "3", "name": "shimada", "age": 50},
{"user_id": "4", "name": "kyogoku", "age": 70}]
# flask_restfulのルーティング
class UserAPI(Resource):
# 取得
# HTTPリクエストにクエリパラメータあり
# 全件取得 or ageフィルタリング
def get(self):
age = request.args.get('age')
if age:
result = list(filter(lambda user: user['age'] == int(age), users))
if result:
return result
else:
abort(444)
return users
# エンドポイントを設定
flask_api.add_resource(UserAPI, '/flaskRestful')

あくまで上書きできるだけ。
上書きしてしまうと他の場所で呼び出したabort(404)のレスポンスも全部それになってしまうので
正直あまり実用性はなさそう

まとめ

flask_restfulのabort関数の使い方をまとめてみた。
基本的にはカスタムエラーハンドリングを使うことが多そう。

参考

関連記事

新着記事

タグ別一覧
top