このページで解説している内容は、以下の YouTube 動画の解説で見ることができます。

【Python入門】Webアプリケーションの作成

Webアプリケーションの作成

 データベースの活用に続いて、今度はWebアプリケーションを作成してみましょう。PythonはWebサイトのサーバサイドプログラミングに対応しており、簡易なものから本格的なWebサービスまで柔軟に構築できます。
 ここでは、まず標準ライブラリのWebサーバ機能を使って、最も基本的なログインフォームの仕組みを作ります。その後、Webフレームワークを利用したより機能的な開発手法も学びます。併せて、CSSを使ったページの見栄え改善も加え、ユーザフレンドリーなWebアプリケーションを構築する流れを身につけましょう。

プログラムのダウンロード

 「ダウンロード」から実行できるサンプルプログラムがダウンロードできます。ファイルは、ESET Endpoint Securityでウイルスチェックをしておりますが、ダウンロードとプログラムの実行は自己責任でお願いいたします。

1.標準ライブラリのhttp.serverを使う

 http.serverモジュールには簡易Webサーバが含まれており、テストや学習用として手軽にWebアプリケーションを立ち上げられます。

起動コマンド

python -m http.server --cgi 

 これでカレントディレクトリ内のファイルがhttp://localhost:8000/ で公開され、cgi-bin/ ディレクトリに置いたPythonスクリプトがCGIとして実行されます。

