入退室管理システムをPythonで自作する方法!サーバー要件とコード例

入退室

学習塾や習いごとなどのスクールで、Pythonを使って入退室管理システムを自作したいと考えている方向けに、技術要件からコード例・サーバー構築まで解説します。

Pythonで入退室管理システムを自作するには、Webフレームワーク・データベース・LINE Messaging API・サーバー環境の4つを組み合わせる必要があります。

コーディングだけでなくインフラ構築まで含めた全体像を把握しておくことが、スムーズに完成させるためのポイントです。

この記事では、Pythonで入退室管理システムを自作する場合の技術要件・具体的なコード例・ConoHa VPSでのFlaskとDBのセットアップ方法まで詳しく解説します。

Pythonで入退室管理システムを自作する場合の技術要件

Pythonで入退室管理システムを構築するには、複数の技術要素を組み合わせる必要があります。

Python + Webフレームワーク

まず、PythonのWebフレームワークが必要です。

代表的なものはFlaskとDjangoで、Flaskは軽量でシンプル、Djangoは多機能で大規模開発向けという特徴があります。

入退室管理システムであればFlaskで十分ですが、将来的な拡張性を考えるならDjangoも選択肢になります。

Flaskを使う場合、以下のようなライブラリが必要になります。

Flask==2.3.0
Flask-SQLAlchemy==3.0.0
requests==2.31.0
qrcode==7.4.2
Pillow==10.0.0
python-dotenv==1.0.0
gunicorn==21.0.0

サーバー環境

Pythonで自作したアプリケーションを24時間365日稼働させるには、VPS(仮想専用サーバー)またはPaaS(Platform as a Service)が必要です。

共用のレンタルサーバーでは、Pythonアプリケーションを常時起動させることができないため、VPSが必須です。

VPSの場合:

  • さくらのVPS・ConoHa VPS・AWS EC2など
  • OSはUbuntu 22.04 LTSが安定しておすすめ
  • Nginxをリバースプロキシとして設定
  • Gunicornでアプリケーションを起動
  • SSL証明書(Let’s Encrypt)の設定

PaaSの場合:

  • Heroku・Railway・Renderなど
  • デプロイが簡単だがカスタマイズ性は低い
  • 無料プランは制限が厳しく実用には有料プランが必要

データベース

入退室履歴や生徒情報を保存するデータベースが必要です。

開発環境ではSQLiteでも問題ありませんが、本番環境では複数ユーザーの同時アクセスに耐えられるPostgreSQLやMySQLを推奨します。

Flask-SQLAlchemyを使えば、PythonのコードからSQLを直接書かずにデータベースを操作できます。

LINE Messaging API

LINE通知を送るには、LINE Messaging APIの設定が必要です。

LINE Developersでチャネルを作成し、Channel Access TokenとChannel Secretを取得します。

WebhookエンドポイントをPythonアプリに実装し、LINEからのリクエストを受け取る仕組みを作ります。

Pythonで入退室管理システムを構築するには、Webフレームワーク・サーバー環境・データベース・LINE APIなど、多岐にわたる技術要素が必要です。

次は、具体的なコード実装を確認します。

Pythonでの実装例とコードサンプル

Pythonでの実装例を、コードサンプルと共に紹介します。

ディレクトリ構成

Flaskで構築する場合の基本的なディレクトリ構成は以下のようになります。

nyutaishitsu/
├── app.py                 # メインアプリケーション
├── config.py              # 設定ファイル
├── models.py              # データベースモデル
├── requirements.txt       # 依存ライブラリ
├── .env                   # 環境変数(APIキーなど)
├── static/
│   ├── css/
│   ├── js/
│   └── qr_codes/         # 生成したQRコード画像
├── templates/
│   ├── index.html
│   ├── admin.html
│   └── scan.html
└── migrations/           # DBマイグレーション

データベースモデル

Flask-SQLAlchemyを使ったデータベースモデルの定義です。

from flask_sqlalchemy import SQLAlchemy
from datetime import datetime

db = SQLAlchemy()

