ななぶろ

-お役立ち情報を気楽に紹介するブログ-

PythonWebアプリケーション開発入門:初心者向け20問と実践ガイド

www.amazon.co.jp

Python Webアプリケーション開発入門:初心者向け20問と実践ガイド

Pythonは、その汎用性と読みやすさから、Webアプリケーション開発においても非常に人気のある言語です。本記事では、PythonのWebアプリケーション開発を始めるための初心者向けの練習問題20問に加え、各問題に対する詳細な解説、実践的なヒント、そしてさらに学習するためのリソースを提供します。Flaskという軽量なWebフレームワークとRequestsライブラリを中心に、段階的にスキルアップできるよう構成されています。

はじめに

PythonでWebアプリケーション開発を始めるにあたり、まずは基本的な概念を理解することが重要です。Webアプリケーションは、クライアント(通常はウェブブラウザ)とサーバーの間でHTTPプロトコルを通じて通信を行うプログラムです。Flaskは、このようなWebアプリケーションの構築を容易にするためのフレームワークであり、Requestsは、Webサイトからデータを取得するためのライブラリです。

Introduction:

Starting web application development with Python requires understanding basic concepts. Web applications are programs that communicate via the HTTP protocol between a client (typically a web browser) and a server. Flask is a framework that simplifies building these applications, and Requests is a library for fetching data from websites.

1. Hello, World! を表示するWebアプリケーションを作成

これは、Webアプリケーション開発の最初のステップです。Flaskを使って、ブラウザに "Hello, World!" と表示するシンプルなWebアプリケーションを作成します。

  • コード例:
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"

if __name__ == "__main__":
    app.run(debug=True)
  • 解説: Flask(__name__) でFlaskのアプリケーションインスタンスを作成します。 @app.route("/") は、ルートURL ("/") にアクセスした際に実行される関数を定義するデコレータです。 return "<p>Hello, World!</p>" は、ブラウザに表示するHTML文字列を返します。 app.run(debug=True) は、開発サーバーを起動し、デバッグモードを有効にします。

  • 実践: このコードを hello_world.py という名前で保存し、ターミナルで python hello_world.py を実行してWebアプリケーションを起動します。ブラウザで http://127.0.0.1:5000/ にアクセスすると、"Hello, World!" と表示されます。

Explanation:

This is the first step in web application development. Create a simple web application using Flask that displays "Hello, World!" in the browser. Flask(__name__) creates an instance of the Flask application. @app.route("/") is a decorator that defines the function to be executed when accessing the root URL ("/"). return "<p>Hello, World!</p>" returns the HTML string to be displayed in the browser. app.run(debug=True) starts the development server and enables debug mode.

2. ユーザーに名前を入力してもらい、挨拶を表示する

HTMLフォームを使って、ユーザーの名前を入力させ、入力された名前を使って "Hello, [名前]!" と表示するWebアプリケーションを作成します。

  • コード例:
from flask import Flask, request, render_template

app = Flask(__name__)

@app.route("/", methods=["GET", "POST"])
def hello():
    if request.method == "POST":
        name = request.form["name"]
        return f"<p>Hello, {name}!</p>"
    else:
        return render_template("hello.html")

if __name__ == "__main__":
    app.run(debug=True)
  • HTMLテンプレート (templates/hello.html):
<!DOCTYPE html>
<html>
<head>
    <title>Hello</title>
</head>
<body>
    <h1>Enter your name:</h1>
    <form method="post">
        <input type="text" name="name">
        <button type="submit">Submit</button>
    </form>
</body>
</html>
  • 解説: methods=["GET", "POST"] は、このルートがGETリクエストとPOSTリクエストの両方を受け入れることを指定します。 request.method == "POST" でフォームからのPOSTリクエストかどうかを判定します。 name = request.form["name"] でフォームから送信された名前を取得します。 render_template("hello.html") は、HTMLテンプレートファイルをレンダリングしてブラウザに返します。

  • 実践: templates フォルダを作成し、その中に hello.html を保存します。上記のPythonコードを app.py という名前で保存し、ターミナルで python app.py を実行してWebアプリケーションを起動します。ブラウザで http://127.0.0.1:5000/ にアクセスすると、フォームが表示されます。名前を入力して送信すると、挨拶が表示されます。

