Webサーバーで動く Python アプリ 【Raspberry Pi 版】

Raspberry Pi

ローカルネットワーク内の Raspberry Pi で Web アプリを動かす方法についてまとめておきます。
最小限の知識、手間で済むよう意図しています。

以下の環境で動作確認をしています。
環境:
・ Raspberry Pi (bullseye、Web サーバーとして使用)
・ Windows パソコン(クライアントとして使用)
・ ローカルネットワーク(Wi-Fi)
★ Raspberry Pi と Windows パソコン等のネットワークなどの基本的な設定は、すでに完了していることを前提としています。Raspberry Pi の初期設定等については、下記の関連リンクを参照してください。

背景 ~ Python のスクリプトを Web アプリ化したい!

Python でプログラミングの検討をしていると、使えそうなスクリプトを Web アプリ化してローカルネットワーク内の Raspberry Pi などに移植し、できるだけ簡単にスクリプトを活用したくなることがあります。

Web アプリ化できてしまえば、普段、使っているパソコン側は環境を汚すことなく/何ら余計な設定をすることなく、作成した便利なアプリがブラウザ経由でそのまま使えることになります。
また、スマートフォンや、ネットワークにつながった他の Linux 機器からもアクセスし、便利な機能を活用できることになります。

Web アプリとしては、以前、このサイトで、Windows のスタンドアロンの PC 上で動く Python のアプリ(電卓)を作っていました。
そこで同サンプルを使って、ネットワーク上の Raspberry Pi を Web サーバー化して Web アプリを動かす手順についてまとめておきます。

なお、Web サーバーについて、本格的なサーバーを設定しようとすると手順が煩雑です。そこで、Raspberry Pi の初期状態ですでにインストールされている、Python のサーバーの機能を使うことにします。
最もシンプルに Web アプリを動かすことを最優先とします。セキュリティ対策などは考慮していませんので、ご理解いただきますようお願いいたします。

設定手順

ステップ1:ドキュメントルートの設定

① 以下を例に、Raspberry Pi でドキュメントルート(公開フォルダ)となるフォルダを作成してください。
例: /home/pi/web_server1/
② ①のフォルダ内に、さらに、”cgi-bin” というフォルダを作成し、”calc1.py” という名前でテキストファイルを作成してください。
例: /home/pi/web_server1/cgi-bin/calc1.py
③ ②のテキストファイルに、以下のサンプルスクリプトをコピー&ペーストして貼りつけ、保存してください。
簡単な足し算をする電卓アプリになっています。
④ Raspberry Pi のターミナルを起動し、以下を参考にして、Python のスクリプト calc1.py に実行権限を設定してください。

cd  /home/pi/web_server1/cgi-bin/
chmod 700 calc1.py 

※ ②のフォルダに移動して、chmod コマンドで実行権限、パーミッションを設定しておきます。
ネットワーク内の別のパソコンから Python のスクリプト calc1.py が実行できるようにするためです。
Raspberry Pi でテキストファイル(calc1.py)を作成すると、初期状態では所有者に実行権限が与えられていないと思います。そこで、所有者にすべての権限 (r+w+x = 4+2+1 = 7)を与えておきます。

⑤ Raspberry Pi のターミナルで以下を実行し、ローカルネットワーク内での Raspberry Pi の IP アドレスを確認してください。

hostname -I

例: 192.168.1.33

ステップ2: Web サーバーの起動

⑥ 以下を参考に、ドキュメントルート(①のフォルダ)に移動し、python のサーバーを起動してください。

cd /home/pi/web_server1
python3 -m http.server 8000 --cgi

※ ここで、”Serving HTTP on 0.0.0.0 port 8000 (http:/0.0.0.0:8000) … ” 等の表示がされたら、Web サーバーの動作まで成功です。
※ Web サーバーの動作を止めるには、ターミナル上で、[ctrl] + [c] を入力してください。

ステップ3: ブラウザで Web サーバーにアクセスしてみる

