MENU

【初心者がつまずいた】Flask入門:Pythonで簡単Webアプリ開発に挑戦!

今回は、「せっかくPythonを学んでいるなら、Webアプリも作れるようになりたい!」と思い、Flaskというフレームワークに挑戦してみました。最終的には、AIと組み合わせたwebアプリを開発してみたいと思っています。

「Flask」はPythonの軽量Webフレームワークで、初心者でも比較的取り組みやすいと聞いていたのですが、実際に手を動かしてみると難しい点やつまずくことがありました。今回は私が実際に試してみて学んだことをそのまま共有したいと思います!

この記事で分かること
  • Pythonで簡単なWebアプリケーションを作る手順
  • テンプレートとHTMLの連携方法
  • フォーム処理とデータ送信
  • SQLAlchemyを使ったデータベース連携
  • Webアプリ開発における基本的な設計と実装方法
目次

Flask環境構築:最初のつまずきポイント

まず最初に、Flaskをインストールして環境を整えることから始めました。といってもFlaskをインストールするだけですが、ここで一つポイントがあります。それは、仮想環境を使うことです。

Pythonを使い慣れている人なら説明はいらないかもしれませんが、プロジェクトごとに依存関係を分離していないと、後から大変なことになる場合があります。

実際私は、最初にグローバル環境にすべてインストールして進めてしまい、依存関係がおかしくなったことでPythonの再インストールまでする羽目になりました。皆さんは同じミスをしないように、しっかり仮想環境を準備しましょう。

私は、AnacondaでPythonをインストールしており、下のサイトを参考にcondaで仮想環境を作りました。

コマンドは以下のとおりです。この環境を使って、Flaskアプリを作成していきます!

conda create -n 環境名 python

最初のアプリ作成:Hello World!

環境ができたら、定番の「Hello World」を表示させることから始めてみました。

from flask import Flask

# Flaskアプリケーションのインスタンスを作成
app = Flask(__name__)

# ルートURL(/)へのアクセスに対するレスポンスを定義
@app.route('/')
def hello_world():
    return 'Hello, Flask World!'

# アプリケーションを実行(デバッグモードで)
if __name__ == '__main__':
    app.run(debug=True)

このコードをapp.pyとして保存し、実行してみました。実行は通常通り以下のコードです。

python app.py

すると、コンソールに以下のように表示されました。

 * Serving Flask app 'app'
 * Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 531-081-905

ブラウザでhttp://127.0.0.1:5000/にアクセスすると、「Hello, Flask World!」という文字が表示されました!

ただ、コードを見返して「@app.route('/')って何だろう?」と疑問が湧きました。調べてみると、これはデコレータと呼ばれるもので、URLパスと直下のPython関数を結びつける役割があるようです。

つまり、複数ページも以下のようにすれば設定出来るということですね。

また、3行目に警告が出ていますが、この警告は 開発用サーバーの使用に関する注意喚起 のようです。これも調べてみると、本番環境では GunicornやuWSGIなどのWSGIサーバーを使う ことで、安全かつ効率的にアプリを運用できる、とのことでした。
「そこで今度は、WSGIサーバーとは何だろう?」という疑問が出てきました。調べたことを簡単にまとめると、WSGIサーバーは、FlaskやDjangoなどのPythonのWebアプリをインターネットで使えるようにする”橋渡し役”のようなものでした。
導入することで、たくさんのリクエストをスムーズに処理できたり、セキュリティが向上したりするようです。導入する手順は、後半でまた記載します。

テンプレートとHTMLの連携:見た目を整える

「Hello World」はできましたが、実際のWebアプリはただのテキストではなく、HTMLで構造化されていますよね。そそこで、FlaskでどうやってHTMLを使うのか調べてみました。

テンプレートフォルダの作成

Flaskでは、慣例的にtemplatesというフォルダにHTMLファイルを配置するようです。プロジェクトのルートにtemplatesフォルダを作成し、その中にindex.htmlを作りました。

<!DOCTYPE html>
<html>
<head>
    <title>Flask学習ブログ</title>
</head>
<body>
    <h1>{{ message }}</h1>
    <p>Flaskでテンプレートを使ってみました!</p>
</body>
</html>

そしてapp.pyを以下のように変更しました。

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html', message='Hello, Templates!')

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

実行してみると、以下のように無事に表示することが出来ました!

「{{ message }}」の部分には「Hello, Templates!」という文字が表示されています。これはJinja2というテンプレートエンジンの記法で、Pythonの変数をHTMLに埋め込めるみたいです。

