from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate from flask_login import LoginManager import pymysql import os from config import Config db = SQLAlchemy() migrate = Migrate() login_manager = LoginManager() def create_app(): app = Flask(__name__) app.config.from_object(Config) # Initialize enhanced logging setup_enhanced_logging(app) # Initialize extensions db.init_app(app) migrate.init_app(app, db) login_manager.init_app(app) login_manager.login_view = 'auth.login' login_manager.login_message = 'Please log in to access this page.' # MySQL connection (read-only) - initialized when needed def get_mysql_connection(): if not hasattr(app, 'mysql_connection') or app.mysql_connection is None: try: app.mysql_connection = pymysql.connect( host=app.config['MYSQL_CONFIG']['host'], database=app.config['MYSQL_CONFIG']['database'], user=app.config['MYSQL_CONFIG']['user'], password=app.config['MYSQL_CONFIG']['password'], port=app.config['MYSQL_CONFIG']['port'], autocommit=False # Ensure read-only behavior ) except Exception as e: print(f"MySQL connection failed: {e}") app.mysql_connection = None return app.mysql_connection # Make connection function available to app context app.get_mysql_connection = get_mysql_connection # Register blueprints from blueprints.auth import auth_bp from blueprints.main import main_bp from blueprints.search import search_bp from blueprints.analytics import analytics_bp app.register_blueprint(auth_bp, url_prefix='/auth') app.register_blueprint(main_bp) app.register_blueprint(search_bp) app.register_blueprint(analytics_bp) # User loader for Flask-Login from models import Users @login_manager.user_loader def load_user(user_id): return Users.query.get(int(user_id)) # Add permission functions to template context from permissions import ( can_manage_users, can_manage_payments, can_view_data, can_process_single_payments, can_manage_batch_payments, can_manage_payment_plans, can_view_logs, can_export_data, has_permission, get_user_permission_level ) @app.context_processor def inject_permissions(): return { 'can_manage_users': can_manage_users, 'can_manage_payments': can_manage_payments, 'can_view_data': can_view_data, 'can_process_single_payments': can_process_single_payments, 'can_manage_batch_payments': can_manage_batch_payments, 'can_manage_payment_plans': can_manage_payment_plans, 'can_view_logs': can_view_logs, 'can_export_data': can_export_data, 'has_permission': has_permission, 'get_user_permission_level': get_user_permission_level } # Note: Database tables will be managed by Flask-Migrate # Use 'flask db init', 'flask db migrate', 'flask db upgrade' commands return app def setup_enhanced_logging(app): """Setup enhanced logging system for the application.""" try: # Create logs directory first os.makedirs('logs', exist_ok=True) from logging_config import setup_flask_logging from middleware import RequestLoggingMiddleware, DatabaseLoggingMiddleware, SecurityMiddleware # Setup Flask logging setup_flask_logging(app) # Initialize middleware with error handling try: RequestLoggingMiddleware(app) app.logger.info("Request logging middleware initialized") except Exception as e: app.logger.warning(f"Request logging middleware failed: {e}") try: DatabaseLoggingMiddleware(app) app.logger.info("Database logging middleware initialized") except Exception as e: app.logger.warning(f"Database logging middleware failed: {e}") try: SecurityMiddleware(app) app.logger.info("Security middleware initialized") except Exception as e: app.logger.warning(f"Security middleware failed: {e}") except ImportError as e: print(f"Enhanced logging not available: {e}") except Exception as e: print(f"Error setting up enhanced logging: {e}") # Don't let logging errors prevent the app from starting pass if __name__ == '__main__': app = create_app() app.run(debug=True)