⑦ ⑥の Web サーバーを動作させた状態で、ローカルネットワーク内の他のパソコン(Windows パソコンなど)で、Microsoft Edge などのブラウザを起動してください。そして、以下を参考に、ローカルネットワーク内のURL にアクセスをしてみてください。
http://192.168.1.33:8000/cgi-bin/calc1.py

※ ここで、192.168.1.33 とした部分は、⑤で確認した Raspberry Pi の IP アドレスに一致させてください。
また、②で Python のスクリプト名を変更した場合は、calc1.py の部分をファイル名に対応するように修正してください。

→ Python の Web アプリ(電卓アプリ)が動いたら、成功です!

うまく動いたら

うまく動いたら、Web サーバーの構成や Web アプリのスクリプトをアレンジしてみてください。

たとえば、上記の事例は、もっともシンプルに Python のスクリプト(cgi) を動かす手順としています。トップページすら作っていません。
そこで、ドキュメントルートとしているフォルダ(home/pi/web_server1/)内に、index.html という名前でテキストファイルを作成し、以下の2行を貼りつけて保存してみてください。詳細はスキップしていますが、トップページが表示できると思います。
hello world! <br>
<a href=”/cgi-bin/calc1.py”>calc</a>

上記のトップページ index.html の作成後、”192.168.1.33:8000″ にアクセスすると、hello world! と書かれたページが表示されると思います。
このトップページにあるリンク”calc” をクリックすると、今回設定した電卓アプリに飛べると思います。
すると、上記の電卓アプリと同様の要領で、Web アプリを追加し、トップページにリンクを追加していけば、任意の動的な機能を Web サーバーに追加していくことが可能ということなります。
サンプルはクライアントとサーバー間でデータのやり取りを行う動的な事例としていますが、上記の index.html のように静的なページを追加するのはさらに簡単です。
ローカルネットワーク内でウェブサイトを構築していくことが可能、ということになります。

なお、今回の電卓の Web アプリは、関連リンクの 「Webサーバーで動く Python アプリ 【Windows 版】」とほぼ同等のものです。Linux 用に冒頭の記載を修正しています。サンプルコードの説明については、同リンクに記載しています。もし興味があるようでしたら、参照してみてください。

まとめ

ローカルネットワーク内の Raspberry Pi を Web サーバー化して Web アプリを動かす手順についてまとめました。
Web アプリが作成できると Python や Raspberry Pi の応用範囲が格段に広がります。

関連リンク
・ 起動用SDカードを設定する 【Raspberry Pi】
・ Webサーバーで動くPythonアプリ 【Windows 版】
・ Raspberry Pi でローカルWebサーバー 【Python 活用】
・ パーミッション関連でよく使うコマンド 【Linux】
・ レンタルサーバーの比較表

サンプルスクリプト

#!/usr/bin/env python3
# coding: utf-8
import cgi
import sys, io 

# python3 -m http.server 8000 --cgi 
# http://192.168.1.XX/cgi-bin/calc1.py
# chmod 755 calc1.py 

sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

form1 = cgi.FieldStorage() 

str01 = form1.getvalue( 'TextBox1', '0' ) 
str02 = form1.getvalue( 'TextBox2', '0' ) 
str03 = str( int( str01 ) + int( str02 ) ) 
# str03 = str( float( str01 ) + float( str02 ) ) 

str0 = '''
<html>
  <body>
    <form name="Form" method="POST" action="/cgi-bin/calc1.py">
      <input type="text" size="10" name="TextBox1" value="{str11}"> + 
      <input type="text" size="10" name="TextBox2" value="{str12}"> = 
      <input type="text" size="10" name="TextBox3" value="{str13}"><br><br>
      <input type="submit" value="calculate" name="button1">
    </form>
  </body>
</html>
'''.format( str11=str01, str12=str02, str13=str03 ) 

print("Content-Type: text/html; charset=UTF-8;\n")
print( str0 ) 
タイトルとURLをコピーしました