PythonによるWebアプリケーション開発(Flask編)


第1章:Webアプリケーションの基礎

この章では、私たちが普段何気なく使っているWebアプリケーションが、どのような仕組みで動いているのかを学びます。これからWebアプリケーションを「作る側」になるために、まずはその基本的な構造と専門用語に慣れていきましょう。

1. Webはどのように動いているか

あなたがブラウザでWebサイトを見るとき、その裏側では「クライアント」と「サーバー」という2人の登場人物が会話をしています。

  • クライアント (Client)
    • あなたのPCやスマートフォンで動いているWebブラウザ(Google Chrome, Safariなど)のことです。「このページを見たい!」とリクエスト(要求)を送る役割を持ちます。
  • サーバー (Server)
    • Webサイトのデータ(HTMLファイル、画像など)が保管されている、世界中のどこかにある高性能なコンピュータのことです。クライアントからのリクエストを受け取り、適切なデータをレスポンス(応答)として返す役割を持ちます。

このクライアントとサーバー間のやり取りは、HTTP(HyperText Transfer Protocol)という共通の言語(通信プロトコル)で行われます。カフェで客(クライアント)が店員(サーバー)に「コーヒーをください」と注文(リクエスト)し、店員がコーヒー(レスポンス)を提供する流れと非常によく似ています。

2. Webアプリケーションとは

では、「Webサイト」と「Webアプリケーション」は何が違うのでしょうか?

  • 静的なWebページ (Static Web Page)
    • いつ、誰が見ても同じ内容が表示されるページです。例えば、会社の基本情報ページやニュース記事などがこれにあたります。サーバーは、あらかじめ用意されたHTMLファイルをそのままクライアントに返すだけです。
  • 動的なWebページ (Dynamic Web Page)
    • 見る人やタイミングによって表示される内容が変わるページです。例えば、SNSのタイムライン、ネット通販サイトのショッピングカート、検索結果の表示ページなどが該当します。

このような動的なページを提供する仕組み全体を「Webアプリケーション」と呼びます。

Webアプリケーションのサーバーは、単にファイルを返すだけではありません。クライアントからのリクエストに応じて、その場でプログラムを実行し、データベースから情報を取得して、HTMLを動的に生成してからクライアントに返します。この「その場でプログラムを実行してHTMLを生成する」というのが、Webアプリケーションの最も重要な特徴です。

3. 動的なWebアプリケーションの構成要素

Webアプリケーションは、大きく分けて2つの部分から構成されています。

  • フロントエンド (Frontend)
    • ユーザーが直接見て、操作する部分です。つまり、ブラウザに表示される画面そのものを指します。主にHTML, CSS, JavaScriptといった技術で作られます。画面作成を担当します。
  • バックエンド (Backend)
    • ユーザーの目には見えない、サーバー側で動く部分です。リクエストの処理、データベースへのアクセス、ビジネスロジックの実行など、アプリケーションの「頭脳」にあたる部分です。今回の研修で学ぶPython (Flask)は、このバックエンドを担当します。データ処理を担当します。

そして、バックエンドは多くの場合、データベース (Database)と連携します。データベースは、ユーザー情報、商品情報、投稿内容といった大量のデータを整理して保管しておくための倉庫です。

例えば、あなたがログインフォームにIDとパスワードを入力して送信すると、バックエンドのプログラムがその情報を受け取り、データベースに問い合わせて「このユーザーは本物か?」を確認し、結果に応じて「ログイン成功ページ」または「エラーページ」のHTMLを動的に生成して、あなたのブラウザに返すのです。

この「フロントエンド」「バックエンド」「データベース」の3つの要素が連携しあって、一つのWebアプリケーションが成り立っています。この研修では、主にバックエンドの開発に焦点を当て、Flaskを使ってこの仕組みを実際に構築していきます。


次の章では、これらの処理を効率的に開発するための「フレームワーク」という考え方や、現代的なWeb開発に欠かせない「REST」「JSON」といった概念について学んでいきます。


第2章:モダンWebアプリケーション開発の考え方