Explanation:

Create a web application that uses an HTML form to ask the user for their name and then displays "Hello, [Name]!". The route now accepts both GET and POST requests. request.method == "POST" checks if the request is from the form (a POST request). name = request.form["name"] retrieves the name submitted in the form. render_template("hello.html") renders the HTML template file.

3. GETリクエストでパラメータを受け取る

URLにパラメータが含まれている場合、そのパラメータの値を使って "Hello, [名前]!" と表示するWebアプリケーションを作成します。

  • コード例:
from flask import Flask, request

app = Flask(__name__)

@app.route("/hello/<name>")
def hello_with_parameter(name):
    return f"<p>Hello, {name}!</p>"

if __name__ == "__main__":
    app.run(debug=True)
  • 解説: @app.route("/hello/<name>") は、URLの /hello/ の後に続く文字列を name という変数に格納し、その値を関数に渡します。 例えば、/hello/John にアクセスすると、name 変数には "John" が格納されます。

  • 実践: ブラウザで http://127.0.0.1:5000/hello/John にアクセスすると、"Hello, John!" と表示されます。

Explanation:

Create a web application that displays "Hello, [Name]!" using the value of a parameter in the URL. The route now includes a variable part <name> which captures the string after /hello/. For example, accessing /hello/John will pass "John" to the function as the name variable.

4. POSTリクエストでデータを送信する

HTMLフォームを使って、ユーザーにメッセージを入力させ、POSTリクエストでサーバーに送信し、受信したメッセージを表示するWebアプリケーションを作成します。

  • コード例: (上記2番の問題の続き)
from flask import Flask, request, render_template

app = Flask(__name__)

@app.route("/", methods=["GET", "POST"])
def hello():
    if request.method == "POST":
        message = request.form["message"]
        return f"<p>You said: {message}</p>"
    else:
        return render_template("hello.html")

if __name__ == "__main__":
    app.run(debug=True)
  • HTMLテンプレート (templates/hello.html):
<!DOCTYPE html>
<html>
<head>
    <title>Hello</title>
</head>
<body>
    <h1>Enter your message:</h1>
    <form method="post">
        <input type="text" name="message">
        <button type="submit">Submit</button>
    </form>
</body>
</html>
  • 解説: POSTリクエストを受け取った場合、request.form["message"] でフォームから送信されたメッセージを取得し、それを表示します。

  • 実践: 上記のHTMLテンプレートとPythonコードを使用し、ブラウザで http://127.0.0.1:5000/ にアクセスすると、フォームが表示されます。メッセージを入力して送信すると、受信したメッセージが表示されます。

Explanation:

Create a web application that uses an HTML form to ask the user for a message, sends it via a POST request to the server, and then displays the received message. The route now handles POST requests to receive the message from the form.

5. 静的ファイルを配信する

HTMLファイルやCSSファイルなどの静的ファイルをWebアプリケーションから配信できるように設定します。

  • コード例:
from flask import Flask, send_from_directory

app = Flask(__name__)

@app.route("/")
def index():
    return send_from_directory('static', 'index.html')

@app.route('/<path:filename>')
def serve_static(filename):
    return send_from_directory('static', filename)

if __name__ == "__main__":
    app.run(debug=True)
  • HTMLファイル (static/index.html):
<!DOCTYPE html>
<html>
<head>
    <title>Static Files</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <h1>Hello from a static file!</h1>
</body>
</html>
  • CSSファイル (static/style.css):
