はじめに
AIバックエンドをもったwebアプリを開発するにあたり、FlaskとReactの連携を試すことにしました。Pythonで記述したデータ生成メソッドやAiによる推論メソッドをFlaskアプリにまとめ、Reactアプリから問い合わせることでweb UIへの表示を目指します。
githubリポジトリはこちらです。
VScodeのターミナルから、cmdとPowershellを使用しています。
node.jsとnpmのインストール
準備として、node.jsのインストールをします。以下を実行します。
winget install OpenJS.NodeJS.LTS
cmdで以下を実行し、node.js, npm, TypeScriptが正しくインストールできているか確認します。それぞれのバージョンが表示されれば成功です。
node -v
npm -v
tsc -v
インストールのトラブルシュートはこちらをご覧ください。
目標
以下に今回の目標を示します。
- Flask アプリで JSON データを生成
- React 側から API 通信でデータを取得し、表示
本来Flaskアプリケーションを導入した目的はAIバックエンドを持たせるためなのですが、今回は簡単なデモとして商品の在庫や定価のデータを生成するアプリにしておきます。
[React UI] → fetch API → [Flask API] → generate JSON → [Reactで表示]
React アプリは localhost:3000 で動かし、localhost:5000 で動く Flask アプリにAPIリクエストを送ってデータを取得します。
React側の作業
先にReactアプリを構築します。
React+TypeScriptテンプレート
cmdで以下を実行します。
npx create-react-app sample --template typescript
"sample"の部分は任意の名称でかまいません。
このコマンドを実行すると、 React + TypeScript の開発環境を簡単に用意することができます。
以下のような確認が出ますが、y を入力 + Enterで進行できます。
Need to install the following packages:
create-react-app@5.1.0
Ok to proceed? (y)
このコマンドの実行には数分かかります。完了すると、以下のようなディレクトリ構造を持つテンプレートが作成されます。
この状態でsampleディレクトリに移動すると、localhost:3000 でReactアプリを起動することができます。
cd sample
npm start
作成するファイル
この時点で、sample/src/ 下に App.tsx が作られています。これが React アプリの本体のようなもので、アプリ全体のルートコンポーネントになっています。
これに加えて、これから以下のファイルを作成します。
- types/Data.ts
せっかくTypeScriptを使用するので、データの型を定義します。 - services/DataService.ts
React側でAPI通信を実装します。ReactアプリケーションからバックエンドAPIに選手データを取得するための非同期関数を定義します。具体的には、データをバックエンド(localhost:5000)から取得して、React側で使えるようにする関数fetchDataを定義し、外部から呼べるようにexportしておきます。 - components/Datalist.tsx
データリスト表示コンポーネントです。
データの型の定義
types/Data.tsを追加して、データの型を定義します。
// src/types/Data.ts
export interface Data {
id: string;
name: string;
price: number;
stock: number;
}
APIリクエスト
services/DataService.tsを追加して、APIリクエストでFlaskアプリからデータを取得できるようにします。
//React側でAPI通信を実装
// src/services/playerService.ts
import { Data } from "../types/Data";
export const fetchData = async (count: number): Promise<Data[]> => {
const response = await fetch(`http://localhost:5000/api/data?count=${count}`);
if (!response.ok) {
throw new Error("データの取得に失敗しました");
}
const data = await response.json();
console.log(data)
return data;
};
データリスト表示コンポーネント
components/Datalist.tsxを追加して、取得したデータをwebUIへ表示できるようにします。
import React, { useEffect, useState } from "react";
import { Data } from "../types/Data";
import { fetchData } from "../services/Dataservice";
const DataList: React.FC = () => {
const [data, setData] = useState<Data[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchData(3)
.then((data) => {
setData(data);
setLoading(false);
})
.catch((err) => {
console.error(err);
setLoading(false);
});
}, []);
if (loading) return <p>読み込み中...</p>;
return (
<div>
<h2>商品一覧(APIから取得)</h2>
<ul>
{data.map((d) => (
<li key={d.id}>
{d.name} - 定価:{d.price} 在庫:{d.stock}
</li>
))}
</ul>
</div>
);
};
export default DataList;
App.tsxの変更
components/Datalist.tsxで作成したDatalistを表示するようにアプリ本体を書き換えます。
// src/App.tsx
import React from "react";
import DataList from "./components/Datalist";
const App: React.FC = () => {
return (
<div>
<DataList />
</div>
);
};
export default App;
Flask側の作業
APIを実装するディレクトリ
現在ルートディレクトリ下には sample/ が存在していますが、Flaskアプリを実装するディレクトリは分けたいと思います。
cmdで以下を実行します。
mkdir api
これで api/ というディレクトリが作成されます。
Python仮想環境作成・必要なライブラリのインストール
環境を汚染しないために、Python仮想環境を作成します。仮想環境名は無難にvenvとしておきます。
Powershellで以下を実行します。
cd api
python -m venv venv
venv/Scripts/Activate
これで venv 仮想環境に入って作業できます。
インストールが必要なライブラリは以下です。
ライブラリ | 用途 |
---|---|
Flask | Flaskアプリ |
Flask-Cors | CORS(クロスオリジン)の許容 |
Powershellで以下を実行してインストールをします。
pip install Flask
pip install Flask-Cors
作成するファイル
-
api/data_generater.py
データ生成のために、generate_data 関数を定義します。 -
api/app.py
flaskアプリ本体です。data_generaterからgenerate_data関数をimportします。/api/data エンドポイントに対して、生成したデータをjson形式で返します。
データ生成メソッドの追加
api/data_generator.py を追加して、適当なデータ生成メソッドを用意します。
import random
import uuid
class DataGenerator:
def __init__(self):
self.namelist = ["キャベツ", "人参", "玉ねぎ", "水菜", "ほうれん草", "レタス"]
self.pricelist = [198,298,398]
self.stocklist = [10,20,30,40,50]
def generate(self):
return{
"id" : str(uuid.uuid4()),
"name" : random.choice(self.namelist),
"price" : random.choice(self.pricelist),
"stock" : random.choice(self.stocklist)
}
def generate_data(times:int):
datagenerator = DataGenerator()
data=[]
for i in range(times):
newdata = datagenerator.generate()
data.append(newdata)
return data
Flaskアプリ本体の用意
api/app.py を追加します。/api/data エンドポイントの動作を定義します。
from flask import Flask, jsonify, request
from data_generator import generate_data
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@app.route("/api/data", methods=["GET"])
def get_players():
count = int(request.args.get("count", 3))
data = generate_data(count)
return jsonify(data)
if __name__ == "__main__":
app.run(debug=True)
動作確認
以上で準備が整いました。それでは、まず Flaskアプリの方を走らせます。
apiディレクトリにいることを確認した後、Powershellで仮想環境venvに入ったまま、以下を実行します。
python app.py
成功すると localhost:5000 でflaskアプリが走ります。
この状態で、React アプリを起動します。sampleディレクトリに戻り、cmd で以下を実行します。
npm start
これで Reactアプリが localhost:3000で起動します。実行するとブラウザが起動し、画面に以下のようなDatalist が表示されるのを確認できます。
最後に
Flask と React を組み合わせた開発の方法を簡単に見てきました。今回のFlaskアプリは単なるデータ生成に過ぎないものでしたが、ゆくゆくはAIモデルによる推論結果を返すものにいたします。React側も単なる表示ではなく、画面遷移を実現したり、UIを改善したりと改善点はたくさんあります。webアプリを作る方どなたかのお役に立てば幸いです。