第1章では、Webアプリケーションがクライアントとサーバーの通信によって成り立っていることを学びました。この章では、その開発をより効率的かつ現代的に行うための重要な考え方について解説します。

1. Web開発におけるPythonの役割

Pythonは、AI・機械学習やデータ分析の分野で非常に人気のある言語ですが、Webアプリケーションのバックエンド開発においても広く採用されています。その理由は以下の通りです。

  • 文法がシンプルで読みやすい: コードが直感的で、初心者でも学びやすい。
  • 豊富なライブラリ: Web開発、データベース接続、データ処理など、あらゆる機能に対応する「部品」が揃っている。
  • 高い汎用性: 小規模なAPIサーバーから、Instagramのような大規模サービスまで、幅広い用途に対応できる。

今回の研修で学ぶFlaskも、Pythonの強力なライブラリの一つです。

2. フレームワークの必要性

Webアプリケーションをゼロから作ろうとすると、URLの解釈、データベースへの接続、セキュリティ対策など、毎回同じような処理を大量に書く必要があり、非常に大変です。

そこで登場するのが「Webフレームワーク」です。

Webフレームワークとは、Webアプリケーション開発で頻繁に使われる基本的な機能をまとめた「骨組み」や「土台」のようなものです。開発者はこの骨組みの上で、アプリケーション固有の機能開発に集中することができます。

フレームワークを使うことで、開発者は車輪の再発明(すでに存在するものをもう一度作ること)を避け、開発スピードの向上コードの品質維持を実現できます。

Pythonの代表的なWebフレームワーク

  • Flask: マイクロフレームワークと呼ばれ、シンプルで学習しやすい。小〜中規模のアプリケーションやAPIサーバーの構築に向いています。
  • Django: フルスタックフレームワークと呼ばれ、Web開発に必要な機能(管理画面、認証など)がすべて揃っています。大規模で複雑なアプリケーションに向いています。

3. モダンなAPIの設計思想「REST」

最近のWebサービスでは、Webブラウザだけでなく、スマートフォンアプリや他のWebサービスなど、様々なクライアントがサーバーの機能を利用します。このとき、お互いがスムーズに連携するための共通の「お作法」が必要になります。それがREST(Representational State Transfer)です。

RESTful APIとは、RESTの考え方に基づいて設計された、サーバーとクライアントのやり取りのルールのことです。以下の特徴を持ちます。

  1. リソース (Resource) すべての情報(例:「ユーザー情報」「商品情報」)を、一意のURLで識別します。
    • /users/123 → IDが123番のユーザー
    • /products → すべての商品の一覧
  2. HTTPメソッド (HTTP Method) URLに対して行う操作を、HTTPメソッドで明確に区別します。これは、演習で実装するCRUD(Create, Read, Update, Delete)操作に直接対応します。
操作HTTPメソッド説明
CreatePOST新しいリソース(データ)を作成する
ReadGETリソース(データ)を取得する
UpdatePUT / PATCH既存のリソース(データ)を更新する
DeleteDELETEリソース(データ)を削除する

Google スプレッドシートにエクスポート

このルールに従うことで、誰にとっても分かりやすく、再利用性の高いAPIを設計することができます。

4. 標準的なデータ交換形式「JSON」

クライアントとサーバーがデータをやり取りする際、お互いが理解できる共通のフォーマットが必要です。現在、そのデファクトスタンダード(事実上の標準)となっているのがJSON(JavaScript Object Notation)です。

JSONは、以下のように{ "キー": "値" }という形式でデータを記述します。

{
  "id": 123,
  "name": "山田 太郎",
  "email": "yamada@example.com",
  "is_premium": true
}

人間にとっても読み書きしやすく、プログラムでも扱いやすいため、Web APIを介したデータ交換に広く利用されています。Pythonには、このJSON形式のデータを簡単に扱うための標準ライブラリが用意されています。


次の章では、いよいよこれらの概念を具体的に実装するためのツールである、簡易フレームワーク「Flask」について詳しく学んでいきます。


第3章:簡易フレームワーク「Flask」入門