静的ファイル(CSS, JavaScript)の追加

HTMLを追加することが出来たので、次は見た目を整えるためにCSSの追加に挑戦してみました。Flaskでは静的ファイルはstaticフォルダに配置するようです。

body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 20px;
    background-color: #f5f5f5;
}

h1 {
    color: #333;
    border-bottom: 2px solid #ddd;
    padding-bottom: 10px;
}

ここまでのフォルダ構成をまとめると以下のようになります。

プロジェクト/
├── app.py
├── templates/
│ └── index.html
└── static/
└── style.css

そしてtemplates/index.htmlにCSSを読み込む行を追加します。

<!DOCTYPE html>
<html>
<head>
    <title>Flask学習ブログ</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <h1>{{ message }}</h1>
    <p>Flaskでテンプレートを使ってみました!</p>
</body>
</html>

実行してみると、スタイルが適用されたページが表示されました!

ここで使用しているurl_for()関数は、静的ファイルへのURLを生成してくれます。これなら開発環境と本番環境でパスが変わっても対応できそうです。

url_forを使うとパスを動的に生成できる

フォーム処理とデータの受け渡し:対話的なアプリに

静的なページを表示できるようになったので、次はユーザーからの入力を処理する方法を学んでみました。このあたりから難しくなってきたと感じたので、コードについては詳しく解説を入れていこうと思います。

シンプルなフォームの作成

まず、templates/index.htmlにフォームを追加しました。

<!DOCTYPE html>
<html>
<head>
    <title>Flask学習ブログ</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <h1>{{ message }}</h1>
    <p>Flaskでテンプレートを使ってみました!</p>
    
    <!-- フォームを作成 -->
    <form method="POST">
        <label for="name">あなたの名前:</label>
        <input type="text" id="name" name="name" required>
        <button type="submit">送信</button>
    </form>
    
    <!-- ユーザー名が送信されたら表示 -->
    {% if user_name %}
    <p>こんにちは、{{ user_name }}さん!</p>
    {% endif %}
</body>
</html>
コード解説
  • <form method="POST">
    • フォームを作成し、データを送信するためのタグ。
    • method="POST" を指定することで、データを送信できるようになります。
  • <label for="name">あなたの名前:</label>
    • 入力欄の説明(ラベル)を表示。
  • <input type="text" id="name" name="name" required>
    • ユーザーが名前を入力するためのテキストボックス。
    • required を指定すると、未入力のまま送信できなくなります。
  • <button type="submit">送信</button>
    • 送信ボタンを作成。
  • {% if user_name %} ... {% endif %}
    • ユーザーが名前を入力して送信した場合のみ、「こんにちは、〇〇さん!」と表示する。

そしてapp.pyファイルを編集し、フォームのデータを受け取るようにします。

from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    user_name = None  # ユーザー名を保存する変数を用意

    if request.method == 'POST':  # フォームが送信された場合
        user_name = request.form.get('name')  # フォームの入力値を取得
    
    # テンプレートを表示し、messageとuser_nameを渡す
    return render_template('index.html', message='Hello, Templates!', user_name=user_name)

if __name__ == '__main__':
    app.run(debug=True)  # アプリを実行(デバッグモード)
コード解説
  • from flask import Flask, render_template, request
    • Flaskの基本機能とテンプレート機能、フォームデータを受け取る機能をインポート。
  • app = Flask(__name__)
    • Flaskアプリを作成。
  • @app.route('/', methods=['GET', 'POST'])
    • /(ルートURL)にアクセスしたときの処理を定義。
    • methods=['GET', 'POST'] を指定することで、フォームの送信(POSTリクエスト)を受け取れるようにする。
  • if request.method == 'POST':
    • フォームが送信された(POSTリクエストが来た)場合の処理。
  • user_name = request.form.get('name')
    • フォームの name="name" の入力値を取得。
  • return render_template('index.html', message='Hello, Templates!', user_name=user_name)
    • index.html を表示し、messageuser_name を渡す。
methodsの’GET’と’POST’って何?

methodsで使われている’GET’と’POST’は、それぞれ以下の2つのHTTPメソッドを許可しています。

  • GET
    • クライアント(ブラウザなど)がサーバーからデータを取得するためのリクエスト
    • 例えば、Webページの読み込み時に使われる
    • フォームのデフォルトの送信方法
  • POST
    • クライアントがサーバーにデータを送信するためのリクエスト
    • 例えば、フォームのデータ送信時に使用される
    • データはリクエストボディに含まれるため、request.form で取得可能