class Student(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    parent_line_id = db.Column(db.String(100), nullable=False)
    qr_code_path = db.Column(db.String(200))
    created_at = db.Column(db.DateTime, default=datetime.now)
    attendance_records = db.relationship('AttendanceRecord', backref='student', lazy=True)

class AttendanceRecord(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    student_id = db.Column(db.Integer, db.ForeignKey('student.id'), nullable=False)
    timestamp = db.Column(db.DateTime, nullable=False)
    status = db.Column(db.String(20))  # 'enter' or 'exit'

QRコード生成

生徒ごとにユニークなQRコードを生成するコードです。

import qrcode
import os

def generate_qr_code(student_id):
    data = f"STUDENT_ID:{student_id}"
    
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_L,
        box_size=10,
        border=4,
    )
    qr.add_data(data)
    qr.make(fit=True)
    
    img = qr.make_image(fill_color="black", back_color="white")
    os.makedirs('static/qr_codes', exist_ok=True)
    filename = f"static/qr_codes/{student_id}.png"
    img.save(filename)
    
    return filename

QRコード読み取りとLINE通知の送信

QRコードを読み取った際に入退室を記録し、保護者にLINE通知を送る処理です。

from flask import Flask, request, jsonify
from datetime import datetime
import requests
import os

app = Flask(__name__)
LINE_CHANNEL_ACCESS_TOKEN = os.getenv('LINE_CHANNEL_ACCESS_TOKEN')

@app.route('/scan', methods=['POST'])
def scan():
    data = request.get_json()
    student_id = data.get('student_id')
    status = data.get('status', 'enter')
    
    student = Student.query.get(student_id)
    if not student:
        return jsonify({'error': 'Student not found'}), 404
    
    # 入退室記録をDBに保存
    record = AttendanceRecord(
        student_id=student_id,
        timestamp=datetime.now(),
        status=status
    )
    db.session.add(record)
    db.session.commit()
    
    # 保護者にLINE通知を送信
    send_line_notification(student.parent_line_id, student.name, status)
    
    return jsonify({'success': True}), 200

def send_line_notification(line_user_id, student_name, status):
    url = 'https://api.line.me/v2/bot/message/push'
    headers = {
        'Content-Type': 'application/json',
        'Authorization': f'Bearer {LINE_CHANNEL_ACCESS_TOKEN}'
    }
    action = '入室' if status == 'enter' else '退室'
    timestamp = datetime.now().strftime('%Y年%m月%d日 %H:%M')
    
    payload = {
        'to': line_user_id,
        'messages': [{
            'type': 'text',
            'text': f'{student_name}さんが{action}しました。\n時刻: {timestamp}'
        }]
    }
    response = requests.post(url, headers=headers, json=payload)
    return response.status_code == 200

config.pyの設定

import os
from dotenv import load_dotenv

load_dotenv()

class Config:
    SECRET_KEY = os.getenv('SECRET_KEY', 'your-secret-key')
    SQLALCHEMY_DATABASE_URI = os.getenv('DATABASE_URL', 'sqlite:///nyutaishitsu.db')
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    LINE_CHANNEL_ACCESS_TOKEN = os.getenv('LINE_CHANNEL_ACCESS_TOKEN')
    LINE_CHANNEL_SECRET = os.getenv('LINE_CHANNEL_SECRET')

Pythonのコード実装は、QRコード生成・データベース操作・LINE通知送信の3つを組み合わせることで完成します。

次は、ConoHa VPSでのサーバーセットアップ手順を確認します。

ConoHa VPSでFlaskとDBをセットアップする方法

ConoHa VPSにPythonのFlaskアプリケーションとデータベースをセットアップする手順を解説します。

ConoHa VPSの初期設定

ConoHa VPSでUbuntu 22.04を選択してサーバーを作成したら、SSHで接続します。

ssh root@[サーバーのIPアドレス]

まず、パッケージを最新化します。

apt update && apt upgrade -y

次に、一般ユーザーを作成してsudo権限を付与します。

adduser nyutai
usermod -aG sudo nyutai

Pythonと必要なパッケージのインストール

Ubuntu 22.04にはPython3が標準でインストールされていますが、pip・venv・必要なライブラリを追加します。

apt install python3-pip python3-venv -y

アプリケーションのディレクトリを作成し、仮想環境を構築します。

mkdir /var/www/nyutaishitsu
cd /var/www/nyutaishitsu
python3 -m venv venv
source venv/bin/activate
pip install flask flask-sqlalchemy requests qrcode pillow python-dotenv gunicorn

PostgreSQLのインストールとセットアップ

apt install postgresql postgresql-contrib -y
systemctl start postgresql
systemctl enable postgresql

データベースとユーザーを作成します。

sudo -u postgres psql
CREATE DATABASE nyutaishitsu;
CREATE USER nyutai_user WITH PASSWORD 'your_password';
GRANT ALL PRIVILEGES ON DATABASE nyutaishitsu TO nyutai_user;
\q

.envファイルにデータベースのURLを設定します。

DATABASE_URL=postgresql://nyutai_user:your_password@localhost/nyutaishitsu
LINE_CHANNEL_ACCESS_TOKEN=your_token
LINE_CHANNEL_SECRET=your_secret
SECRET_KEY=your_secret_key

Gunicornでアプリケーションを起動

Gunicornを使ってFlaskアプリケーションを起動します。

gunicorn --workers 3 --bind 0.0.0.0:8000 app:app

systemdに登録して自動起動させます。

nano /etc/systemd/system/nyutaishitsu.service
[Unit]
Description=Nyutaishitsu Flask App
After=network.target

[Service]
User=nyutai
WorkingDirectory=/var/www/nyutaishitsu
Environment="PATH=/var/www/nyutaishitsu/venv/bin"
ExecStart=/var/www/nyutaishitsu/venv/bin/gunicorn --workers 3 --bind 0.0.0.0:8000 app:app

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl start nyutaishitsu
systemctl enable nyutaishitsu

NginxのリバースプロキシとSSL設定

apt install nginx certbot python3-certbot-nginx -y

Nginxの設定ファイルを作成します。

nano /etc/nginx/sites-available/nyutaishitsu
server {
    listen 80;
    server_name yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /static/ {
        alias /var/www/nyutaishitsu/static/;
    }
}
ln -s /etc/nginx/sites-available/nyutaishitsu /etc/nginx/sites-enabled/
nginx -t
systemctl restart nginx

SSL証明書を取得します。

certbot --nginx -d yourdomain.com

ConoHa VPSでFlaskとPostgreSQLをセットアップする手順は、パッケージインストール・DB作成・Gunicorn設定・Nginx設定・SSL取得の順で進めます。

次は、ICカード連携の実装方法を確認します。

ICカード連携をPythonで実装する方法

QRコードではなくICカードで入退室管理をPythonで実装する場合、追加の構成が必要になります。

ICカードリーダーの制御

ICカードリーダー(Felica・MIFARE対応など)はUSB接続のデバイスで、PCやラズベリーパイに接続してPythonのnfcpyライブラリで制御します。

pip install nfcpy
import nfc
import requests

WEBHOOK_URL = 'https://yourdomain.com/scan'

def on_connect(tag):
    idm = tag.idm.hex()
    print(f"カードID: {idm}")
    
    # WebサーバーのAPIにカードIDを送信
    requests.post(WEBHOOK_URL, json={
        'card_id': idm,
        'status': 'enter'
    })
    return True

clf = nfc.ContactlessFrontend('usb')
while True:
    clf.connect(rdwr={'on-connect': on_connect})

Webブラウザから直接ICカードを読み取れない点への対応

WebブラウザからはICカードリーダーを直接制御できないため、ローカルで動くPythonスクリプトがカードを読み取り、WebサーバーのAPIに送信する構成が必要です。

各教室のPC・またはラズベリーパイにこのスクリプトを常駐させ、読み取りデータをHTTPリクエストでFlaskアプリに送信する仕組みになります。

ラズベリーパイを使う場合、systemdに登録して起動時に自動でスクリプトを実行させます。

nano /etc/systemd/system/card-reader.service
[Unit]
Description=IC Card Reader
After=network.target

[Service]
ExecStart=/usr/bin/python3 /home/pi/card_reader.py
Restart=always

[Install]
WantedBy=multi-user.target

交通系ICカードの対応

SuicaやPASMOなどの交通系ICカードはFeliCa規格です。

nfcpyはFeliCaに対応しているため、交通系ICカードのIDmを読み取ることができます。

ただしカード番号(IDm)は機器によって異なるため、最初に生徒のカードIDmを登録するステップが必要になります。

ICカード連携はQRコードと異なりローカルのPythonスクリプトが必要ですが、Webサーバーとの連携はHTTPリクエストで実現できます。

株式会社エクレ

2012年より学習塾を経営し、10年以上にわたり学習塾の経営・運営に携わる。他塾のコンサルティング・新規立ち上げ支援も手がけてきた。塾経営の現場で感じたコスト・利便性の課題を起点に、学習塾・スクール向け入退室管理システム「LINE入退クラウド」(2025年)「WebPush入退クラウド」(2026年)を開発・運営。Webサイト制作・SEO・デジタルマーケティング支援も行っている。