Files
bookapp/web/app.py
Mike Wichers fd4ce634d4 Fix startup crash by removing unused MiniHuey import
Removed `from huey.contrib.mini import MiniHuey` which caused
`ModuleNotFoundError: No module named 'gevent'` on startup. MiniHuey
was never used; the app correctly uses SqliteHuey via `web.tasks`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 23:51:38 -05:00

106 lines
3.6 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
from datetime import datetime
from sqlalchemy import text
from flask import Flask
from flask_login import LoginManager
from werkzeug.security import generate_password_hash
from web.db import db, User, Run
from web.tasks import huey
from core import config
# Calculate paths relative to this file (web/app.py -> project root is two levels up)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATE_DIR = os.path.join(BASE_DIR, 'templates')
app = Flask(__name__, template_folder=TEMPLATE_DIR)
app.url_map.strict_slashes = False
app.config['SECRET_KEY'] = config.FLASK_SECRET
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{os.path.join(config.DATA_DIR, "bookapp.db")}'
db.init_app(app)
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
@login_manager.user_loader
def load_user(user_id):
return db.session.get(User, int(user_id))
@app.context_processor
def inject_globals():
return dict(app_version=config.VERSION)
# Register Blueprints
from web.routes.auth import auth_bp
from web.routes.project import project_bp
from web.routes.run import run_bp
from web.routes.persona import persona_bp
from web.routes.admin import admin_bp
app.register_blueprint(auth_bp)
app.register_blueprint(project_bp)
app.register_blueprint(run_bp)
app.register_blueprint(persona_bp)
app.register_blueprint(admin_bp)
# --- SETUP ---
with app.app_context():
db.create_all()
# Auto-create Admin from Environment Variables (Docker/Portainer Setup)
if config.ADMIN_USER and config.ADMIN_PASSWORD:
admin = User.query.filter_by(username=config.ADMIN_USER).first()
if not admin:
print(f"🔐 System: Creating Admin User '{config.ADMIN_USER}' from environment variables.")
admin = User(username=config.ADMIN_USER, password=generate_password_hash(config.ADMIN_PASSWORD, method='pbkdf2:sha256'), is_admin=True)
db.session.add(admin)
db.session.commit()
else:
print(f"🔐 System: Syncing Admin User '{config.ADMIN_USER}' settings from environment.")
if not admin.is_admin: admin.is_admin = True
admin.password = generate_password_hash(config.ADMIN_PASSWORD, method='pbkdf2:sha256')
db.session.add(admin)
db.session.commit()
elif not User.query.filter_by(is_admin=True).first():
print(" System: No Admin credentials found in environment variables. Admin account not created.")
# Migration: Add 'progress' column if missing
try:
with db.engine.connect() as conn:
conn.execute(text("ALTER TABLE run ADD COLUMN progress INTEGER DEFAULT 0"))
conn.commit()
print("✅ System: Added 'progress' column to Run table.")
except: pass
# Reset stuck runs on startup
try:
stuck_runs = Run.query.filter_by(status='running').all()
if stuck_runs:
print(f"⚠️ System: Found {len(stuck_runs)} stuck runs. Resetting to 'failed'.")
for r in stuck_runs:
r.status = 'failed'
r.end_time = datetime.utcnow()
db.session.commit()
except Exception as e:
print(f"⚠️ System: Failed to clean up stuck runs: {e}")
if __name__ == "__main__":
import threading
# Start Huey consumer in background thread
def run_huey():
from huey.consumer import Consumer
consumer = Consumer(huey, workers=1, worker_type='thread', loglevel=20)
consumer.run()
t = threading.Thread(target=run_huey, daemon=True)
t.start()
app.run(host='0.0.0.0', port=5000, debug=False)