このコードを実行してみると、以下のように無事に入力した名前を返してくれました!

リダイレクトとフラッシュメッセージ

Flaskでフォームを送信すると、デフォルトではそのままページが再読み込みされます。
しかし、これだと「リロード時に再送信の確認が出る」「ページの表示がスムーズでない」といった問題が発生しました。

そこで、以下の2つの機能を追加して修正してみました。

  1. リダイレクト(ページの移動)
    • フォームを送信した後、自動的に別のページ(または同じページ)に移動する
    • これにより、ページのリロードで再送信される問題を防ぐ
  2. フラッシュメッセージ(一時的な通知)
    • 「送信しました!」のような一時的なメッセージを画面に表示
    • ただし、ページを更新すると消える仕組み

まず、FlaskのPythonコードを修正して、フォーム送信後にリダイレクトしつつ、フラッシュメッセージを表示するようにします。

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

app = Flask(__name__)
app.secret_key = 'some_secret_key'  # フラッシュメッセージの機能を使うために必要

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':  # フォームが送信された場合
        user_name = request.form.get('name')  # 入力された名前を取得
        if user_name:  # 名前が入力されている場合のみ処理
            flash(f'ようこそ, {user_name}さん!')  # フラッシュメッセージをセット
            return redirect(url_for('index'))  # 同じページにリダイレクト
    
    return render_template('index.html', message='Hello, Templates!')

if __name__ == '__main__':
    app.run(debug=True)  # アプリを起動
コード解説
  • app.secret_key = 'some_secret_key'
    • フラッシュメッセージを使うために必須の設定
    • Flaskは、一時的なメッセージを「セッション」という仕組みで保存する。
    • そのために「秘密鍵(ひみつかぎ)」を設定する必要がある。
    • Flaskが「これは本当に正しいデータか?」をチェックするため。
  • flash(f'ようこそ, {user_name}さん!')
    • 「ようこそ、○○さん!」というメッセージを保存する。
    • ただし、これは「次のページ読み込み時に一度だけ表示される」特殊なメッセージ → つまり、画面を更新すると消える
  • return redirect(url_for('index'))
    • 「ページをリロードして、再度トップページ(/)を開く」
    • フォームを送信すると、ページを移動してから戻る動作になる。
    • こうすることで以下の問題を解決。
      1. フォームを再送信する問題を防げる
      2. フラッシュメッセージを適切に表示できる

次に、フラッシュメッセージをHTML側で表示できるようにします。

<!DOCTYPE html>
<html>
<head>
    <title>Flask学習ブログ</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <h1>{{ message }}</h1>
    
    <!-- フラッシュメッセージの表示 -->
    {% with messages = get_flashed_messages() %}
        {% if messages %}
            {% for message in messages %}
                <div class="flash-message">{{ message }}</div>
            {% endfor %}
        {% endif %}
    {% endwith %}
    
    <p>Flaskでテンプレートを使ってみました!</p>
    
    <form method="POST">
        <label for="name">あなたの名前:</label>
        <input type="text" id="name" name="name" required>
        <button type="submit">送信</button>
    </form>
</body>
</html>
コード解説
  • {% with messages = get_flashed_messages() %}
    • get_flashed_messages() で、Pythonで保存されたフラッシュメッセージを取得。
    • もしメッセージがあれば、それをmessagesという変数に入れる
    • {% with %} ... {% endwith %} の間で、その変数 messages を使う
  • {% for message in messages %}
    • メッセージが複数ある場合に、1つずつ表示する
    • 実際には、flash() を1回だけ呼んでいるので1つだけ表示される

今のままだと、フラッシュメッセージの見た目が味気ないので、CSSを追加して目立たせようと思います。CSSに以下を追加します。

.flash-message {
    background-color: #4CAF50; /* 緑色の背景 */
    color: white; /* 文字色を白に */
    padding: 10px;
    margin-bottom: 15px;
    border-radius: 5px; /* 角を丸くする */
}

実際に動かしてみると、以下のようにしっかりと表示することが出来ました。
また、ページの更新を行っても確認が入らず、最初の画面に戻るだけになりました。
これでかなり使いやすくなりました!

JavaScriptの非同期通信(Fech API)を使うことで、ページ遷移やリロードをせずに表示することも出来ます。この内容は以下の記事でまとめていますので、よければそちらもご覧ください。

