見出し画像

Bottle を試してみる

複数の Raspberry Pi とデータベース、NASを使い、LANで機能する装置群を作っていますが、スマホなどでもデータ入力や閲覧が出来るようにしたいと考えて、Bottle を試してみることにしました。

主に制御系を扱って来たのでHTMLもままならない状況ですが、様々なWebページを参考に簡単なWebアプリ?を作ってみました。

2つの値を入力すると、2値を使った四則演算結果を表示するだけのものですが、HTML, CSS, BottleでGET POSTを使ったデータの受け渡しを使えるようになりました。良く解らないところもあるのですが、一応動いています。

フォルダー構造

test2 と言うフォルダー以下に次のように配置しました。

/test2
      template.py
      /views
            index.html
            result.html
      /static
            /css
                  index.css
                  result.css
            /img

フォルダー構造

bottle.py は pip でインストールしたのでこのフォルダー構造内にはありません。画像を使わないのでフォルダー/test2/static/img 内は空です。

動作概要

template.py を実行して、Webブラウザから http://localhost:8080 にアクセスすると下図の画面が現れ、2つの値を入力して「送信」ボタンをクリックすると送信出来ます。

index.html の画面

送信すると、下図のように結果を表示し、「入力に戻る」ボタンをクリックすると上図の表示(2値は空欄)に戻ります。

result.html の画面

値2に0を入力すると割り算の行に ZeroDivisionError と表示します。

result.html  ZeroDivisionError の画面


ソースコード

template.py

from bottle import run, route, template, get, post, request, static_file
import os


# Static file
@get("/static/css/<filepath:re:.*\.css>")
def css(filepath):
    return static_file(filepath, root="static/css")

@get("/static/img/<filepath:re:.*\.(jpg|png|gif|ico|svg)>")
def img(filepath):
    return static_file(filepath, root="static/img")


# 入力ページ
@route("/")
def index():
    return template('index')



# 結果ページ
#@route("/result", method="GET")
@route("/result", method="POST")
def result():
    # GETリクエストの場合のフォームパラメータ
    #val1 = request.query.getunicode("val1")
    #val2 = request.query.getunicode("val2")

    # POST/PUTリクエストの場合のフォームパラメータ
    #val1 = request.forms.getunicode("val1")
    #val2 = request.forms.getunicode("val2")

    # GET/POST/PUT全部まぜこぜのフォームパラメータ
    val1 = request.params.getunicode("val1")
    val2 = request.params.getunicode("val2")

    v1 = float(val1)
    v2 = float(val2)
    r1 = str(v1 + v2)
    r2 = str(v1 - v2)
    r3 = str(v1 * v2)
    if v2 == 0:
        r4 = 'ZeroDivisionError'
    else:
        r4 = str(v1 / v2)

    rd = { '1' : r1, '2' : r2, '3' : r3, '4' : r4 }

    #return template('result', val1=val1, val2=val2, r1=r1, r2=r2, r3=r3, r4=r4)
    return template('result', val1=val1, val2=val2, rd=rd)



# プロセス起動
if __name__ == "__main__":
#    run(host='127.0.0.1', port=8080, reloader=True, debug=True)
    # ローカルIPまたはlocalhostでアクセス
    run(host='0.0.0.0', port=8080, reloader=True, debug=True)

データの受け渡しに GET と POST を使って試しました。
また演算結果を渡す方法として文字列型と辞書型を試しました。
上のソースはPOSTと文字列型、辞書型併用による受け渡しをしています。
GETと文字列型のみについてはコメントアウトした行を参考にしてみて下さい。

index.html

<!doctype html>

<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <link rel="stylesheet" type="text/css" href="/static/css/index.css">
    <title>四則演算</title>
  </head>


  <body>
  <div class = "div_main">
    <p>値1と値2を使って四則演算します。</p>
    <!-- <form class="form1" action="/result" method="get"> -->
    <form class="form1" action="/result" method="post">
      値1: <input name="val1" type="text" size="30"><br>
      値2: <input name="val2" type="text" size="30"><br><br>
      <input class="bt1" value="送信" type="submit">
    </form>
  </div>


  </body>

</html>

index.css

@charset "utf-8";

.div_main{
  width: 300px;
  padding: 10px;
  text-align: center;
  border: 1px solid #cccccc;
  margin: 30px auto;
  background-color:lightgray;
}


result.html

<!doctype html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width">
  <link rel="stylesheet" type="text/css" href="/static/css/result.css">
  <title>結果のページ</title>
</head>
<body>

  <p>{{ val1 }} + {{ val2 }} = {{ rd['1'] }}</p>
  <p>{{ val1 }} - {{ val2 }} = {{ rd['2'] }}</p>
  <p>{{ val1 }} * {{ val2 }} = {{ rd['3'] }}</p>
  <p>{{ val1 }} / {{ val2 }} = {{ rd['4'] }}</p>
  
  <button type=“button” onclick="location.href='/'">入力に戻る</button>

</body>
</html>

演算結果を渡す方法として文字列型と辞書型を試しました。
上のソースは文字列型、辞書型併用による受け渡しをしています。
文字列型のみの受け渡しは、template.pyのコメント行入れ替えを行い、以下のように書き換えて下さい。
rd['1'] → r1 , rd['2'] → r2 , rd['3'] → r3 , rd['4'] → r4

この部分の記述はコメントアウトしても is not defined エラーが発生するので削除しました。コメント行でエラーが発生するなんて???

result.css

@charset "utf-8";

body{
  width: 300px;
  padding: 10px;
  text-align: center;
  border: 1px solid #cccccc;
  margin: 30px auto;
  /* background-color:lightgray; */
}


まだまだ勉強

template.py はローカルIPまたはlocalhostでアクセス出来るので、他のPCでも動作させることが出来ます。ただし、シングルプロセス、シングルスレッドと言うことなので、一方のPCで操作している間はもう一方のPCで操作出来ない状態でした。
LAN内で特定の人が使うWebアプリにしても、出来れば2~3人程度同時に使えるようにしたいものです。

どうやら、Apache2 と mod_wsgi と言うのを使って、LAN内にWSGI対応のHTTPサーバーを立ち上げるとマルチプロセスにも出来るようなのですが、いろいろ試してみないと解かりません。

LAN内ならSSLは不要な気がしますが、将来に備えてSSL対応を含むデプロイと言うのも試したいと思います。
セキュリティー対策とか難しそうですが・・・

私の用途からすると、実用的な範囲で簡素なページを作れれば良いのですが、まだまだ勉強が必要そうです。


今後とも宜しくお願い致します。



出来ればサポート頂けると、嬉しいです。 新しい基板や造形品を作る資金等に使いたいと思います。