入退室管理システムを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リクエストで実現できます。