h1 {
    color: blue;
}
  • 解説: send_from_directory('static', 'index.html') は、static フォルダにある index.html ファイルを配信します。 <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> は、CSSファイルを読み込みます。

  • 実践: static フォルダを作成し、その中に index.htmlstyle.css を保存します。上記のPythonコードを app.py という名前で保存し、ターミナルで python app.py を実行してWebアプリケーションを起動します。ブラウザで http://127.0.0.1:5000/ にアクセスすると、静的ファイルが表示されます。

Explanation:

Configure the web application to serve static files like HTML and CSS from a designated folder. The route uses send_from_directory('static', 'index.html') to serve the file. The HTML template includes a link to the CSS file using url_for('static', filename='style.css').

6. テンプレートエンジン (Jinja2) を使用する

HTMLファイルをテンプレートとして作成し、Flaskのテンプレートエンジンを使って、変数やループなどの動的なコンテンツを生成します。

  • コード例:
from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def index():
    items = ["apple", "banana", "cherry"]
    return render_template("index.html", items=items)

if __name__ == "__main__":
    app.run(debug=True)
  • HTMLテンプレート (templates/index.html):
<!DOCTYPE html>
<html>
<head>
    <title>Jinja2 Template</title>
</head>
<body>
    <h1>Items:</h1>
    <ul>
        {% for item in items %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>
</body>
</html>
  • 解説: render_template("index.html", items=items) は、index.html テンプレートをレンダリングし、items 変数をテンプレートに渡します。 {% for item in items %}{{ item }} は、Jinja2の構文で、リストをループ処理して各要素を表示します。

  • 実践: templates フォルダを作成し、その中に index.html を保存します。上記のPythonコードを app.py という名前で保存し、ターミナルで python app.py を実行してWebアプリケーションを起動します。ブラウザで http://127.0.0.1:5000/ にアクセスすると、リストが表示されます。

Explanation:

Create an HTML template and use Flask's Jinja2 templating engine to generate dynamic content like variables and loops. The route uses render_template("index.html", items=items) to render the template, passing in a list of items. The template iterates through the list using Jinja2 syntax: {% for item in items %} and displays each item with {{ item }}.

7. Cookieを設定・取得する

ユーザーにCookieを設定し、次にアクセスした際にCookieの値を取得して表示するWebアプリケーションを作成します。

  • コード例:
from flask import Flask, request, make_response

app = Flask(__name__)

@app.route("/")
def index():
    if 'username' in request.cookies:
        username = request.cookies['username']
        return f"<p>Welcome back, {username}!</p>"
    else:
        return "<p>Please set a cookie.</p><form method='post'><input type='text' name='username'><button type='submit'>Set Cookie</button></form>"

@app.route("/", methods=['POST'])
def set_cookie():
    username = request.form['username']
    resp = make_response("<p>Cookie set!</p>")
    resp.set_cookie('username', username)
    return resp

if __name__ == "__main__":
    app.run(debug=True)
  • 解説: request.cookies['username'] でCookieの値を取得します。 make_response("<p>Cookie set!</p>") は、レスポンスオブジェクトを作成します。 resp.set_cookie('username', username) は、Cookieを設定します。

  • 実践: 上記のPythonコードを app.py という名前で保存し、ターミナルで python app.py を実行してWebアプリケーションを起動します。ブラウザで http://127.0.0.1:5000/ にアクセスすると、Cookieの設定フォームが表示されます。ユーザー名を入力して送信すると、Cookieが設定され、次にアクセスした際には "Welcome back, [ユーザー名]!" と表示されます。

Explanation:

Create a web application that sets a cookie for the user and then retrieves its value on subsequent visits. request.cookies['username'] retrieves the cookie value. make_response("<p>Cookie set!</p>") creates a response object, and resp.set_cookie('username', username) sets the cookie.

8. セッション管理を行う

ユーザーセッションを作成し、ログイン状態を保持するWebアプリケーションを作成します。

  • コード例:
from flask import Flask, session, redirect, url_for

app = Flask(__name__)
app.secret_key = 'some secret key'  # Change this!

@app.route('/')
def index():
    if 'username' in session:
        return f"Logged in as {session['username']}"
    else:
        return '<a href="/login">Login</a>'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('index'))
    else:
        return '<form method="post"><input type="text" name="username"><button type="submit">Login</button></form>'