index.html ファイルを準備

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>ログイン</title>
  <style>
    body { font-family: sans-serif; background-color: #f4f4f4; margin: 30px; }
    form { background: #fff; padding: 20px; border-radius: 5px; }
    p { margin: 10px 0; }
    input[type="text"], input[type="password"] {
      width: 200px; padding: 5px; margin: 5px 0;
    }
    input[type="submit"] {
      padding: 8px 16px; cursor: pointer; background: #007BFF; color: #fff; border: none;
      border-radius: 3px;
    }
    input[type="submit"]:hover {
      background: #0056b3;
    }
  </style>
</head>
<body>
  <h1>ログインページ</h1>
  <form action="cgi-bin/login.py" method="post">
    <p>ユーザー名: <br><input type="text" name="user"></p>
    <p>パスワード: <br><input type="password" name="password"></p>
    <p><input type="submit" value="ログイン"></p>
  </form>
</body>
</html>

 フォームのaction属性でcgi-bin/login.pyを指定し、method="post"とすることでログイン情報を安全に送信。

CSSでフォームの背景色やボタンのホバー時の色などを設定し、見栄えを良くしています。

データベースの作成とユーザーアカウントの作成

前回のコンテンツ「データベースをSQLで操作する」を実行していれば、個々の操作は必要ありません。

データベースに接続してテーブルを作成

 データベースファイル(例: shop.db)が存在しない場合は新規に作成されます。以下は「accountテーブルを削除→作成」する例です。

「create_database.py」の内容

import sqlite3

def create_database():
    # shop.db に接続(存在しない場合は作成)
    con = sqlite3.connect('shop.db')
    cur = con.cursor()
    
    # テーブルが存在すれば削除
    cur.execute("DROP TABLE IF EXISTS account")
    
    # user(ユーザ)と password(パスワード)の2列を持つtableを作成
    cur.execute("CREATE TABLE account (user TEXT PRIMARY KEY, password TEXT)")
    
    con.commit()
    con.close()
    
if __name__ == "__main__":
    create_database()
    print("Database and table created.")

INSERTでユーザーアカウントを追加

 複数行まとめて追加したい場合はexecutemany()が便利です。以下の例ではユーザ名とパスワードをタプルで渡し、DBに登録します。

「insert_users.py」の内容

import sqlite3

def insert_users():
    con = sqlite3.connect('shop.db')
    cur = con.cursor()
    
    account_data = [
        ('suzuki', 'abc123'),
        ('sato', 'def456'),
        ('takahashi', 'ghi789')
    ]
    # INSERT文の?部分にそれぞれタプルの要素が代入される
    cur.executemany("INSERT INTO account VALUES (?, ?)", account_data)
    con.commit()
    con.close()
    print("Inserted users:", account_data)

if __name__ == "__main__":
    insert_users()

2.CGIプログラムでログイン処理を実装する

 PythonのCGIプログラムはcgi-bin/ディレクトリに配置し、実行権限(UNIX系ではchmod +x)を付与しておきます。

「login.py」の内容

import cgi
import codecs
import sys
import sqlite3

# 標準出力をUTF-8に設定
sys.stdout = codecs.getwriter('utf-8')(sys.stdout.detach())
print("Content-Type: text/html; charset=UTF-8\n")

# フォームデータを取得
form = cgi.FieldStorage()
user = form.getfirst("user", "")
password = form.getfirst("password", "")

# データベース (shop.db) へ接続してログイン判定
con = sqlite3.connect("shop.db")
cur = con.cursor()
cur.execute("SELECT * FROM account WHERE user=? AND password=?", (user, password))
result = list(cur)
con.close()

# ログイン結果をHTMLで表示
if result:
    msg = "ログインに成功しました。ようこそ!"
else:
    msg = "ログインに失敗しました。もう一度試してください。"

print(f"""
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>ログイン結果</title>
  <style>
    body {{
      font-family: sans-serif; 
      margin: 30px; 
      background-color: #f8f8f8;
    }}
    .result-box {{
      background: #fff; 
      padding: 20px; 
      border-radius: 5px; 
      margin: 20px 0;
    }}
    p {{
      font-size: 1.2em;
      margin: 10px 0;
    }}
  </style>
</head>
<body>
  <h1>ログイン結果</h1>
  <div class="result-box">
    <p>{msg}</p>
    <p><a href="../index.html">戻る</a></p>
  </div>
</body>
</html>
""")
  1. データベースから認証SELECT * FROM account WHERE user=? AND password=? でユーザ名とパスワードが一致する行を検索。
  2. 結果表示 : 該当があればログイン成功、なければ失敗メッセージをHTMLとして出力。
  3. CSS : メッセージの背景やテキストサイズを調整し、見やすいデザインに。

3.Webサーバの起動と確認

 同ディレクトリ(index.htmlshop.db がある位置)で以下のコマンドを実行すると、簡易Webサーバが起動します。

python -m http.server --cgi
  • --cgi オプション:CGIスクリプト (login.pyなど) を有効にするために必要。
  • サーバ起動後、ブラウザで http://localhost:8000/ にアクセスし、「ログインページ」が表示されれば成功。

テスト手順

  1. ユーザー名・パスワードを入力し、「ログイン」を押す。
  2. CGIプログラム(login.py)が動き、shop.dbを検索。
  3. 成功時「ログインに成功しました。ようこそ!」、失敗時「ログインに失敗しました。もう一度試してください。」と表示。

ログイン画面

ログイン結果

Webサーバの停止

ターミナルでCtrl+Cキーを押します。

> ←ここでCtrl+Cキーを押す
Keyboard interrupt received, exiting.

4.Bottleなど他のフレームワークを使う

 上記の方法は標準ライブラリとCGIのみでWebアプリを作る例でしたが、BottleFlaskなどを利用すると次のような利点があります。

  • コードの簡潔化
  • 柔軟なURLルーティング
  • 内蔵のテスト用サーバ
  • テンプレートエンジンによるHTML生成

Bottleのインストール方法

 Bottleは標準ライブラリではないため、Anaconda NavigatorのGUI以外の環境で使用する場合は以下のようにしてインストールを行います。

環境インストールコマンド
CPython(通常のPython)pip install bottle
Anaconda / Minicondaconda install -y -c conda-forge bottle

 以下はBottleを使ったミニサンプル例です。あくまで、サンプルであるため、データベースに接続したユーザー認証は行っておりません。

「webapp.py」の内容

from bottle import route, run, request

@route('/')
def index():
    return '''
    <form action="/login" method="post">
      ユーザー名: <br><input type="text" name="user"><br>
      パスワード: <br><input type="password" name="password"><br>
      <input type="submit" value="ログイン">
    </form>
    '''

@route('/login', method='POST')
def login():
    user = request.forms.get('user')
    password = request.forms.get('password')
    # ここでDB検索などを行い、認証
    if user == "suzuki" and password == "abc123":
        return "ログイン成功"
    else:
        return "ログイン失敗"

if __name__ == '__main__':
    run(host='localhost', port=8080)

CGI環境が不要で、ファイルを1つ起動すればWebアプリを立ち上げられます。

ログインページ画面の表示

サーバ起動後、ブラウザで http://localhost:8000/ にアクセスし、「ログインページ」を表示します。

ログイン画面

ログイン結果

Webサーバの停止

ターミナルでCtrl+Cキーを押します。

Bottle v0.13.2 server starting up (using WSGIRefServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.

127.0.0.1 - - [10/Mar/2025 00:47:27] "GET / HTTP/1.1" 200 241
127.0.0.1 - - [10/Mar/2025 00:47:29] "POST /login HTTP/1.1" 200 18
> ←ここでCtrl+Cキーを押す

5.CSSで見栄えを改善

 HTML内に<style>を埋め込む、または外部CSSをリンクすることで、背景色や文字スタイルを変えられます。今回のサンプルではフォームやメッセージ部分の背景色、文字サイズ、ボタンのホバー動作などを設定しています。さらにアイコンや画像を加えるなどすれば、より洗練されたUIとなります。

まとめ

 Pythonの標準ライブラリhttp.serverとCGIを使うと、軽量なWebサーバとプログラム実行環境を素早く用意できます。ログインなどのフォーム送信を受け取り、データベースと連携して認証処理を行う流れも、シンプルなCGIスクリプトで十分に確認できます。
 ただし、本格的な開発ではWebフレームワーク(Bottle、Flask、Djangoなど)の利用が一般的です。これらはルーティングやテンプレート、セキュリティ考慮などを扱いやすい形で提供しており、大規模アプリケーションにも対応できます。さらにCSSなどでUIを改善することで、ユーザに使いやすいWebアプリが完成します。

 フレームワークの使い方や、DBとの連携、ファイルアップロードといった機能の拡張を行えば、実践的なWebサービス開発へと近づいていきます。ぜひ実際にプログラムを書きつつ、開発フローを体験してみてください。