今回は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
データベースとGUI管理ツール
今回はPythonに標準で組み込まれている「SQLite3」を使用します。
SQLiteのGUI管理ツールとして「DB Browser for SQLite」が便利です。以下のURLからダウンロードします。
サイト内の最新バージョン(今回では「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__.py | Python実行時の初期設定をまとめたファイルです。今回では、データベースへの接続設定を主に記述します。 |
---|---|
app.py | Pythonを実行する起動ファイルです。 |
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」ファイルが自動で作成されます。
作成されたデータベースファイルを「DB.Browser.for.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ライブラリを提供しています。
Webサイトでは、各製品の機能を手軽に体験できるデモアプリケーションやトライアル版も公開しておりますので、こちらもご確認ください。
また、ご導入前の製品に関するご相談、ご導入後の各種サービスに関するご質問など、お気軽にお問合せください。