@app.route('/logout')
def logout():
    session.pop('username', None)
    return redirect(url_for('index'))

if __name__ == '__main__':
    app.run(debug=True)
  • 解説: app.secret_key = 'some secret key' は、セッションを安全に保つために必要な秘密鍵を設定します。 session['username'] = request.form['username'] でユーザー名をセッションに保存します。 session.pop('username', None) でセッションからユーザー名を取り除きます。

  • 実践: 上記のPythonコードを app.py という名前で保存し、ターミナルで python app.py を実行してWebアプリケーションを起動します。ブラウザで http://127.0.0.1:5000/ にアクセスすると、ログインページが表示されます。ユーザー名を入力して送信すると、セッションが作成され、ログイン状態が保持されます。

Explanation:

Create a web application that manages user sessions to maintain login state. The app.secret_key is crucial for session security. The username is stored in the session using session['username'] = request.form['username'], and removed during logout with session.pop('username', None).

9. 外部APIからデータを取得する

JSONPlaceholderなどの公開されているAPIからデータを取得し、Webページに表示するWebアプリケーションを作成します。

  • コード例:
from flask import Flask, render_template
import requests

app = Flask(__name__)

@app.route("/")
def index():
    response = requests.get("https://jsonplaceholder.typicode.com/todos/1")
    data = response.json()
    return render_template("index.html", data=data)

if __name__ == "__main__":
    app.run(debug=True)
  • HTMLテンプレート (templates/index.html):
<!DOCTYPE html>
<html>
<head>
    <title>External API Data</title>
</head>
<body>
    <h1>Todo Item:</h1>
    <p>Title: {{ data['title'] }}</p>
    <p>Completed: {{ data['completed'] }}</p>
</body>
</html>
  • 解説: requests.get("https://jsonplaceholder.typicode.com/todos/1") でAPIにGETリクエストを送信します。 response.json() でJSONデータをPythonの辞書に変換します。

  • 実践: 上記のPythonコードを app.py という名前で保存し、ターミナルで python app.py を実行してWebアプリケーションを起動します。ブラウザで http://127.0.0.1:5000/ にアクセスすると、APIから取得したデータが表示されます。

Explanation:

Create a web application that retrieves data from an external API (like JSONPlaceholder) and displays it on the webpage. The code uses requests.get() to fetch data, converts the response to JSON using response.json(), and renders the data in a template.

10. エラーハンドリングを行う

存在しないURLにアクセスした場合のエラーページを表示するWebアプリケーションを作成します。

  • コード例:
from flask import Flask, render_template

app = Flask(__name__)

@app.errorhandler(404)
def page_not_found(error):
    return render_template('404.html'), 404

if __name__ == "__main__":
    app.run(debug=True)
  • HTMLテンプレート (templates/404.html):
<!DOCTYPE html>
<html>
<head>
    <title>Page Not Found</title>
</head>
<body>
    <h1>404 - Page Not Found</h1>
