nicegui==3.7.1 # Web UI frameworkfastapi==0.129.0 # Backend frameworkhttpx==0.28.1 # HTTP client for API callsbcrypt==5.0.0 # Password hashinguvicorn==0.40.0 # ASGI serverpython-multipart==0.0.22 # Form data parsingaiosqlite==0.22.1 # Async SQLite support
The complete dependency list includes 50 packages supporting:
NiceGUI web framework with Tailwind CSS
FastAPI for async backend operations
httpx for Open Library API integration
bcrypt for secure password hashing
Socket.IO for real-time features
5
Initialize the Database
The database is automatically created when you first run the application:
# Run main.py - this creates cs_library.dbpython3 main.py
Press Ctrl+C to stop after the database is created.
def init_db() -> None: with _connect() as conn: conn.executescript(''' 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 ); 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 "" ); 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 ); ''') conn.commit()
This creates:
users - Student and admin accounts
books - Library catalog with ISBN as primary key
loans - Checkout/return transaction history
6
Seed Initial Data
Populate the database with the library catalog and test accounts:
The system queries Open Library for book metadata:
database.py
async def _fetch_from_open_library(isbn: str) -> Optional[dict]: """Fetch book metadata from Open Library and cache it locally.""" url = ( f"https://openlibrary.org/api/books" f"?bibkeys=ISBN:{isbn}&format=json&jscmd=data" ) headers = {"User-Agent": "SCSU_CS_Library_Kiosk/1.0 ([email protected])"} try: async with httpx.AsyncClient(timeout=8.0) as client: response = await client.get(url, headers=headers) if response.status_code != 200: return None data = response.json() # ... parse and cache book data ... except httpx.TimeoutException: print(f" [API] Timeout looking up ISBN {isbn}.") return None
Ensure the Raspberry Pi has internet access for API lookups. Books are cached locally after first lookup.
9
Run the Kiosk Application
Start the kiosk in production mode:
# Ensure virtual environment is activatedsource venv/bin/activate# Launch the kioskpython3 main.py
ui.run( host='0.0.0.0', # Listen on all interfaces port=8080, # Default port title="CS Library Kiosk", favicon='favicon1.ico', dark=True # Dark theme enabled)
Access the kiosk from any device on the network:
Local: http://localhost:8080
Network: http://192.168.1.100:8080 (use your Raspberry Pi’s IP)
10
Set Up Autostart (Production)
Configure the kiosk to start automatically on boot:
async def checkout_books(books: list, user_id: int) -> None: """Mark each book as 'Checked Out' and create a loan record. Due in 14 days.""" due = datetime.now() + timedelta(days=14) # 14-day loan period def _checkout(): with _connect() as conn: for book in books: conn.execute( "UPDATE books SET status = 'Checked Out' WHERE isbn = ?", (book["isbn"],) ) conn.execute( "INSERT INTO loans (user_id, isbn, due_date) VALUES (?, ?, ?)", (user_id, book["isbn"], due) ) conn.commit() await _run(_checkout)
async def register_user(name: str, email: str, student_id: str, password: str) -> Optional[dict]: """Hash the password and insert a new user. Returns user dict or None if email/student_id taken.""" pw_hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode() # ... insert user with hashed password ...
#!/bin/bashBACKUP_DIR="/home/pi/backups"mkdir -p $BACKUP_DIRcp /home/pi/cs-library-kiosk/cs_library.db $BACKUP_DIR/cs_library_$(date +%Y%m%d_%H%M%S).db# Keep only last 30 days of backupsfind $BACKUP_DIR -name "cs_library_*.db" -mtime +30 -delete
Make executable and add to cron:
chmod +x ~/backup-library.sh# Add to crontab (daily at 2 AM)crontab -e