Help us understand the problem. What is going on with this article?

Flaskで作るAPIのコードサンプル集

More than 1 year has passed since last update.

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

monkeydaichan
コンテナマスター:Kubernetes, helm, istio, Docker, Docker compose クラウドマスター:AWS, Azure, GCP, OCI, AlibabaCloud, IBM
https://daichan.club/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away