Fask で作った住所録アプリで下のような実験をしてみてください。
アプリの外からデータを送り込む実験
まず、住所録アプリを起動します。環境設定を行うコマンド等の説明は省略しています。
1 |
$ python3 app.py |
http://localhost:5000 をブラウザで表示するとこれまでに入力したデータが表示されているはずです。この状態で、別のターミナルウインドウ(WindowsならWSL、Macならターミナル)を開いて次のコマンドを実行してみてください。
1 |
$ curl "http://localhost:5000/checkin?name=TANAKA&address=UnitedStateOfAmerica" |
ブラウザで開いていた http://localhost:5000 の表示はすぐには変わりませんが、画面を更新表示するとこの様になっているはずです。
これは何が起きたのか考えてみましょう。
住所録アプリの住所入力画面はHTMLのフォーム <form>〜</form> で記述されており、データは Python プログラムの def checkin() 関数内で受け取っていました。このとき POST メソッドによってデータ送信されます。ソースコードではこの部分です。
1 2 3 4 5 6 |
@app.route('/checkin', methods=['GET', 'POST']) def checkin(): try: if request.method == 'POST': name = request.form['name'] address = request.form['address'] |
上の実験で実行した curl コマンドは、http://localhost:5000/checkin というURLに GET メソッドを使って name=TANAKA および address=UnitedStateOfAmerica というパラメータを送る命令です。Python プログラムには実は GET メソッドに対する処理も書いてあって、それはこの部分です。
1 2 3 |
else: name = request.args.get('name', '') address = request.args.get('address', '') |
以上の事実が意味することは、WEBアプリに対して、別のシステムやデバイスからネットワーク経由でデータを送ることができるということです。例えばその用途として、センサを持ったマイコンボードからデータを送信して、WEBアプリで受信し、データの処理・管理を行うというシステムが考えられます。
色々な用語が出てきて混乱したかもしれません。以下の内容に進む前に、ひとつづつ調べて疑問がないようにしてください。
センサ・データを受信するアプリ
- app.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# coding: utf-8 from flask import Flask, render_template, request, redirect, url_for import sqlite3 import datetime app = Flask(__name__) # データベースアクセスのためのグローバル変数 conn: sqlite3.Connection cur: sqlite3.Cursor DATABASE_NAME = 'SENSOR_DATA.db' # データベースに接続する def connect_database(): global conn, cur # データベースを作成して接続する(既に存在していれば再接続) conn = sqlite3.connect(DATABASE_NAME) cur = conn.cursor() # address_book というテーブルがまだ無ければ作る。 sql = 'CREATE TABLE IF NOT EXISTS sensor_data(\ id INTEGER PRIMARY KEY AUTOINCREMENT,\ time DATETIME2,\ temp FLOAT,\ humid FLOAT)' cur.execute(sql) conn.commit() # 初期画面:これまで受信したデータの表示 @app.route('/') def index(): global cur connect_database() cur.execute('SELECT * FROM sensor_data') data = cur.fetchall() return render_template('index.html', page='menu', sensor_data=data) # センサーデータの受信 @app.route('/post', methods=['GET']) def post(): # GETプロトコルでデータ受信 try: temp = str(request.args.get('temp', default=-999.0, type=float)) humid = str(request.args.get('humid', default=-999.0, type=float)) except Exception as e: return str(e) # データ管理のため現在時刻も保存する time = str(datetime.datetime.now()) # データベースに格納 global cur, conn connect_database() sql = 'INSERT INTO sensor_data(time,temp,humid) VALUES(?,?,?)' data = [time,temp,humid] cur.execute(sql, data) conn.commit() # 初期画面に遷移させる return redirect(url_for('index')) if __name__ == "__main__": app.run(debug=True) |
- index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!DOCTYPE html> <html lang="ja"> <head> <meta http-equiv="refresh" content="1; URL="> <title>Flask Sample</title> </head> <body> <h2>Flaskによるセンサ・データの受信テスト</h2> <table border="1"> <th>No.</th><th>時刻</th><th>温度</th><th>湿度</th> {% for record in sensor_data %} <tr> <td>{{ record[0] }}</td><td>{{ record[1] }}</td><td>{{ record[2] }}</td><td>{{ record[3] }}</td> </tr> {% endfor %} </table> </body> </html> |
以上のファイルでアプリは完成ですのでいつものように動作させて、ブラウザで http://localhost:5000 を参照してください。
- senddata.sh
これはセンサーデータを送るためのシェル・スクリプトです。現時点ではまだセンサー・デバイスは実装していませんので、スクリプトを使ってテストします。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#! /bin/bash URL="http://localhost:5000/post" curl "$URL?temp=20.0&humid=50.0" read -p "Hit Enter key." curl "$URL?temp=20.2&humid=51.3" read -p "Hit Enter key." curl "$URL?temp=20.3&humid=52.8" read -p "Hit Enter key." curl "$URL?temp=20.6&humid=55.1" read -p "Hit Enter key." curl "$URL?temp=20.7&humid=57.8" |
1 |
$ chmod 744 senddata.sh |
1 |
$ ./senddata.sh |
コメント