前の章で学んだ「フレームワーク」や「REST」といった概念を、いよいよ具体的なツールを使って形にしていきます。この章では、シンプルで学びやすいPythonのWebフレームワークFlaskの基本的な使い方をマスターしましょう。

1. Flaskとは

Flaskは、「マイクロフレームワーク」と呼ばれています。これは、Webアプリケーションを作る上で本当に必要最低限の機能(リクエストの受付、応答の返却など)だけを提供し、それ以外の機能(データベース操作、フォーム作成など)は、必要に応じて開発者がライブラリを追加して拡張していく、という設計思想を意味します。

このシンプルさゆえに、Flaskは以下のような特徴を持っています。

  • 学習が容易: 覚えるべき「お作法」が少なく、初心者でもすぐに動くものを作れる。
  • 柔軟性が高い: 開発者が使いたいライブラリを自由に組み合わせることができる。
  • 軽量で高速: 余計な機能が少ないため、動作が軽い。

この章では、Flaskアプリケーションを構成する上で特に重要な要素を一つずつ見ていきます。

2. Flaskを構成する主要な要素

Flaskアプリケーションの基本的な構造は、まるで人体のようです。URLという「住所」を頼りにやってきたリクエストを、体の中の各「臓器」が連携して処理し、レスポンスという「返事」を返します。

① Routing:URLと処理を結びつける神経網

Routing(ルーティング)は、特定のURLへのアクセスを、どのPythonの関数で処理するかを結びつける仕組みです。Flaskでは、@app.route()というデコレータを使ってこれを定義します。

from flask import Flask

app = Flask(__name__)

# "/" (トップページ)へのアクセスがあったら、hello_world関数を呼び出す
@app.route("/")
def hello_world():
    return "<h1>Hello, World!</h1>"

# "/about" へのアクセスがあったら、about_page関数を呼び出す
@app.route("/about")
def about_page():
    return "<h1>これはAboutページです。</h1>"

このコードにより、ユーザーが http://.../ にアクセスすれば "Hello, World!" が、/about にアクセスすれば "これはAboutページです。" がブラウザに表示されます。Routingは、アプリケーションへのリクエストを適切な処理担当者に振り分ける、交通整理人のような役割を担います。

② Templates:HTMLを動的に生成する顔

Pythonのコードの中に直接HTMLを書き込むのは、見た目が悪く、管理も大変です。そこでFlaskでは、Templates(テンプレート)という仕組みを使います。

これは、あらかじめHTMLの「ひな形」を用意しておき、プログラム側から動的に変化する部分(ユーザー名や商品リストなど)のデータを流し込む方法です。Flaskは内部で Jinja2 という強力なテンプレートエンジンを採用しています。

templates/index.html

<!DOCTYPE html>
<html>
<head>
    <title>マイページ</title>
</head>
<body>
    <h1>こんにちは、{{ username }}さん!</h1>
</body>
</html>

Pythonコード

from flask import render_template

@app.route("/user/<name>")
def user_page(name):
    # index.htmlを読み込み、usernameという変数にnameの値を渡す
    return render_template("index.html", username=name)

このコードを実行し /user/鈴木 にアクセスすると、{{ username }} の部分が「鈴木」に置き換えられたHTMLが生成され、ブラウザには「こんにちは、鈴木さん!」と表示されます。これにより、ロジック(Python)と見た目(HTML)をきれいに分離できます。

③ データベース連携:記憶を司る脳 (sqlite3)

Webアプリケーションでは、ユーザー情報や投稿内容などを永続的に保存するためにデータベースが必要です。Flask自体は特定のデータベースに依存しませんが、Pythonにはsqlite3という軽量なデータベースを操作するためのライブラリが標準で組み込まれています。

sqlite3は、特別なサーバーを必要とせず、単一のファイルとしてデータベースを扱えるため、開発中の学習や小規模なアプリケーションに最適です。演習では、このsqlite3を使ってデータの保存、取得、更新、削除(CRUD)を実装します。

④ 開発支援機能:健康状態を知らせるセンサー

