この記事では、PythonのFlaskを使って作成した簡単な計算アプリを例に、Webシステムを構成する主要な要素—サーバー、ネットワーク、クライアント、ホスト—について解説します。ローカル環境で完結するミニマルなHTTPモジュールとしてのFlaskアプリを通じ、各概念の役割や相互の関係を理解しましょう。
今回作成するFlaskアプリの紹介
まずは、今回題材とする簡単な計算アプリについて紹介します。
具体的には以下の様な画面で四則演算をします。
具体的な数値を入れて演算子を選び、計算するをクリックします。
するとバックエンドでプログラミングが処理され、答えが表示されます。
機能概要
- Webブラウザから2つの数値と演算子(+, -, *, /)を入力します。
- 「計算する」ボタンを押すと、サーバー側で計算が実行されます。
- 計算結果が同じ画面に表示されます。
動作イメージ
-
ユーザー操作(クライアント側)
ブラウザでフォームに数値と演算子を入力し、「計算する」ボタンを押します。これにより、入力データを含んだHTTPリクエストがサーバーに送信されます。 -
サーバー側での処理
Pythonで書かれたFlaskアプリ(サーバー)がリクエストを受け取り、入力された数値と演算子に基づいて計算処理を行います。計算結果はHTMLテンプレート(Jinja2)に埋め込まれ、HTTPレスポンスとして生成されます。 -
結果の表示(クライアント側)
ブラウザは、サーバーから受け取ったHTMLレスポンスを解釈(レンダリング)し、計算結果を画面に表示します。
この一連の流れは、あなたのPCのローカル環境で完結します。インターネットに公開されるわけではなく、自己完結型のミニマルなHTTPモジュールとして動作する良い例となります。
Flaskアプリのコード
以下に、この計算アプリを実現するためのFlask(Python)コードとHTMLテンプレートを示します。
1. Flaskアプリケーション (app.py
)
from flask import Flask, render_template, request
# Flaskアプリケーションのインスタンスを作成
app = Flask(__name__)
# ルートURL ('/') へのアクセスを処理する関数を定義
# GETメソッド(初回アクセス時)とPOSTメソッド(フォーム送信時)の両方に対応
@app.route('/', methods=['GET', 'POST'])
def calc():
result = None # 結果を初期化
# フォームが送信された場合 (POSTリクエストの場合)
if request.method == 'POST':
try:
# フォームから 'num1', 'num2', 'operator' の値を取得
num1 = float(request.form['num1'])
num2 = float(request.form['num2'])
operator = request.form['operator']
# 演算子に応じて計算を実行
if operator == '+':
result = num1 + num2
elif operator == '-':
result = num1 - num2
elif operator == '*':
result = num1 * num2
elif operator == '/':
# 0除算を防ぐ基本的なチェック(より厳密なエラー処理も可能)
if num2 == 0:
result = "エラー: 0で割ることはできません"
else:
result = num1 / num2
else:
result = "エラー: 不明な演算子です"
# 数値変換エラーやその他の予期せぬエラーをキャッチ
except ValueError:
result = "エラー: 有効な数値を入力してください"
except Exception as e:
result = "エラー: " + str(e)
# 'index.html' テンプレートをレンダリングして返す
# result変数をテンプレートに渡す
return render_template('index.html', result=result)
# このスクリプトが直接実行された場合にFlask開発サーバーを起動
if __name__ == '__main__':
# debug=True にすると、コード変更時に自動リロードされ、エラー詳細が表示される
app.run(debug=True)
コード解説:
-
Flask(__name__)
: Flaskアプリの本体を作成します。 -
@app.route('/', methods=['GET', 'POST'])
: 特定のURLパス (/
) とHTTPメソッド (GET
,POST
) に対応する関数 (calc
) を紐付けます。 -
request.method
: 現在のリクエストがGET
かPOST
かを判定します。 -
request.form['キー']
: POSTリクエストで送信されたフォームデータを取得します。 -
float()
: フォームから受け取った文字列を浮動小数点数に変換します。エラーが発生する可能性があるためtry...except
で囲んでいます。 -
render_template('index.html', result=result)
:templates
フォルダにあるindex.html
を読み込み、result
変数の値を埋め込んでHTMLを生成し、クライアント(ブラウザ)に返します。 -
if __name__ == '__main__': app.run(debug=True)
: このPythonファイルが直接実行されたときに、開発用のWebサーバーを起動します。debug=True
は開発中に便利な機能(エラー表示、自動リロード)を有効にします。
2. HTMLテンプレート (templates/index.html
)
Flaskはデフォルトで templates
という名前のフォルダ内にあるHTMLファイルを探します。以下の内容で templates/index.html
を作成してください。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>簡単な計算アプリ</title>
<style>
body { font-family: sans-serif; padding: 20px; }
form { margin-bottom: 20px; }
input[type="text"], select, button { padding: 8px; margin-right: 5px; }
h2 { color: green; }
.error { color: red; } /* エラースタイルを追加 */
</style>
</head>
<body>
<h1>簡単な計算アプリ</h1>
<form method="post">
<input type="text" name="num1" placeholder="数字1" required>
<select name="operator">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<input type="text" name="num2" placeholder="数字2" required>
<button type="submit">計算する</button>
</form>
{# Jinja2テンプレートエンジン: result変数がNoneでない場合に以下のブロックを表示 #}
{% if result is not none %}
{# 結果がエラーメッセージかどうかを判定してクラスを適用 #}
{% if 'エラー' in result|string %}
<h2 class="error">結果: {{ result }}</h2>
{% else %}
<h2>結果: {{ result }}</h2>
{% endif %}
{% endif %}
</body>
</html>
コード解説:
-
<form method="post">
: フォームのデータをPOSTメソッドで、同じURL (/
) に送信します。 -
<input type="text" name="num1">
,<select name="operator">
,<input type="text" name="num2">
: ユーザーが数値を入力したり、演算子を選択したりするためのフォーム部品です。name
属性の値が、Flask側でrequest.form
を使って値を取得する際のキーになります。required
属性は簡単な入力チェックです。 -
<button type="submit">
: このボタンを押すとフォームが送信されます。 -
{% if result is not none %}
...{% endif %}
: Jinja2の制御構文です。Flaskからresult
変数が渡され、かつNone
でない(つまり計算結果またはエラーメッセージがある)場合に、中のHTMLを表示します。 -
{{ result }}
: Jinja2の変数展開です。Flaskから渡されたresult
変数の値をここに表示します。 -
{% if 'エラー' in result|string %}
: 結果に「エラー」という文字列が含まれているかチェックし、含まれていればerror
クラスを適用して赤字で表示します。
Flaskアプリの動かし方
準備
- Pythonのインストール: もしまだなら、Python公式サイトからダウンロードしてインストールしてください。
-
Flaskのインストール: ターミナル(コマンドプロンプト)を開き、以下のコマンドを実行します。
pip install Flask
フォルダ構成
以下のようなフォルダ構成でファイルを作成します。
my_calc_app/
├── app.py
└── templates/
└── index.html
-
my_calc_app
というフォルダを作成します(名前は任意)。 - その直下に
app.py
を置きます。 -
my_calc_app
フォルダの中にtemplates
という名前のフォルダを作成します。 -
templates
フォルダの中にindex.html
を置きます。
実行とアクセス
- ターミナルで
my_calc_app
フォルダに移動します (cd my_calc_app
)。 - 以下のコマンドを実行してFlaskアプリを起動します。
python app.py
- ターミナルに
* Running on http://127.0.0.1:5000/
のような表示が出たら、Webブラウザを開き、アドレスバーにhttp://127.0.0.1:5000/
またはhttp://localhost:5000/
と入力してアクセスします。 - 計算アプリが表示され、操作できるはずです。
Flaskアプリから学ぶWebの基本概念
さて、この簡単なFlaskアプリの動作を通して、Webシステムの基本となるサーバー、ネットワーク、クライアント、ホストの概念を見ていきましょう。
1. サーバー(Server)
定義:
サーバーは、クライアントからのリクエストを受け取り、何らかの処理(データ提供、計算、認証など)を行い、その結果(応答)をクライアントに返すシステムやソフトウェアのことです。
今回のFlaskアプリにおけるサーバー:
-
app.py
を実行しているPythonプロセスそのものが、HTTPサーバーとしての役割を担っています。 - 具体的には、Flaskフレームワークが、Webブラウザ(クライアント)からのHTTPリクエスト(例:
/
へのアクセス、計算データのPOST送信)を受け付けます。 -
@app.route
で定義されたcalc
関数が呼び出され、リクエストの内容に基づいて計算処理を実行します。 -
render_template
を使って計算結果を含むHTMLを生成し、HTTPレスポンスとしてクライアントに返します。
このように、Flaskアプリはデータやサービスの「提供側」として動作しています。
2. ネットワーク(Network)
定義:
ネットワークは、複数のコンピュータやデバイス(ホスト)を相互に接続し、情報やリソースを交換(通信)できるようにする環境や仕組み全体を指します。インターネットも広大なネットワークの一つです。
今回のFlaskアプリにおけるネットワーク:
- アプリの実行時に
http://127.0.0.1:5000/
にアクセスしました。127.0.0.1
は特別なIPアドレスで、「ループバックアドレス」や「ローカルホスト」と呼ばれ、自分自身のコンピュータを指します。 - 通信は、インターネットのような外部のネットワークを経由せず、お使いのPC内部のネットワーク機能(OSのTCP/IPスタック) を使って行われています。これをローカルネットワーク(より正確にはループバックインターフェースを通じた通信)と呼びます。
- ブラウザ(クライアント)とFlaskアプリ(サーバー)は、このローカルネットワーク上で、HTTPというプロトコル(通信ルール)に従ってリクエストとレスポンスをやり取りしています。
ポイント:
- 外部ネットワークに接続されていなくても動作するため、開発や学習、テストに非常に便利です。
- 基本的な通信の仕組み(TCP/IP、HTTP)は、ローカルでもインターネット上でも同じです。
3. クライアント(Client)
定義:
クライアントは、サーバーに対してリクエストを送り、その応答(データやサービス)を受け取って利用する側のシステムやソフトウェアです。
今回のFlaskアプリにおけるクライアント:
- Webブラウザ(Google Chrome, Firefox, Safari, Edgeなど)がクライアントの役割を果たします。
- ユーザーがアドレスバーに
http://127.0.0.1:5000/
と入力すると、ブラウザはFlaskサーバーに対してHTTP GETリクエストを送信します。 - ユーザーがフォームに数値を入力し「計算する」ボタンを押すと、ブラウザは入力データを含んだHTTP POSTリクエストをFlaskサーバーに送信します。
- FlaskサーバーからのHTTPレスポンス(HTML)を受け取り、それを解釈して画面に表示(レンダリング)します。
4. ホスト(Host)
定義:
ホストは、ネットワークに接続された任意のコンピュータやデバイスを指す一般的な用語です。ネットワーク上で通信するためには、通常IPアドレスが割り当てられます。
今回のFlaskアプリにおけるホスト:
- このFlaskアプリを実行しているあなたのPC自体がホストです。
- このホスト(PC)上では、サーバーとしての役割を持つFlaskアプリ(Pythonプロセス)と、クライアントとしての役割を持つWebブラウザの両方が動作しています。
注意点:
ホストという言葉は、特定の役割(サーバーかクライアントか)を区別せず、単にネットワーク上の「機器」や「ノード」を指す広い概念です。したがって、「クライアントの対義語は?」と聞かれた場合、「サーバー」と答えるのが適切であり、「ホスト」ではありません。ホストは、サーバーにもクライアントにもなり得ます。
まとめ
今回は、簡単なFlask計算アプリを例に、Webの基本的な構成要素を見てきました。
-
サーバー: Flaskアプリケーション (
app.py
) がリクエストを受け付け、計算処理を行い、結果を返す役割。 -
ネットワーク: PC内部のローカルネットワーク (
127.0.0.1
) 上で、HTTPプロトコルを使って通信。 - クライアント: Webブラウザがリクエストを送信し、サーバーからのHTMLレスポンスを表示する役割。
- ホスト: アプリを実行しているPC自体。サーバーとクライアントの両方を含むネットワーク上のデバイス。
このように、ローカルで完結するシンプルなWebアプリケーションであっても、サーバー、ネットワーク、クライアント、ホストといった基本概念が連携して動作しています。これらの関係性を理解することは、より複雑なWebシステムやインターネット上のサービスの仕組みを学ぶ上での重要な基礎となります。
この記事が、Flaskアプリケーションを通してWebシステムの基本概念を学ぶ一助となれば幸いです。
Happy Coding!