データベースとの連携:情報を保存する

フォーム入力を受け取れるようになったので、次はデータを保存してみたいと思います。Flaskでよく使われるSQLAlchemyというものを使ってみます。

SQLAlchemyとは?

SQLAlchemyは、Pythonでデータベースを扱うためのライブラリです。

  • ORM(オブジェクト・リレーショナル・マッピング)という機能を持つ。
  • データベースをPythonのクラスとして扱えるので、SQLを書かずにデータを操作できる。
  • SQLite、MySQL、PostgreSQLなど複数のデータベースに対応している。

今回は、手軽に使えるSQLite(エスキューエル・ライト)をデータベースとして使用します。 SQLiteは、ファイルにデータを保存するタイプのデータベースなので、特別なサーバー設定なしで動作します。
まず、必要なライブラリをインストールします。

conda install flask-sqlalchemy

次にapp.pyを更新してデータベースの設定を追加します。
ここでは設定変更が多いため、いくつかの段階に分けて解説します。

データベース設定

まずはapp.py を編集して、データベースの設定を追加します。

from flask import Flask, render_template, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'  # SQLiteのデータベースファイル
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False  # 変更の追跡を無効化(パフォーマンス向上)
app.secret_key = 'some_secret_key'

db = SQLAlchemy(app)
コード解説
  • SQLALCHEMY_DATABASE_URI
    • データベースの保存場所を指定します。
    • sqlite:///site.db は、アプリと同じフォルダ内に site.db というデータベースファイルを作成する設定です。
  • SQLALCHEMY_TRACK_MODIFICATIONS
  • データベースの変更を追跡する機能ですが、不要なので False にします。

データモデルの作成

次に、データベースに保存するための「テーブル(表)」をPythonのクラスとして定義します。

# メッセージモデルの定義
class Message(db.Model):
    id = db.Column(db.Integer, primary_key=True)  # 自動で番号が増えるID
    name = db.Column(db.String(50), nullable=False)  # ユーザー名(必須)
    content = db.Column(db.Text, nullable=False)  # メッセージ内容(必須)
    date_posted = db.Column(db.DateTime, default=datetime.utcnow)  # 投稿日時(現在時刻)

    def __repr__(self):
        return f"Message('{self.name}', '{self.date_posted}')"
db.Model の解説
  • db.Model は、SQLAlchemy の ORM(オブジェクト・リレーショナル・マッピング) の機能を利用するための基礎クラスです。
  • class Message(db.Model): とすることで、Message クラスが データベースのテーブル に対応することになります。
  • db.Model を継承したクラスは、データベースの 1つのテーブル として扱われます。
Message クラスの解説
  • id:メッセージごとに自動で増える番号(主キー)
  • name:ユーザーの名前(最大50文字)
  • content:メッセージ内容(長文OK)
  • date_posted:投稿日時(デフォルトは現在時刻)
  • __repr__ メソッド:オブジェクトの情報をわかりやすく表示するための関数

データベースの作成

データベースを作成するために、以下のコードを追加します。

# データベースの作成
with app.app_context():
    db.create_all()
コード解説
  • Flask 2.0以降では、db.create_all() を実行するときにアプリケーションコンテキストが必要です。
  • これがないと「アプリケーションの設定を適用できない」といったエラーが発生します。
    with app.app_context(): を使って、Flaskのアプリケーションコンテキスト内で実行します。

フォーム送信の処理(データベースへの保存)

フォームから送信されたデータをデータベースに保存し、一覧を表示できるようにします。

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        user_name = request.form.get('name')
        user_message = request.form.get('message')
        
        if user_name and user_message:
            new_message = Message(name=user_name, content=user_message)
            db.session.add(new_message)  # データを追加
            db.session.commit()  # データベースに保存
            flash('メッセージが投稿されました!')
            return redirect(url_for('index'))
    
    # すべてのメッセージを取得して表示
    messages = Message.query.order_by(Message.date_posted.desc()).all()
    return render_template('index.html', title='メッセージボード', messages=messages)

if __name__ == '__main__':
    app.run(debug=True)
コード解説
  • db.session.add(new_message):新しいデータをデータベースに追加
  • db.session.commit():データを実際に保存(確定)
  • Message.query.order_by(Message.date_posted.desc()).all():保存されたメッセージを新しい順に取得

HTMLテンプレートの更新

メッセージ一覧を表示するために、templates/index.html を更新します。

