Database Configuration
SQLite Database Setup
The CS Library Kiosk uses SQLite3 as its primary database (as implemented in the current system).
While the SRS mentions MySQL/MariaDB for production, the current implementation uses SQLite for simplicity and reliability on Raspberry Pi hardware.
Database Initialization
Create Database Structure
The database is automatically initialized when you run the seeder:cd /opt/cs-library-kiosk
source venv/bin/activate
python3 mock_data.py
This creates cs_library.db with the following tables:
- users - Student and admin accounts
- books - Library catalog
- loans - Checkout/return transactions
Verify Database Creation
# Check database file exists
ls -lh cs_library.db
# Inspect database schema
sqlite3 cs_library.db ".schema"
Database Schema Details
The database.py module implements the following schema:
Users Table
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
student_id TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE COLLATE NOCASE,
password_hash TEXT NOT NULL,
active INTEGER NOT NULL DEFAULT 1,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
Books Table
CREATE TABLE IF NOT EXISTS books (
isbn TEXT PRIMARY KEY,
title TEXT NOT NULL,
author TEXT NOT NULL,
cover TEXT NOT NULL DEFAULT "",
status TEXT NOT NULL DEFAULT "Available",
shelf TEXT NOT NULL DEFAULT ""
);
Loans Table
CREATE TABLE IF NOT EXISTS loans (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL REFERENCES users(id),
isbn TEXT NOT NULL REFERENCES books(isbn),
checked_out DATETIME DEFAULT CURRENT_TIMESTAMP,
due_date DATETIME NOT NULL,
returned INTEGER NOT NULL DEFAULT 0,
returned_date DATETIME
);
Database Configuration in Code
The database path is configured in database.py:13:
DB_PATH = Path(__file__).parent / "cs_library.db"
To use a different location:
# Option 1: Environment variable
import os
DB_PATH = Path(os.getenv('DB_PATH', '/var/lib/cs-library/cs_library.db'))
# Option 2: Absolute path
DB_PATH = Path('/opt/cs-library-kiosk/data/cs_library.db')
Environment Variables
Creating Environment Configuration
Create a .env file for environment-specific settings:
Create .env file
cd /opt/cs-library-kiosk
vim .env
Add Configuration Variables
# Application Settings
APP_HOST=0.0.0.0
APP_PORT=8080
APP_TITLE="CS Library Kiosk"
# Database Configuration
DB_PATH=/opt/cs-library-kiosk/cs_library.db
# Open Library API Settings
USE_LIVE_API=True
API_USER_AGENT="SCSU_CS_Library_Kiosk/1.0 ([email protected])"
API_TIMEOUT=8.0
# Session Settings
SESSION_TIMEOUT=900 # 15 minutes in seconds
# Checkout Settings
LOAN_PERIOD_DAYS=14
MAX_RENEWALS=2
# Logging
LOG_LEVEL=INFO
LOG_FILE=/var/log/cs-library-kiosk/app.log
Secure the .env file
chmod 600 .env
chown pi:pi .env
Never commit .env files to version control. Add .env to .gitignore.
Load Environment Variables
The application already uses python-dotenv (in requirements.txt:33).Add to your main.py:from dotenv import load_dotenv
import os
# Load environment variables
load_dotenv()
# Access variables
HOST = os.getenv('APP_HOST', '0.0.0.0')
PORT = int(os.getenv('APP_PORT', '8080'))
Network Configuration
Static IP Address (Recommended)
For production deployment, configure a static IP address:
Edit dhcpcd configuration
sudo vim /etc/dhcpcd.conf
Add static IP configuration
Add at the end of the file:# Static IP for CS Library Kiosk
interface eth0
static ip_address=192.168.1.100/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1 8.8.8.8
Adjust the IP address, gateway, and DNS servers according to your network configuration.
Restart networking
sudo systemctl restart dhcpcd
# Verify new IP
ip addr show eth0
Firewall Configuration
Install UFW (Uncomplicated Firewall)
Configure firewall rules
# Default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Allow SSH (for remote management)
sudo ufw allow 22/tcp
# Allow kiosk web interface
sudo ufw allow 8080/tcp
# Optional: Allow from specific IP range only
# sudo ufw allow from 192.168.1.0/24 to any port 8080
# Enable firewall
sudo ufw enable
DNS and API Access
Ensure the kiosk can reach the Open Library API:
# Test DNS resolution
nslookup openlibrary.org
# Test HTTPS connectivity
curl -I https://openlibrary.org/api/books?bibkeys=ISBN:9780140328721&format=json&jscmd=data
# Test from Python
python3 -c "import httpx; print(httpx.get('https://openlibrary.org').status_code)"
Backup Procedures
Automated Database Backups
Per SRS Section 4.3, the system requires daily automated database backups to protect against SD card corruption.
Create backup directory
sudo mkdir -p /var/backups/cs-library-kiosk
sudo chown pi:pi /var/backups/cs-library-kiosk
Create backup script
sudo vim /usr/local/bin/backup-cs-library.sh
Add the following:#!/bin/bash
# CS Library Kiosk Backup Script
BACKUP_DIR="/var/backups/cs-library-kiosk"
DB_PATH="/opt/cs-library-kiosk/cs_library.db"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
BACKUP_FILE="$BACKUP_DIR/cs_library_$TIMESTAMP.db"
# Create backup
sqlite3 "$DB_PATH" ".backup '$BACKUP_FILE'"
# Compress backup
gzip "$BACKUP_FILE"
# Keep only last 30 days of backups
find "$BACKUP_DIR" -name "cs_library_*.db.gz" -mtime +30 -delete
# Log backup
echo "$(date): Backup completed - $BACKUP_FILE.gz" >> /var/log/cs-library-backup.log
Make script executable
sudo chmod +x /usr/local/bin/backup-cs-library.sh
Schedule daily backups with cron
Add the following line to run backup daily at 2 AM:0 2 * * * /usr/local/bin/backup-cs-library.sh
Test backup script
sudo /usr/local/bin/backup-cs-library.sh
# Verify backup created
ls -lh /var/backups/cs-library-kiosk/
USB Backup (Recommended)
For additional protection against SD card failure:
Mount USB drive
# Identify USB device
lsblk
# Create mount point
sudo mkdir -p /mnt/usb-backup
# Mount USB drive (adjust device as needed)
sudo mount /dev/sda1 /mnt/usb-backup
Configure automatic mounting
# Get UUID of USB drive
sudo blkid /dev/sda1
# Edit fstab
sudo vim /etc/fstab
Add line (replace UUID):UUID=XXXX-XXXX /mnt/usb-backup vfat defaults,nofail 0 0
Create USB backup script
sudo vim /usr/local/bin/backup-to-usb.sh
#!/bin/bash
# Sync database backups to USB
rsync -av --delete \
/var/backups/cs-library-kiosk/ \
/mnt/usb-backup/cs-library-backups/
# Also backup the entire application
rsync -av --exclude='venv' --exclude='__pycache__' \
/opt/cs-library-kiosk/ \
/mnt/usb-backup/cs-library-app/
sudo chmod +x /usr/local/bin/backup-to-usb.sh
Schedule USB sync
Add to crontab (runs at 3 AM):0 3 * * * /usr/local/bin/backup-to-usb.sh
Backup Restoration
To restore from a backup:
# Stop the service
sudo systemctl stop cs-library-kiosk.service
# Backup current database (just in case)
cp /opt/cs-library-kiosk/cs_library.db /tmp/cs_library_current.db
# Find backup to restore
ls -lh /var/backups/cs-library-kiosk/
# Decompress and restore
gunzip -c /var/backups/cs-library-kiosk/cs_library_20260304_020000.db.gz > /opt/cs-library-kiosk/cs_library.db
# Set proper permissions
chown pi:pi /opt/cs-library-kiosk/cs_library.db
chmod 600 /opt/cs-library-kiosk/cs_library.db
# Restart service
sudo systemctl start cs-library-kiosk.service
Application Configuration
Configuring API Integration
The Open Library API integration is configured in database.py:16:
# Enable/disable live API lookups
USE_LIVE_API = True
To disable API lookups (offline mode):
Or set via environment variable:
# In .env file
USE_LIVE_API=False
Adjusting Loan Period
Default loan period is 14 days (database.py:261, 309):
due = datetime.now() + timedelta(days=14)
To change globally, add to environment configuration:
# In .env
LOAN_PERIOD_DAYS=21
Then modify database.py:
import os
LOAN_DAYS = int(os.getenv('LOAN_PERIOD_DAYS', '14'))
due = datetime.now() + timedelta(days=LOAN_DAYS)
SQLite Optimization
Add to database connection in database.py:21-24:
def _connect() -> sqlite3.Connection:
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
conn.execute("PRAGMA foreign_keys = ON")
# Performance optimizations
conn.execute("PRAGMA journal_mode = WAL") # Write-Ahead Logging
conn.execute("PRAGMA synchronous = NORMAL") # Faster writes
conn.execute("PRAGMA cache_size = 10000") # Increase cache
return conn
Adjust NiceGUI settings in main.py:450:
ui.run(
host='0.0.0.0',
port=8080,
title="CS Library Kiosk",
favicon='favicon1.ico',
dark=True,
reload=False, # Disable auto-reload in production
show=False # Don't auto-open browser
)
Logging Configuration
Application Logging
Create a logging configuration:
import logging
from logging.handlers import RotatingFileHandler
import os
# Configure logging
log_level = os.getenv('LOG_LEVEL', 'INFO')
log_file = os.getenv('LOG_FILE', '/var/log/cs-library-kiosk/app.log')
# Create log directory if needed
os.makedirs(os.path.dirname(log_file), exist_ok=True)
# Configure logger
logging.basicConfig(
level=getattr(logging, log_level),
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
RotatingFileHandler(log_file, maxBytes=10485760, backupCount=5),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
Log Rotation
Configure logrotate:
sudo vim /etc/logrotate.d/cs-library-kiosk
/var/log/cs-library-kiosk/*.log {
daily
rotate 14
compress
delaycompress
notifempty
create 0640 pi pi
sharedscripts
postrotate
systemctl reload cs-library-kiosk.service > /dev/null 2>&1 || true
endscript
}
Monitoring and Alerts
System Health Monitoring
Create a health check script:
sudo vim /usr/local/bin/health-check.sh
#!/bin/bash
# Check if service is running
if ! systemctl is-active --quiet cs-library-kiosk.service; then
echo "ALERT: CS Library Kiosk service is not running" | \
logger -t cs-library-health
# Attempt restart
systemctl restart cs-library-kiosk.service
fi
# Check database accessibility
if ! sqlite3 /opt/cs-library-kiosk/cs_library.db "SELECT 1" > /dev/null 2>&1; then
echo "ALERT: Database is not accessible" | \
logger -t cs-library-health
fi
# Check disk space
USAGE=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ $USAGE -gt 90 ]; then
echo "ALERT: Disk usage is at ${USAGE}%" | \
logger -t cs-library-health
fi
# Check temperature
TEMP=$(vcgencmd measure_temp | sed 's/temp=//' | sed 's/.C//')
if (( $(echo "$TEMP > 80" | bc -l) )); then
echo "ALERT: CPU temperature is ${TEMP}°C" | \
logger -t cs-library-health
fi
sudo chmod +x /usr/local/bin/health-check.sh
# Run every 5 minutes
*/5 * * * * /usr/local/bin/health-check.sh
Security Configuration
Database Security
# Set restrictive permissions on database
chmod 600 /opt/cs-library-kiosk/cs_library.db
chown pi:pi /opt/cs-library-kiosk/cs_library.db
# Prevent accidental deletion
sudo chattr +i /opt/cs-library-kiosk/cs_library.db
# (Use 'sudo chattr -i' to unlock when needed)
Password Security
The system uses bcrypt for password hashing (requirements.txt:50, database.py:80):
- Passwords are hashed with bcrypt salt rounds
- Never stored in plain text
- Verified using secure comparison
Ensure all user inputs are validated:
- ISBN format validation (10 or 13 digits)
- Student ID format validation
- SQL injection prevention (parameterized queries used throughout)
- XSS prevention (NiceGUI handles escaping)
Production Checklist
Database
Database initialized with schema
Test accounts created or removed
Database file permissions set (600)
Backup scripts configured and tested
Network
Static IP configured (if required)
Open Library API accessible
Application
Systemd service enabled and running
Environment variables configured
Logging configured and rotating
Auto-start on boot tested
Security
Default passwords changed
SSH key-based auth enabled
Unnecessary services disabled
File permissions restricted
Monitoring
Health check script running
Backup verification successful
Temperature monitoring active
Troubleshooting
Database Locked Errors
# Check for lingering processes
lsof /opt/cs-library-kiosk/cs_library.db
# If using WAL mode, check for wal files
ls -la /opt/cs-library-kiosk/cs_library.db*
# Clear WAL checkpoint
sqlite3 /opt/cs-library-kiosk/cs_library.db "PRAGMA wal_checkpoint(FULL);"
Service Fails to Start
# Check logs
sudo journalctl -u cs-library-kiosk.service -n 50
# Verify file paths in service file
sudo systemctl cat cs-library-kiosk.service
# Test manually
cd /opt/cs-library-kiosk
source venv/bin/activate
python3 main.py
API Timeouts
# Test API connectivity
curl -m 10 https://openlibrary.org/api/books?bibkeys=ISBN:9780140328721&format=json
# Adjust timeout in database.py:146
async with httpx.AsyncClient(timeout=15.0) as client:
Next Steps
With your system fully configured:
- Test all workflows (checkout, return, search, renewals)
- Load production data and remove test accounts
- Perform user acceptance testing
- Document any custom configurations
- Train staff on system operation and maintenance