FlaskでAPIを作りました.
そのときに調べた情報がチュートリアルレベルが多かったので,実際に書いたコードを紹介できればと.
随時追記していきます.
対象者
FlaskでちょっとしたAPI作りたい
環境
- Mac
- Python 3.6.0
- Flask==1.0.2
- Flask-API==1.1
ソース
ここにおいてます.
https://github.com/monkeydaichan/flask-sample
Code
JsonをPostしてJsonが返ってくるPostAPI
postするjsonのデータは{"name":"monkeydaichan"}
です.
戻り値は{"data":{"id":1,"name":"monkeydaichan"}}
こうしてます.
# coding:utf-8
import json
from flask import Flask, jsonify, make_response, request, Response
app = Flask(__name__)
@app.route('/post', methods=['POST'])
def post_json():
json = request.get_json() # Get POST JSON
NAME = json['name']
result = {
"data": {
"id": 1,
"name": NAME
}
}
return jsonify(result)
if __name__ == "__main__":
app.run()
アクセスしてみる
$ curl -X POST -H "Content-Type: application/json" -d '{"name":"monkeydaichan"}' http://localhost:5000/post
{"data":{"id":1,"name":"monkeydaichan"}}
URLパラメータを取得してJsonが返ってくるGetAPI
URLから値を取得してJsonを返すAPIです.
/api/ にアクセスると{"data":{"id":1,"name":"monkeydaichan"}}
が返ってきます.
# coding:utf-8
import json
from flask import Flask, jsonify, make_response, request, Response
app = Flask(__name__)
@app.route('/api/<name>', methods=['GET'])
def get_json(name):
NAME = name
result = {
"data": {
"id": 1,
"name": NAME
}
}
return jsonify(result)
if __name__ == "__main__":
app.run()
アクセスしてみる.
$ curl -X GET -H "Content-Type: application/json" http://localhost:5000/api/monkeydaichan
{"data":{"id":1,"name":"monkeydaichan"}}
エラーハンドリング
デコレーターを利用したエラーハンドリング
JsonをPostしてJsonが返ってくるPostAPIこのAPIのhttp://localhost/pos
という定義されていないAPIにアクセスします.
# coding:utf-8
import json
from flask import Flask, jsonify, make_response, request, Response
from flask_api import status
app = Flask(__name__)
@app.route('/post', methods=['POST'])
def post_json():
try:
json = request.get_json() # Get POST JSON
NAME = json['name']
result = {
"data": {
"id": 1,
"name": NAME
}
}
return jsonify(result)
except Exception as e:
result = error_handler(e)
return result
@app.errorhandler(400)
@app.errorhandler(404)
@app.errorhandler(500)
def error_handler(error):
response = jsonify({
"error": {
"type": error.name,
"message": error.description
}
})
return response, error.code
if __name__ == "__main__":
app.debug=True
app.run(host='0.0.0.0')
アクセスしてみる
$ curl -X POST -H "Content-Type: application/json" -d '{"name":"monkeydaichan"}' http://localhost:5000/pos
{
"error": {
"message": "The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.",
"type": "Not Found"
}
}
Flaskのログにも404エラーが表示されています.
127.0.0.1 - - [09/Feb/2019 20:22:01] "POST /pos HTTP/1.1" 404 -
関数のExceptionを拾って任意のステータスコードを返す
JsonをPostしてJsonが返ってくるPostAPIこのAPIにnameキーがなかった場合のエラーハンドリングを実装します.
Requestするjsonは{"hoge":"monkeydaichan"}
として,statusCodeをセットするためにflask_api
をインポートしています.
# coding:utf-8
import json
from flask import Flask, jsonify, make_response, request, Response
from flask_api import status
app = Flask(__name__)
@app.route('/post', methods=['POST'])
def post_json():
try:
json = request.get_json() # Get POST JSON
NAME = json['name']
result = {
"data": {
"id": 1,
"name": NAME
}
}
return jsonify(result)
except Exception as e:
result = errorhandling(e)
return result, status.HTTP_500_INTERNAL_SERVER_ERROR
def errorhandling(error):
exception_type = error.__class__.__name__
exception_message = str(error)
result_error = {
"error": {
"type": exception_type,
"message": exception_message
}
}
return jsonify(result_error)
if __name__ == "__main__":
app.debug=True
app.run(host='0.0.0.0')
アクセスしてみる.
$curl -X POST -H "Content-Type: application/json" -d '{"hoge":"monkeydaichan"}' http://localhost:5000/post
{
"error": {
"message": "'name'",
"type": "KeyError"
}
}
Flaskのログにも500エラーが表示されています.
127.0.0.1 - - [09/Feb/2019 20:13:20] "POST /post HTTP/1.1" 500 -
POSTへのリクエストをPOSTへリダイレクトする
/postに来たリクエストを/fooにリダイレクトしています.
redirect(url_for('foo'), code=307)
コード307を追加しないと動きませんでした...
import json
from flask import Flask, jsonify, make_response, request, Response, redirect, url_for
from flask_api import status
app = Flask(__name__)
@app.route('/post', methods=['POST'])
def hello():
return redirect(url_for('foo'), code=307)
@app.route('/foo', methods=['POST'])
def foo():
json = request.get_json()
name = json['name']
result = {
"name": name
}
return jsonify(result)
if __name__ == "__main__":
app.debug=True
app.run(host='0.0.0.0')
アクセスしてみる.
$curl -X POST -H "Content-Type: application/json" -d '{"name":"monkeydaichan"}' http://localhost:5000/post
{
"name": "monkeydaichan"
}
Reference
https://inokara.hateblo.jp/entry/2016/10/01/123923
https://qiita.com/5zm/items/c8384aa7b7aae924135c
https://qiita.com/kohbis/items/f3156f822bac330494fd
https://mabui.org/python-post-api-flask/
https://student-engineer.net/flask-api/
https://medium.com/nyle-engineering-blog/flask%E3%81%A7rest-api%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B-fad8ae1fde5c