概要
flasgger でパラメータに path を使っている場合に validation する方法を紹介します
flasgger にはおそらくデフォルトでは path をチェックする機能は備わっていないので自分で実装する必要があります
環境
- macOS X 10.13.6
- Python 3.6.5
- flasgger 0.9.0
Marshmallow Schemas を使って実装したベースアプリ
これをベースに validation 機能を付けてみます
path でパラメータを取るのでこれを validate してみます
- vim app.py
# coding: utf-8
from flask import Flask, jsonify
from flasgger import Schema, Swagger, SwaggerView, fields
class CategorySchema(Schema):
id = fields.Int()
name = fields.Str(required=True)
class PetSchema(Schema):
category = fields.Nested(CategorySchema, many=True)
name = fields.Str()
class RandomView(SwaggerView):
summary = 'A cute furry animal endpoint.'
description = 'Get a random pet'
parameters = [
{
'name': 'id',
'in': 'path',
'required': True,
'type': 'integer'
}
]
responses = {
200: {
'description': 'A pet to be returned',
'schema': PetSchema
}
}
def get(self, id):
pet = {'category': [{'id': id, 'name': 'rodent'}], 'name': 'Mickey'}
return jsonify(PetSchema().dump(pet).data)
app = Flask(__name__)
app.add_url_rule(
'/random/<id>',
view_func=RandomView.as_view('random'),
methods=['GET']
)
if __name__ == '__main__':
app.run(debug=True)
- pipenv run python3 app.py
で起動して
curl localhost:5000/random/1
で以下のようなレスポンスが返ってきます
{
"category": [
{
"id": 1,
"name": "rodent"
}
],
"name": "Mickey"
}
validation 機能を入れる前は文字列でも問題ありません
これが数字以外の場合はエラーになるようにします
validation 機能を追加する
まず import 系を少し追加します
validation 時にエラーのレスポンスを直接返却する必要があるので、それに関するモジュールやクラスを import します
import json
from werkzeug.exceptions import abort
from flask import Response
上記を追加しましょう
そして validation 用のメソッドを追加します
def my_validate(self, id):
try:
int(id)
except ValueError as e:
print(e)
abort(
Response(
json.dumps({'error': 'id must be set integer type', 'id': id}),
status=400
)
)
path で取得した id 情報を validation 用のメソッドに渡します
そして integer に変換できるか調査して、もし Exception が発生したらエラーを返却します
あとはこのメソッドをコールするだけです
def get(self, id):
self.my_validate(id)
pet = {'category': [{'id': id, 'name': 'rodent'}], 'name': 'Mickey'}
return jsonify(PetSchema().dump(pet).data)
修正後の全体のコードは以下の通りです
# coding: utf-8
import json
from werkzeug.exceptions import abort
from flask import Response
from flask import Flask, jsonify
from flasgger import Schema, Swagger, SwaggerView, fields
class CategorySchema(Schema):
id = fields.Int()
name = fields.Str(required=True)
class PetSchema(Schema):
category = fields.Nested(CategorySchema, many=True)
name = fields.Str()
class RandomView(SwaggerView):
summary = 'A cute furry animal endpoint.'
description = 'Get a random pet'
parameters = [
{
'name': 'id',
'in': 'path',
'required': True,
'type': 'integer'
}
]
responses = {
200: {
'description': 'A pet to be returned',
'schema': PetSchema
}
}
def my_validate(self, id):
try:
int(id)
except ValueError as e:
print(e)
abort(
Response(
json.dumps({'error': 'id must be set integer type', 'id': id}),
status=400
)
)
def get(self, id):
self.my_validate(id)
pet = {'category': [{'id': id, 'name': 'rodent'}], 'name': 'Mickey'}
return jsonify(PetSchema().dump(pet).data)
app = Flask(__name__)
app.add_url_rule(
'/random/<id>',
view_func=RandomView.as_view('random'),
methods=['GET']
)
if __name__ == '__main__':
app.run(debug=True)
これで再度実行すると id の部分が文字列の場合にはエラーが返ってくるようになります
curl -v 'localhost:5000/random/a'
{"error": "id must be set integer type", "id": "a"}
validation = True と validation_function = None の機能について
実は flasgger には validation の機構が備わっています
validation
と validation_function
という機能があります
validation
はデフォルトで用意された validator で有効/無効の値しか設定できません
True にした場合に有効になります
やってくれることは例えば
- HTTP メソッドチェック (405 チェック)
- ContType のチェック、application/json かどうかのチェック
- ボディが空でないかのチェック
などです
今回のようにフォーマットチェックなどしたい場合には正直使えません
True にしても余計なことをチェックするケースが多いかなと思います
また validation_function
に関してですがこれは基本的に POST 時のボディを validate するときに使うっぽいです (?)
今回のように path のフォーマットチェックをする場合は素直に validation 用のメソッドを作ってしまうほうが早いです
最後に
flasgger の Marshmallow Schemas で path パラメータをチェックするための独自の validation 機能を実装してみました
おそらくこの方法が一番てっとり早いと思います
途中で軽く触れた validation
と validation_function
の機能に関しても検証してみたいと思います
この辺りの情報はググっても出てこないので Github の issue やコードを見るしか方法がなさそうです
0 件のコメント:
コメントを投稿