<!DOCTYPE html>
<html>
<head>
    <title>{{ title }}</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <h1>Flask メッセージボード</h1>
    
    {% with messages = get_flashed_messages() %}
        {% if messages %}
            {% for message in messages %}
                <div class="flash-message">{{ message }}</div>
            {% endfor %}
        {% endif %}
    {% endwith %}
    
    <div class="form-container">
        <h2>新しいメッセージを投稿</h2>
        <form method="POST">
            <div class="form-group">
                <label for="name">お名前:</label>
                <input type="text" id="name" name="name" required>
            </div>
            <div class="form-group">
                <label for="message">メッセージ:</label>
                <textarea id="message" name="message" rows="4" required></textarea>
            </div>
            <button type="submit">投稿する</button>
        </form>
    </div>
    
    <div class="messages-container">
        <h2>メッセージ一覧</h2>
        {% if messages %}
            {% for msg in messages %}
                <div class="message-card">
                    <div class="message-header">
                        <span class="message-author">{{ msg.name }}</span>
                        <span class="message-date">{{ msg.date_posted.strftime('%Y-%m-%d %H:%M') }}</span>
                    </div>
                    <div class="message-content">
                        {{ msg.content }}
                    </div>
                </div>
            {% endfor %}
        {% else %}
            <p>まだメッセージはありません。最初の投稿をしてみましょう!</p>
        {% endif %}
    </div>
</body>
</html>

CSSスタイルの変更

最後に、表示を見やすくするためにCSSに以下の内容を追記します。

