記事
· 2022年7月26日 9m read

FlaskとEmbedded Pythonで簡単なWebアプリを作ってみよう!

開発者の皆さん、こんにちは!

Flaskを使うと簡単にWebアプリが作成できるようでしたので、Embedded Pythonを利用してIRISに保存した月毎の歩数データ(テーブル/グローバル)を matplotlibを利用してグラフ表示する簡単なWebアプリを作成してみました。

使っているPythonスクリプトファイルやHTMLは以下の通りです(図例はテーブルからデータを取る例ですが、サンプルにはグローバルからデータを取得する例も含まれます)。

サンプルはこちらに置いています👉https://github.com/Intersystems-jp/WalkSteps

IRISのインストール環境に合わせて、サンプルのディレクトリを分けています。

<Windows にIRISをインストールされている場合>
https://github.com/Intersystems-jp/WalkSteps/tree/master/Windows をご覧ください。
Windows上Pythonのバージョンは3.9で試しています。3.10では動作しませんでしたので、3.9でお試しください。

<Windows以外にIRISをインストールされている場合>
https://github.com/Intersystems-jp/WalkSteps/tree/master/Linux をご覧ください。​​

 

できあがりのイメージは以下の通りです。


 

1) 事前準備について

flaskとmatplitlib を pip でインストールします(Windows上にインストールしたIRISを使う場合もpipでインストールしてください​)。

WindowsにインストールしたIRISを利用する場合のみ、以下ご確認ください。

テーブルからデータを取得する例を試される場合は table_goiris.py の2行目、グローバルからデータを取得する例を試される場合は、global_goiris.py の2行目に記載のある sys.path のディレクトリを変更します。

以下2つのディレクトリを確認し、sys.pathに追加してください。

  • IRISインストールディレクトリ/mgr/python
  • IRISインストールディレクトリ/lib/python

​​例:

sys.path+=['c:\\intersystems\\irishealth\\mgr\\python','c:\\intersystems\\irishealth\\lib\\python']

 

2)画面表示について

画面表示に使用しているHTMLは、index.html で、Flaskの render_template() 関数を利用し、HTTP応答としてHTML文書を返送しています。
​​​(HTMLの継承ができたので、ベースとなるHTMLを base.htmlに作成し、index.htmlの中で {% extends 'base.html' %} と指定して base.html を継承しています)

{% extends 'base.html' %}

{% block body %}
<div class="form">
    <form action="/" method='POST'>
        <H2>{{selectmonth}}月の歩数</H2>
        <div class="alert alert-warning" role="alert">
            <label for="title"> 確認したい月を指定してください。</label>
            <select name="selectmonth">
            {% for month in monthlist %}
                <option value="{{ month }}">{{ month }}月</option>
            {% endfor %}
            </select>
            <input type="submit" value="歩数確認">
        </div>
    </form>
    {% if rdate != "" %}
    <div class="card-body">
        {{ image | safe }}
    </div>
    {% endif %}
</div>
{% endblock %}

 

3)画面表示に使うグラフとデータについて