</body>
</html>
  • 解説: @app.errorhandler(404) は、404エラーが発生した場合に実行される関数を定義します。 render_template('404.html')404.html テンプレートをレンダリングし、404ステータスコードを返します。

  • 実践: 上記のPythonコードを app.py という名前で保存し、ターミナルで python app.py を実行してWebアプリケーションを起動します。ブラウザで存在しないURL (例: http://127.0.0.1:5000/nonexistent) にアクセスすると、404エラーページが表示されます。

Explanation:

Create a web application that handles errors, specifically displaying a custom error page when a user tries to access a non-existent URL. The @app.errorhandler(404) decorator defines the function to handle 404 errors and renders a custom template.

11. フォームのバリデーションを行う

HTMLフォームで入力されたデータが正しい形式であるか検証するWebアプリケーションを作成します。

  • コード例:
from flask import Flask, render_template, request
from wtforms import Form, EmailField, validators

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your secret key'  # Change this!

class ContactForm(Form):
    email = EmailField('Email', [validators.DataRequired(), validators.Email()])

@app.route('/', methods=['GET', 'POST'])
def index():
    form = ContactForm()
    if form.validate_on_submit():
        # Process the data here
        return '<p>Thank you for your message!</p>'
    return render_template('index.html', form=form)

if __name__ == '__main__':
    app.run(debug=True)
  • HTMLテンプレート (templates/index.html):
<!DOCTYPE html>
<html>
<head>
    <title>Form Validation</title>
</head>
<body>
    <h1>Contact Form</h1>
    {% for error in form.errors %}
        <p class="error">{{ error }}</p>
    {% endfor %}
    <form method="post">
        {{ form.email(class='form-control') }}
        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
</body>
</html>
  • 解説: ContactForm クラスは、フォームのフィールド (メールアドレス) とバリデーションルールを定義します。 form.validate_on_submit() でフォームが有効かどうか検証します。

  • 実践: 上記のPythonコードを app.py という名前で保存し、ターミナルで python app.py を実行してWebアプリケーションを起動します。ブラウザでフォームに無効なメールアドレスを入力して送信すると、エラーメッセージが表示されます。

Explanation:

Create a web application that validates form input to ensure data is in the correct format (e.g., email address). The code uses WTForms to define the form fields and validation rules, and form.validate_on_submit() to check if the form is valid.

12. データベースに接続する

SQLiteなどの軽量なデータベースに接続し、データを保存・取得するWebアプリケーションを作成します。

  • コード例:
from flask import Flask, render_template
import sqlite3

app = Flask(__name__)
DATABASE = 'database.db'

def get_db():
    conn = sqlite3.connect(DATABASE)
    conn.row_factory = sqlite3.Row  # Access columns by name
    return conn

@app.route('/')
def index():
    conn = get_db()
    cur = conn.cursor()
    cur.execute('SELECT * FROM items')
    items = cur.fetchall()
    conn.close()
    return render_template('index.html', items=items)

if __name__ == '__main__':
    # Create the table if it doesn't exist
    with sqlite3.connect(DATABASE) as conn:
        cur = conn.cursor()
        cur.execute('''
            CREATE TABLE IF NOT EXISTS items (
                id INTEGER PRIMARY KEY,
                name TEXT NOT NULL
            )
        ''')
        conn.commit()
    app.run(debug=True)
  • HTMLテンプレート (templates/index.html):
<!DOCTYPE html>
<html>
<head>
    <title>Database Connection</title>
</head>
<body>
    <h1>Items</h1>
    <ul>
        {% for item in items %}
            <li>{{ item['name'] }}</li>
        {% endfor %}
    </ul>
</body>
</html>
  • 解説: get_db() 関数は、データベースに接続し、結果を辞書として返すように設定します。 cur.execute('SELECT * FROM items') でテーブルからデータを取得します。

  • 実践: 上記のPythonコードを app.py という名前で保存し、ターミナルで python app.py を実行してWebアプリケーションを起動します。ブラウザでデータベースに接続され、データが表示されます。

Explanation:

Create a web application that connects to a database (like SQLite) and stores/retrieves data. The code uses sqlite3 to connect to the database, execute queries, and fetch results.

13. RESTful APIを作成する

GET, POST, PUT, DELETEなどのHTTPメソッドを使用して、データの取得・作成・更新・削除を行うRESTful APIを作成します。

  • コード例:
from flask import Flask, jsonify, request
import sqlite3

app = Flask(__name__)
DATABASE = 'database.db'

def get_db():
    conn = sqlite3.connect(DATABASE)
    conn.row_factory = sqlite3.Row
    return conn

@app.route('/items', methods=['GET'])
def get_items():
    conn = get_db()
    cur = conn.cursor()
    cur.execute('SELECT * FROM items')
    items = cur.fetchall()
    conn.close()
    item_list = [dict(item) for item in items]  # Convert to dicts
    return jsonify(item_list)

@app.route('/items', methods=['POST'])
def create_item():
    name = request.json['name']
    conn = get_db()
    cur = conn.cursor()
    cur.execute('INSERT INTO items (name) VALUES (?)', (name,))
    conn.commit()
    conn.close()
    return jsonify({'message': 'Item created'}), 201

if __name__ == '__main__':
    # Create the table if it doesn't exist
    with sqlite3.connect(DATABASE) as conn:
        cur = conn.cursor()
        cur.execute('''
            CREATE TABLE IF NOT EXISTS items (
                id INTEGER PRIMARY KEY,
                name TEXT NOT NULL
            )
        ''')
        conn.commit()
    app.run(debug=True)
  • 解説: @app.route('/items', methods=['GET']) は、GETリクエストを受け付けるエンドポイントを定義します。 request.json['name'] でJSONデータから名前を取得します。

  • 実践: 上記のPythonコードを app.py という名前で保存し、ターミナルで python app.py を実行してWebアプリケーションを起動します。APIエンドポイントにリクエストを送信することで、データの取得・作成を行うことができます。

Explanation:

Create a RESTful API using Flask to handle GET, POST, PUT, and DELETE requests for data management. The code defines endpoints for retrieving all items (/items with GET) and creating new items (/items with POST).

14. 認証機能を実装する

ユーザー名とパスワードを使ってログインできるWebアプリケーションを作成します。

  • コード例:
from flask import Flask, render_template, request, redirect, url_for, session
import sqlite3

app = Flask(__name__)
app.secret_key = 'your secret key'  # Change this!

DATABASE = 'database.db'

def get_db():
    conn = sqlite3.connect(DATABASE)
    conn.row_factory = sqlite3.Row
    return conn

@app.route('/')
def index():
    if 'username' in session:
        return render_template('index.html')
    else:
        return redirect(url_for('login'))

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']  # In a real app, hash the password!

        conn = get_db()
        cur = conn.cursor()
        cur.execute('SELECT * FROM users WHERE username = ?', (username,))
        user = cur.fetchone()
        conn.close()

        if user and user['password'] == password:  # In a real app, compare hashed passwords!
            session['username'] = username
            return redirect(url_for('index'))
        else:
            return render_template('login.html', error='Invalid credentials')
    else:
        return render_template('login.html')

@app.route('/logout')
def logout():
    session.pop('username', None)
    return redirect(url_for('login'))

if __name__ == '__main__':
    # Create the users table if it doesn't exist
    with sqlite3.connect(DATABASE) as conn:
        cur = conn.cursor()
        cur.execute('''
            CREATE TABLE IF NOT EXISTS users (
                id INTEGER PRIMARY KEY,
                username TEXT NOT NULL UNIQUE,
                password TEXT NOT NULL
            )
        ''')
        conn.commit()

    app.run(debug=True)
  • HTMLテンプレート (templates/login.html):
<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
</head>
<body>
    <h1>Login</h1>
    {% if error %}
        <p style="color: red;">{{ error }}</p>
    {% endif %}
    <form method="post">
        <label for="username">Username:</label><br>
        <input type="text" id="username" name="username"><br><br>
        <label for="password">Password:</label><br>
        <input type="password" id="password" name="password"><br><br>
        <button type="submit">Login</button>
    </form>
</body>
</html>
  • 解説: session['username'] = username でユーザー名をセッションに保存し、ログイン状態を保持します。

  • 実践: 上記のPythonコードを app.py という名前で保存し、ターミナルで python app.py を実行してWebアプリケーションを起動します。ログインフォームに入力することで、認証機能を利用できます。

Explanation:

Implement authentication functionality in a web application using usernames and passwords. The code uses sessions to maintain user login state, connects to a database to verify credentials, and provides login and logout routes. Important: This example stores passwords in plain text for simplicity. In a real-world application, you should always hash passwords before storing them in the database.

15. 認可機能を実装する

特定のユーザーロール (例: 管理者) にのみアクセスできるページを作成します。

  • コード例:
from flask import Flask, render_template, redirect, url_for, session
import sqlite3

app = Flask(__name__)
app.secret_key = 'your secret key'  # Change this!

DATABASE = 'database.db'

def get_db():
    conn = sqlite3.connect(DATABASE)
    conn.row_factory = sqlite3.Row
    return conn

@app.route('/')
def index():
    if 'username' in session:
        return render_template('index.html')
    else:
        return redirect(url_for('login'))

@app.route('/admin')
def admin():
    if 'username' in session and session['role'] == 'admin':
        return render_template('admin.html')
    else:
        return redirect(url_for('login'))

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']  # In a real app, hash the password!

        conn = get_db()
        cur = conn.cursor()
        cur.execute('SELECT * FROM users WHERE username = ?', (username,))
        user = cur.fetchone()
        conn.close()

        if user and user['password'] == password:  # In a real app, compare hashed passwords!
            session['username'] = username
            session['role'] = user['role']  # Store the user's role
            return redirect(url_for('index'))
        else:
            return render_template('login.html', error='Invalid credentials')
    else:
        return render_template('login.html')

@app.route('/logout')
def logout():
    session.pop('username', None)
    session.pop('role', None)
    return redirect(url_for('login'))

if __name__ == '__main__':
    # Create the users table if it doesn't exist
    with sqlite3.connect(DATABASE) as conn:
        cur = conn.cursor()
        cur.execute('''
            CREATE TABLE IF NOT EXISTS users (
                id INTEGER PRIMARY KEY,
                username TEXT NOT NULL UNIQUE,
                password TEXT NOT NULL,
                role TEXT NOT NULL  -- Add a role column
            )
        ''')
        conn.commit()

    app.run(debug=True)
  • HTMLテンプレート (templates/admin.html):
<!DOCTYPE html>
<html>
<head>
    <title>Admin Page</title>
</head>
<body>
    <h1>Welcome to the Admin Page!</h1>
</body>
</html>
  • 解説: session['role'] = user['role'] でユーザーのロールをセッションに保存し、アクセス制御を行います。

  • 実践: 上記のPythonコードを app.py という名前で保存し、ターミナルで python app.py を実行してWebアプリケーションを起動します。管理者権限を持つユーザーでログインすることで、管理者ページにアクセスできます。

Explanation:

Implement authorization functionality to restrict access to certain pages based on user roles (e.g., admin). The code stores the user's role in the session and checks it before granting access to protected routes.

16. Webアプリケーションをデプロイする

作成したWebアプリケーションをHerokuなどのクラウドプラットフォームにデプロイします。

  • 解説: Herokuは、Pythonアプリケーションを簡単にデプロイできるPaaS (Platform as a Service) です。まず、Herokuアカウントを作成し、コマンドラインツールをインストールする必要があります。次に、Procfile ファイルを作成し、Webアプリケーションの起動方法を指定します。最後に、Gitを使用してコードをHerokuにプッシュすることで、デプロイが完了します。

  • 実践: Herokuのドキュメントを参照して、詳細な手順を確認してください。

17. ログ記録を行う

Webアプリケーションのエラーやイベントをログファイルに記録する機能を追加します。

  • コード例:
import logging
from flask import Flask

app = Flask(__name__)
logging.basicConfig(level=logging.DEBUG, filename='

<ins class="adsbygoogle"
    style="display:block"
    data-ad-client="ca-pub-1480979447036150"
    data-ad-slot="2902356472"
    data-ad-format="auto"
    data-full-width-responsive="true"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>