Pythonフレームワーク「Flask」でWeb APIを作成する

普段のお仕事に役立つ普遍的なプログラミングTIPSや、業界で注目度が高い最新情報をお届けする「編集部ピックアップ」。
今回はPythonのWebアプリケーションフレームワーク「Flask」でWeb APIを作成する方法ついてお届けします。

Flaskは、Python言語で稼働するWebアプリケーションのフレームワークです。シンプルで軽量な作りであることから簡単にWebアプリケーションを作成できる特徴があります。
今回の記事では、「Flask」を使ってREST APIを作成する方法をご紹介します。

PythonとFlaskのインストール

まずはPythonとFlaskをインストールします。Flaskの導入方法は以下の記事で解説しておりますので、参考にしながらFlaskの実行環境を構築してください。

今回はflask-api-appという名前で環境を作成しAPIを作成していきます。

python -m venv flask-api-app

「flask-api-app」フォルダに移動し、仮想環境を有効化します。

cd flask-api-app
Scripts\activate

Flask-SQLAlchemyのインストール

今回作成するREST APIでは、データベースを使ってGET(参照)、POST(登録)、PUT(更新)、DELET(削除)の処理が行えるようにします。

Flaskにてデータベースとのやり取りを行う方法として「Flask-SQLAlchemy」と呼ばれるライブラリを使います。「Flask-SQLAlchemy」はORM(Object Relational Mapping)としてオブジェクトの関連付けを行ってくれるため、SQL文を作成せずデータベース操作が可能となります。

さらにPythonオブジェクトとJSONデータの変換のために「flask-marshmallow 」と「marshmallow-sqlalchemy」を使用します。

以下のコマンドを入力することでインストールが行えます。
※ 今回の記事では、「C:\Work\Python\Flask」にPythonの実行環境が作成されている前提で進めます。

pip install flask-sqlalchemy flask-marshmallow marshmallow-sqlalchemy
Flask-SQLAlchemyのインストール

データベースとGUI管理ツール

今回はPythonに標準で組み込まれている「SQLite3」を使用します。

SQLiteのGUI管理ツールとして「DB Browser for SQLite」が便利です。以下のURLからダウンロードします。

DB Browser for SQLite

サイト内の最新バージョン(今回では「Version 3.12.2 released」)をクリックし、Downloadsの「DB.Browser.for.SQLite-3.12.2-win64.zip – .zip (no installer) for Win64」から入手します。任意の場所に解凍し、「DB Browser for SQLite.exe」を実行することで起動できます。

REST APIの作成

ここまでの準備が完了したら、FlaskでREST APIを作成していきましょう。「flask-api-app」フォルダ配下に「app.py」ファイルを作成し、さらに「src」フォルダを追加してその配下に「__init__.py」ファイルと「db.py」ファイルを作成します。

ファイルの追加
__init__.pyPython実行時の初期設定をまとめたファイルです。今回では、データベースへの接続設定を主に記述します。
app.pyPythonを実行する起動ファイルです。
db.pyデータベースに対してCRUD処理を行うファイルです。

initファイルの作成

「__init__.py」ファイルの中身を以下のように記述します。

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///order.sqlite3'
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config['JSON_AS_ASCII'] = False #日本語を利用

#SQLAlchemyでデータベース定義
db = SQLAlchemy(app)
ma = Marshmallow(app)

import src.db

app.config['SECRET_KEY']app.config['SQLALCHEMY_DATABASE_URI']では、データベースの設定とセッション情報を暗号化するためのキーを設定します。今回はSQLiteのデータベースファイル名としてorder.sqlite3を指定しています。

app.config["SQLALCHEMY_TRACK_MODIFICATIONS"]trueに設定すると、Flask-SQLAlchemyがオブジェクトの変更を追跡し、警告を出力するようになります。今回はFlask-SQLAlchemyイベントシステムを使用しないためFalseを設定します。

また、FlaskでJSON形式のレスポンスを行うために「flask.jsonify」を使用しますが、デフォルトの文字コードとして「ASCII」が設定されるため日本語を返そうとすると不都合が起きます。

app.config["JSON_AS_ASCII"]Falseにすることで文字コードの設定をUTF-8に変更できるため、日本語等のその他の文字を正しく表示できます。

起動ファイルの作成

「app.py」ファイルの中身を以下のように記述します。

import sys
sys.dont_write_bytecode = True

from src import app

if __name__ == '__main__':
    app.run(debug=True)

このファイルが直接実行されたときに実行される処理を記述します。debug=Trueを指定することデバッグモードでアプリケーションを起動し、実行時にコンソール上に情報を表示します。

dbファイルの作成

「db.py」ファイルの中身を以下のように記述し、データベースモデルの定義を行います。

from src import app
from src import db
from src import ma
from flask import Flask, render_template, request, redirect, jsonify
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Column, Integer, String, desc

# DBの作成
class Order(db.Model):
    __tablename__ = 'Order'
    id = db.Column(Integer, primary_key=True) #連番(主キー)
    product = db.Column(String(32)) #受注した製品名
    date = db.Column(String(8)) #受注日
    amount = db.Column(Integer) #受注した数量

今回は以下の項目を管理するテーブルを作成します。