/* 既存のスタイルに追加 */
.form-container, .messages-container {
    background-color: white;
    padding: 15px;
    margin-bottom: 20px;
    border-radius: 5px;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

.form-group {
    margin-bottom: 15px;
}

.form-group label {
    display: block;
    margin-bottom: 5px;
}

input[type="text"], textarea {
    width: 100%;
    padding: 8px;
    border: 1px solid #ddd;
    border-radius: 4px;
}

button {
    background-color: #4CAF50;
    color: white;
    padding: 10px 15px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

button:hover {
    background-color: #45a049;
}

.message-card {
    background-color: #f9f9f9;
    padding: 10px;
    margin-bottom: 10px;
    border-radius: 4px;
    border-left: 4px solid #4CAF50;
}

.message-header {
    display: flex;
    justify-content: space-between;
    margin-bottom: 5px;
    font-size: 0.9em;
}

.message-author {
    font-weight: bold;
    color: #333;
}

.message-date {
    color: #777;
}

.message-content {
    line-height: 1.4;
}

CSS追加前と追加後の表示画面を見比べてみました。
CSSの追加前後では、見た目の良さが全然違いますね!

データベースとの連携まとめ

以上で、Flaskでデータを保存し、表示する仕組みが完成しました!
まとめると、以下のような内容でしたね。

  • Flask-SQLAlchemyを使うと、データベースを簡単に扱える。
  • db.Model を継承してデータモデルを定義する。
  • db.session.add() でデータを追加し、db.session.commit() で保存する。
  • Message.query.all() でデータを取得できる。

また、【データベースの作成】で解説しましたが、私は最初db.create_all()をアプリケーションコンテキスト外で呼び出しており、エラーが発生して悩みました。古い情報で学習した方は、以下の点には注意が必要ですね。

db.create_all()with app.app_context():を使ってアプリケーションコンテキスト内で呼び出す。(Flask 2.0以降の変更点

デプロイの準備:本番環境への移行

ローカル環境(自分のPC上)で動作確認ができたので、次は本番環境に向けた準備をします。
本番環境とは、インターネット上にアプリケーションを公開し、誰でもアクセスできる状態にする環境のことです。
ただし、今回は実際にデプロイ(公開)するのではなく、準備の段階を学びます。

環境変数の利用

本番環境では、アプリケーションの設定情報(例えば データベースの接続情報シークレットキー など)を 直接コードに書かず に、環境変数から読み込むようにします。

なぜ環境変数を使うのか?
  • セキュリティ対策
    • シークレットキーをソースコードに直接書くと、万が一コードを公開した際に悪用される危険があります。
  • 環境ごとの設定変更を簡単にするため
    • ローカル環境(開発用)と本番環境(公開用)で異なる設定を使いたい場合に便利です。
import os  # 環境変数を扱うためのモジュール
from flask import Flask, render_template, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime

app = Flask(__name__)

# 環境変数からデータベースの接続情報を取得(なければSQLiteを使用)
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL', 'sqlite:///site.db')

# SQLAlchemy の設定(変更追跡を無効化)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# シークレットキーも環境変数から取得(開発時はデフォルト値を使用)
app.secret_key = os.environ.get('SECRET_KEY', 'dev_secret_key')

# 本番環境ではデバッグモードをオフにする
app.debug = os.environ.get('FLASK_DEBUG', 'False').lower() == 'true'

# 以下は前と同じ...
コード解説
  • os.environ.get('DATABASE_URL', 'sqlite:///site.db')
    • 環境変数 DATABASE_URL の値を取得し、もし設定されていなければ 'sqlite:///site.db' をデフォルトとして使う。
    • これにより、本番環境では MySQL や PostgreSQL などの本番用データベースを指定できる。
  • os.environ.get('SECRET_KEY', 'dev_secret_key')
    • 環境変数 SECRET_KEY の値を取得し、なければ 'dev_secret_key' をデフォルトとして使う。
    • シークレットキーは、セッション情報(ログイン情報など)を保護するためのキーなので、本番環境では強力なキーを設定する。
  • os.environ.get('FLASK_DEBUG', 'False').lower() == 'true'
    • FLASK_DEBUG の環境変数が 'true' ならデバッグモードを有効にし、それ以外なら無効にする。
    • 本番環境ではデバッグモードをオフにし、エラーメッセージを一般ユーザーに見せないようにする。

要件ファイル(environment.yml)の作成

デプロイ時に、開発環境と同じ Python ライブラリ(パッケージ)を本番環境にインストールする必要があります。
そのために、使用しているパッケージの一覧をenvironment.yml というファイルに保存します。

conda env export > environment.yml

このファイルを本番サーバーにアップロードし、以下のコマンドで環境を再現できます。

conda env create -f environment.yml

gunicorn の設定(WSGIサーバー)

WSGI(Web Server Gateway Interface)は、Python の Web アプリケーションを 本番環境で動かすための仕組み です。Flask はデフォルトで開発用サーバーを持っていますが、これは 本番環境では非推奨 のようです。そこで、gunicorn(グニコーン) という WSGIサーバーを使います。

gunicorn のインストール(ターミナルで実行)

conda install -c conda-forge gunicorn

Procfile の作成(Heroku でのデプロイ時に使用)

web: gunicorn app:app
Procfile 内容の解説
  • web: → Webアプリとして起動することを指定。
  • gunicorn app:appapp.pyapp を WSGI サーバーで起動する。

デプロイの準備が完了!

ここまでの手順を踏むことで、本番環境へのデプロイの準備が整いました。ただし、実際のデプロイ手順は 使用するホスティングサービス(Heroku, PythonAnywhere, AWS, GCP など)によって異なります。

近いうちに、実際にHeroku などのサービスを使ってデプロイをしてみようと思います。

まとめ

今回はFlaskでのアプリ開発を初めて試してみた学習記録を発信しました。

学んだこと
  • Flaskは本当に軽量で柔軟:最初は「Hello World」程度の簡単なコードから始めて、徐々に機能を追加できるのが初心者には嬉しいポイントでした。
  • 環境構築の重要性:最初に仮想環境を作っておくことで、依存関係のトラブルを回避することが重要です。
  • テンプレートシステムの便利さ:Jinja2テンプレートを使うことで、動的なHTMLページを簡単に作成できました。
  • データベース連携はORM(SQLAlchemy)がおすすめ:生のSQLクエリを書く必要がなく、Pythonのオブジェクトとして扱えたため、操作しやすかったです。

これからもっとFlaskを深く学んで、認証システムやAPI機能など、さらに高度な機能を取り入れたアプリ開発に挑戦するのも楽しそうだと感じました。今回のメッセージボードアプリも、機会があればユーザー登録機能やファイルアップロード機能などを追加して、機能を拡張していきたいですね。

ただ、目的はAIと組み合わせたwebアプリを開発なので、まずはそちらを優先しようと思います。

次に試してみたいこと
  • 業務効率化ツールの作成(自動メール返信など)
  • FlaskでWebチャットボットの作成
  • ChatGPTと他のAI(Claude, Gemini)を比較

では、また学習した内容を随時紹介していきますので、良ければ他の記事もご覧ください!

よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

非IT職のデスクワーカーです。
簡単な業務効率化やデータ分析にPythonをよく活用しています。
このブログを通してAI技術を身に着け、より業務効率化や新しいものを作りたいと考えています。

目次