以下、Linux用ディレクトリ以下にあるコード例で解説しますが、Windowsディレクトリ以下にある内容と大枠に違いはありません。

 

    3-1) テーブルデータを利用する場合

    IRISからデータを取得する処理は、table_goiris.py に記述しています。

    getMonthTbl()関数では、保存されている歩数データの「月」情報をSELECTで取得し、Pythonリストに格納し戻しています。

    def getMonthTbl():
        rs=iris.sql.exec("select DATEPART('MM',RecordDate) As month from MyHealth.Steps group by DATEPART('MM',RecordDate)")
        monthlist=[]
        for row in enumerate(rs):
            monthlist.append(row[1][0]) 
        return monthlist

     

    createChartFromTbl()関数では、指定月の日付と歩数をSELECTで取得し、Pythonリストに格納し戻しています。

    def createChartFromTbl(monthnumber):
        sql="select tochar(RecordDate,'DD'),Steps from MyHealth.Steps WHERE DATEPART('MM',recorddate) = ?"
        stmt=iris.sql.prepare(sql)
        rs=stmt.execute(monthnumber) 
        
        rdate=[]
        steps=[]
        for row in enumerate(rs):
            rdate.append(row[1][0])
            steps.append(row[1][1])
    
        return rdate,steps
    

     

    table_goiris.py で作成したリストを利用して、table_app.pyの中でグラフを生成しています。

    matplotlibで作成したグラフを、HTMLに埋め込む方法については、こちらのページ(https://shiren-blog.com/flask-matplotlib-graph-demo/)を参考にさせていただきました。

    (imgタグのsrcにBase64でエンコードしたグラフのデータをセットし、index.htmlに当てはめる方法をとっています)​​​

    import base64
    from io import BytesIO
    import matplotlib.pyplot as plt
    
    from flask import Flask, render_template, request
    import table_goiris as goiris
    
    app = Flask(__name__)
    
    @app.route('/',methods=['GET','POST'])
    def index():
        #月取得(テーブル編)
        monthlist=goiris.getMonthTbl()
        if request.method=='GET':
            defaultmonth=7
        else:
            result=request.form
            defaultmonth=result['selectmonth']
    
        #print(defaultmonth)
        #データ取得(テーブル編)
        result=goiris.createChartFromTbl(defaultmonth)
    
        rdate=result[0]
        steps=result[1]
    
        #参考にしたページ:https://shiren-blog.com/flask-matplotlib-graph-demo/
        #グラフ作成
        fig = plt.figure(figsize=(10, 5))
        ax = fig.add_subplot(111)
    
        if defaultmonth=="5":
            color="green"
        elif defaultmonth=="6":
            color="orange"
        else:
            color="blue"
        ax.plot(rdate, steps, label="test",marker="o",color=color,linestyle="-.")
        #バッファに保存
        buf=BytesIO()
        fig.savefig(buf,format='png')
        #グラフをHTMLに埋め込むように変換
        data=base64.b64encode(buf.getbuffer()).decode('ascii')
        image_tag = f'<img src="data:image/png;base64,{data}"/>'
        return render_template("index.html",image=image_tag,monthlist=monthlist,selectmonth=defaultmonth)
    
    
    if __name__=="__main__":
        #app.run(debug=True,host='0,0,0,0',port="8081")
        app.run(debug=True,host='0.0.0.0')
    


    3-2) グローバルを利用する場合

    IRISからデータを取得する処理は、global_goiris.py に記述しています。

    getMonthGlo()関数では、保存されている歩数データの「月」情報を取得し、Pythonリストに格納し戻しています(ObjectScriptで$Order()してるのと同じイメージで記述できます)。

    def getMonthGlo():
        glo=iris.gref("^MySteps")
        monthlist=[]
        month=""
        while True:
            month=glo.order([2022,month])
            if (month==None):
                break
            monthlist.append(month)
        return monthlist     

     

    createChartFromGlo()関数では、指定月の日付と歩数を得し、Pythonリストに格納し戻しています(ObjectScriptで$Order()してるのと同じイメージで記述できます)。

    def createChartFromGlo(monthnumber):
        glo=iris.gref("^MySteps")
    
        rdate=[]
        steps=[]
        date=""
        while True:
            date=glo.order([2022,monthnumber,date])
            if (date==None):
                break
            rdate.append(date)
            steps.append(glo[2022,monthnumber,date])
        
        return rdate,steps

     

    global_goiris.py  で作成したリストを利用して、global_app.pyの中でグラフを生成しています。

    matplotlibで作成したグラフを、HTMLに埋め込む方法については、こちらのページ(https://shiren-blog.com/flask-matplotlib-graph-demo/)を参考にさせていただきました。

    (imgタグのsrcにBase64でエンコードしたグラフのデータをセットし、index.htmlに当てはめる方法をとっています)​​​

    import base64
    from io import BytesIO
    import matplotlib.pyplot as plt
    
    from flask import Flask, render_template, request
    import global_goiris as goiris
    
    app = Flask(__name__)
    
    @app.route('/',methods=['GET','POST'])
    def index():
        #月取得(グローバル編)
        monthlist=goiris.getMonthGlo()
        if request.method=='GET':
            defaultmonth=7
        else:
            result=request.form
            defaultmonth=result['selectmonth']
    
        #print(defaultmonth)
        #データ取得(グローバル編)
        result=goiris.createChartFromGlo(defaultmonth)
    
        rdate=result[0]
        steps=result[1]
    
        #参考にしたページ:https://shiren-blog.com/flask-matplotlib-graph-demo/
        #グラフ作成
        fig = plt.figure(figsize=(10, 5))
        ax = fig.add_subplot(111)
    
        if defaultmonth=="5":
            color="green"
        elif defaultmonth=="6":
            color="orange"
        else:
            color="blue"
        ax.plot(rdate, steps, label="test",marker="o",color=color,linestyle="-.")
        #バッファに保存
        buf=BytesIO()
        fig.savefig(buf,format='png')
        #グラフをHTMLに埋め込むように変換
        data=base64.b64encode(buf.getbuffer()).decode('ascii')
        image_tag = f'<img src="data:image/png;base64,{data}"/>'
        return render_template("index.html",image=image_tag,monthlist=monthlist,selectmonth=defaultmonth)
    
    
    if __name__=="__main__":
        #app.run(debug=True,host='0,0,0,0',port="8081")
        app.run(debug=True,host='0.0.0.0')

     

    4)サンプルデータの作成

    サンプルデータの作成に利用するMyHealth.StepクラスをIRISのUSERネームスペースにインポートします。​​​

    • スタジオを利用されている場合は、USERネームスペースに接続先を変更した後、*.cls をスタジオにドラッグ&ドロップするとインポートできます。
    • VSCodeを利用されている場合は、使用するIRISのUSERネームスペースに接続した後、MyHealth.Step.clsをワークスペースで開き、保存します(保存と同時にコンパイルが実行されます)。
    • 管理ポータルからインポートする場合は、管理ポータル > システムエクスプローラ > クラス (USERネームスペース選択) の画面で「インポート」ボタンからインポートできます。

    続いて、IRISにログインし(またはターミナルを開き)USERネームスペースに接続していることを確認し、以下実行します。

    テーブルを利用する場合:

    do ##class(MyHealth.Steps).create()

    グローバルを利用する場合:​​​

    do ##class(MyHealth.Steps).createGlobal()

    ※2022年5月1日~7月31日の歩数データがランダムに作成されます(実行毎に再作成するようにしています)。

     

    5)実行!

    5-1)Windows以外で試す場合

    IRISインストールディレクトリ/bin/irispythonコマンドを利用して table_app.py または global_app.py を実行します。

    impor irisを行うため、irispythonを利用しています。

    IRISインストールディレクトリが、 /usr/irissys である場合の例は以下の通りです(実行環境に合わせてディレクトリはご変更ください)。

    ※実行する table_app.py または global_app.py もフルパスで指定しています。

    テーブル編

    /usr/irissys/bin/irispython /home/isjedu/WalkSteps/Linux/table_app.py

    グローバル編

    /usr/irissys/bin/irispython /home/isjedu/WalkSteps/Linux/global_app.py

     

    5-2)Windowsで試す場合

    実行前の準備が完了しているかご確認ください(リンク先の「3.実行前の確認」をご確認ください)。

    Pythonコマンドの後に、table_app.py または global_app.py をフルパスで指定してください。

    テーブル編

    python c:\WorkSpace\WalkSteps\Windows\table_app.py

    グローバル編

    python c:\WorkSpace\WalkSteps\Windows\global_app.py

     

    いかがでしたでしょうか。FlaskもPythonもとても便利ですね!🐍

    もっと良い方法をご存知の方いらっしゃいましたら、ぜひ共有いただけると嬉しいです!

    コミュニティへの投稿、お待ちしております_(._.)_

     


    👇Embedded Python概要やEmbedded Pythonでデータベースプログラミング(SQLアクセス編)を解説するYouTubeプレイリストとサンプルコード一式公開中です!👇
    【はじめてのInterSystems IRIS】Embedded Python セルフラーニングビデオシリーズ公開!

    ディスカッション (0)1
    続けるにはログインするか新規登録を行ってください