項目名フィールド型説明
id数値型連番(キー項目)
product文字列型受注した製品名
date文字列型(日付)
※SQLiteでは日付型はないため文字列型で管理する
受注日
amount数値型受注した数量

次に、データベースを作成するための関数を作成します。before_first_requestを使用して、APIに初めてリクエストが送信されたときにだけデータベースの作成を行います。

・・・(中略)・・・
@app.before_first_request
def init():
    db.create_all()

次にJSON出力用のスキーマを定義し、データを全件取得して返却するGETの処理を記述します。

@app.route()はURLと関数の関連付けを行います。ここでは「http:// 127.0.0.1:5000/order」にアクセスするとgetAll()関数が呼び出されます。また、methodsでは、HTTPメソッドを指定しています。

・・・(中略)・・・
class OrderSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Order
order_schema = OrderSchema(many=True)

#GET(全件参照)
@app.route('/order', methods=["GET"])
def getAll():
    data = Order.query.all()
    return jsonify(order_schema.dump(data))

ここで一度Web APIを実行してみます。以下のコマンドを実行し、APIを起動します。

flask run

APIを起動したら、Postmanなどのツールを使用してリクエストを送信し、テストを兼ねてデータベースの作成を行います。

http://127.0.0.1:5000/order」に対してGETリクエストを実行すると空のデータが返却されます。

「var\src-instance」フォルダ配下に「order.sqlite3」ファイルが自動で作成されます。

作成されたSQLiteファイル

作成されたデータベースファイルを「DB.Browser.for.SQLite」で確認すると、定義されたモデルで作成されていることが確認できます。

SQLiteファイルの中身

続いて同ファイルに以下を追加し、GET(1件参照)、POST(登録)、PUT(更新)、DELETE(削除)の処理も追加していきます。

・・・(中略)・・・
#GET(1件参照)
@app.route('/order/<int:id>', methods=["GET"])
def get(id):
    
    data = Order.query.filter_by(id=id).all() 
    return jsonify(order_schema.dump(data))

#POST(登録)
@app.route('/order', methods=["POST"])
def post():
    entry = Order()
    # jsonリクエストから値取得
    json = request.get_json()
    if type(json) == list:
        data = json[0]
    else:
        data = json
    entry.product = data["product"]
    entry.date = data["date"]
    entry.amount = data["amount"]
    db.session.add(entry)
    db.session.commit()
    db.session.close()

    latestdata= Order.query.order_by(desc(Order.id)).first()   
    return redirect('/order/' + str(latestdata.id))

#PUT(更新)
@app.route('/order/<int:id>', methods=["PUT"])
def put(id):
    entry = Order.query.get(id)
    # jsonリクエストから値取得
    json = request.get_json()
    if type(json) == list:
        data = json[0]
    else:
        data = json
    entry.product = data["product"]
    entry.date = data["date"]
    entry.amount = data["amount"]
    db.session.merge(entry)
    db.session.commit()
    db.session.close()

    return redirect('/order/' + str(id))

#DELETE(削除)
@app.route('/order/<int:id>', methods=["DELETE"])
def delete(id):
    entry = Order.query.get(id)
    db.session.delete(entry)
    db.session.commit()    
    db.session.close()

    return '', 204

動作確認

以上でAPIの作成は完了です。それぞれリクエストを送信して動作確認してみます。

POST(登録)

http://127.0.0.1:5000/order」に対してPOSTリクエストを実行します。以下のJSONをBodyに追加して実行します。

[
    {
        "amount": 200,
        "date": "2022-10-01",
        "product": "コーヒービター"
    }
]

データベースファイルを確認すると、リクエストで送信した値が登録されています。

登録されたデータ

PUT(更新)

http://127.0.0.1:5000/order/1」に対してPUTリクエストを実行します。以下のJSONをBodyに追加して実行します。

[
    {
        "amount": 300,
        "date": "2022-10-15",
        "product": "コーヒーマイルド"
    }
]

データベースファイルを確認すると、リクエストで送信した値でデータが更新されています。

更新されたデータ

DELETE(削除)

http://127.0.0.1:5000/order/1」に対してDELETEリクエストを実行します。

データベースファイルを確認すると、id=1のデータが削除されています。

削除されたデータ

GET(全件参照)

すでにGETリクエストが動作確認済みですが、POSTで何件かデータを登録し、全件取得の処理を確認してみます。データを登録後に「http://127.0.0.1:5000/order」に対してGETリクエストを実行します。

GET(1件参照)

http://127.0.0.1:5000/order/3」のように、URLにidを追加することで、1件だけのデータを取得することもできます。

さいごに

以上がFlaskでWeb APIを実装する方法でした。次回はこのAPIと弊社のJavaScriptライブラリの連携方法についてご紹介したいと思います。

Flaskで業務アプリのUIを開発するには?

グレープシティでは、Flaskとも連携可能な、業務システム開発で使えるJavaScriptライブラリを提供しています。

グレープシティのJavaScriptライブラリ
グレープシティのJavaScriptライブラリ

Webサイトでは、各製品の機能を手軽に体験できるデモアプリケーションやトライアル版も公開しておりますので、こちらもご確認ください。

また、ご導入前の製品に関するご相談、ご導入後の各種サービスに関するご質問など、お気軽にお問合せください。

\  この記事をシェアする  /