Flaskには、開発をスムーズに進めるための便利な機能が組み込まれています。

  • Debugger(デバッガー): プログラムにエラーが発生した際に、ブラウザ上でエラーの原因やその時の変数の状態などを詳しく表示してくれます。これにより、問題解決の時間が大幅に短縮されます。
  • Logger(ロガー): アプリケーションがどのように動作しているか(誰がどのページにアクセスしたか、エラーが発生したかなど)を記録(ログ)としてファイルやコンソールに出力します。

これらの機能を活用することで、アプリケーションの健康状態を常に把握しながら開発を進めることができます。


次の最終章では、いよいよこれらの要素を組み合わせて、データの閲覧、登録、更新、削除(CRUD)ができる、一つの完成したWebアプリケーションを作成する演習に入ります!


第4章:【演-習】簡易Webアプリケーションの作成

さあ、いよいよ最後の章です!これまで学んだWebの基礎、RESTの考え方、そしてFlaskの各機能を組み合わせて、一つの完成したWebアプリケーションをゼロから構築していきます。この演習を通して、Webアプリケーション開発の全体像をその手で掴み取りましょう。

1. 演習の概要と完成イメージ

作成するアプリケーション

今回は、「簡易タスク管理アプリケーション」を作成します。このアプリケーションでは、以下の機能を実現します。

  • C (Create): 新しいタスクを登録できる
  • R (Read): 登録されているタスクの一覧を閲覧できる
  • U (Update): 既存のタスクの内容を更新できる
  • D (Delete): 完了したタスクを削除できる

プロジェクトのフォルダ構成

まず、flask-crud-appという名前でプロジェクトフォルダを作成し、その中に以下の構成でファイルとフォルダを準備します。

flask-crud-app/
│
├── app.py           # Flaskアプリケーション本体のPythonコード
├── schema.sql       # データベースのテーブル定義を記述するSQLファイル
│
└── templates/       # HTMLテンプレートを格納するフォルダ
    ├── index.html   # タスク一覧・登録フォーム画面
    └── edit.html    # タスク編集画面


2. Step 1:プロジェクトの準備と基本画面の構築

① Flaskのインストールとプロジェクト初期化

まず、Flaskと、今後のためにpandasもインストールしておきましょう。コマンドプロンプト(ターミナル)で以下のコマンドを実行します。

pip install Flask pandas

次に、app.pyにFlaskアプリケーションの最も基本的なコードを記述します。

app.py

from flask import Flask, render_template

app = Flask(__name__)

# トップページ(タスク一覧)を表示
@app.route('/')
def index():
    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug=True)

この時点では、まだデータベースとの連携はなく、単純にindex.htmlを表示するだけの状態です。

② データベースの準備

schema.sqlファイルに、タスクを保存するためのテーブル定義を記述します。

schema.sql

CREATE TABLE tasks (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    title TEXT NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

そして、データベースを初期化するための簡単なPythonスクリプトも作成しておくと便利です。init_db.pyというファイル名で、app.pyと同じ階層に作成します。

init_db.py

import sqlite3

connection = sqlite3.connect('database.db')

with open('schema.sql') as f:
    connection.executescript(f.read())

connection.commit()
connection.close()

コマンドプロンプトでpython init_db.pyを実行すると、database.dbという名前のデータベースファイルが作成されます。

③ 基本画面の作成

templates/index.htmlに、タスク一覧と新規登録フォームの基本的なHTMLを記述します。

templates/index.html

<!DOCTYPE html>
<html>
<head>
    <title>Task Manager</title>
</head>
<body>
    <h1>Task Manager</h1>

    <form method="post">
        <input type="text" name="title" required>
        <button type="submit">Add Task</button>
    </form>

    <hr>

    <h2>Tasks</h2>
    <ul>
        </ul>
</body>
</html>


3. Step 2:【Read & Create】データの一覧表示と新規登録

次に、データベースからタスクを読み込んで表示する機能(Read)と、フォームから新しいタスクを登録する機能(Create)を実装します。これらは同じURL(トップページ)で処理するため、まとめて実装します。

app.pyを以下のように修正します。

app.py (修正後)

import sqlite3
from flask import Flask, render_template, request, redirect, url_for

app = Flask(__name__)

def get_db_connection():
    conn = sqlite3.connect('database.db')
    conn.row_factory = sqlite3.Row
    return conn

@app.route('/', methods=('GET', 'POST'))
def index():
    conn = get_db_connection()

    if request.method == 'POST':
        title = request.form['title']
        conn.execute('INSERT INTO tasks (title) VALUES (?)', (title,))
        conn.commit()
        conn.close()
        return redirect(url_for('index'))

    tasks = conn.execute('SELECT * FROM tasks').fetchall()
    conn.close()
    return render_template('index.html', tasks=tasks)

if __name__ == '__main__':
    app.run(debug=True)

  • get_db_connection(): データベースへの接続を簡単にするためのヘルパー関数です。
  • methods=('GET', 'POST'): このルートがGETリクエスト(ページ表示)とPOSTリクエスト(フォーム送信)の両方に対応することを宣言します。
  • if request.method == 'POST':: もしリクエストがPOST(フォーム送信)なら、INSERT文を実行してデータを保存し、トップページにリダイレクトします。
  • GETリクエストの場合: SELECT文で全タスクを取得し、tasksという変数でindex.htmlに渡します。

次に、index.htmlを修正して、渡されたtasksを表示できるようにします。

templates/index.html (修正後)

<ul>
        {% for task in tasks %}
        <li>
            {{ task['title'] }} ({{ task['created_at'] }})
        </li>
        {% endfor %}
</ul>

{% for task in tasks %} ... {% endfor %}はJinja2のループ構文で、tasksリストの中身を一つずつ取り出して<li>タグを生成します。


4. Step 3:【Update & Delete】データの更新と削除

最後に、既存タスクの編集と削除機能を実装します。

まず、app.pyに編集ページ用のルートと、更新処理、削除処理のルートを追加します。

app.py (追記)

# ... (index関数の後に追加) ...

@app.route('/<int:id>/edit/', methods=('GET', 'POST'))
def edit(id):
    conn = get_db_connection()

    if request.method == 'POST':
        title = request.form['title']
        conn.execute('UPDATE tasks SET title = ? WHERE id = ?', (title, id))
        conn.commit()
        conn.close()
        return redirect(url_for('index'))

    task = conn.execute('SELECT * FROM tasks WHERE id = ?', (id,)).fetchone()
    conn.close()
    return render_template('edit.html', task=task)

@app.route('/<int:id>/delete/', methods=('POST',))
def delete(id):
    conn = get_db_connection()
    conn.execute('DELETE FROM tasks WHERE id = ?', (id,))
    conn.commit()
    conn.close()
    return redirect(url_for('index'))

次に、編集画面用のHTMLファイルtemplates/edit.htmlを新規作成します。

templates/edit.html

<!DOCTYPE html>
<html>
<head>
    <title>Edit Task</title>
</head>
<body>
    <h1>Edit Task</h1>
    <form method="post">
        <input type="text" name="title" value="{{ task['title'] }}">
        <button type="submit">Update</button>
    </form>
</body>
</html>

最後に、一覧画面index.htmlに、編集と削除のリンクを追加します。

templates/index.html (最終版)

<ul>
        {% for task in tasks %}
        <li>
            {{ task['title'] }}
            - <a href="{{ url_for('edit', id=task['id']) }}">Edit</a>
            - <form action="{{ url_for('delete', id=task['id']) }}" method="post" style="display:inline;">
                <button type="submit">Delete</button>
              </form>
        </li>
        {% endfor %}
</ul>

これで全ての機能が実装できました!コマンドプロンプトでpython app.pyを実行し、ブラウザでhttp://127.0.0.1:5000にアクセスして、タスクの登録、編集、削除ができることを確認してください。


お疲れ様でした!これであなたは、PythonとFlaskを使って、基本的ながらもデータと連携する完全なWebアプリケーションを一人で構築する力を手に入れました。

セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。