import logging import logging.handlers import os from flask import Flask, redirect, url_for from app.config import Config from app.services.db_service import db def create_app(): app = Flask(__name__) app.config.from_object(Config) # Initialize extensions db.init_app(app) # Configure logging setup_logging(app) # Register blueprints register_blueprints(app) # Register error handlers register_error_handlers(app) # ROOT → LOGIN @app.route("/") def index(): return redirect(url_for("auth.login")) return app def setup_logging(app): """Configure comprehensive logging for debugging""" # Ensure logs directory exists logs_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'logs') os.makedirs(logs_dir, exist_ok=True) # Create logger logger = logging.getLogger() logger.setLevel(logging.DEBUG) # Remove existing handlers logger.handlers.clear() # Create formatters detailed_formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s', datefmt='%Y-%m-%d %H:%M:%S' ) # File handler for all logs file_handler = logging.handlers.RotatingFileHandler( os.path.join(logs_dir, 'app.log'), maxBytes=10485760, # 10MB backupCount=5 ) file_handler.setLevel(logging.DEBUG) file_handler.setFormatter(detailed_formatter) logger.addHandler(file_handler) # File handler for RA bill fetching only ra_bill_handler = logging.handlers.RotatingFileHandler( os.path.join(logs_dir, 'ra_bill_fetch.log'), maxBytes=5242880, # 5MB backupCount=5 ) ra_bill_handler.setLevel(logging.DEBUG) ra_bill_handler.setFormatter(detailed_formatter) # Only attach to relevant loggers ra_loggers = ['app.routes.dashboard', 'app.routes.file_report'] for logger_name in ra_loggers: logging.getLogger(logger_name).addHandler(ra_bill_handler) # Console handler for important messages console_handler = logging.StreamHandler() console_handler.setLevel(logging.INFO) console_formatter = logging.Formatter( '%(levelname)s - %(name)s - %(message)s' ) console_handler.setFormatter(console_formatter) logger.addHandler(console_handler) # Suppress verbose libraries logging.getLogger('werkzeug').setLevel(logging.WARNING) logging.getLogger('sqlalchemy.engine').setLevel(logging.WARNING) app.logger.info("Logging initialized successfully") app.logger.info(f"Log files location: {logs_dir}") def register_blueprints(app): from app.routes.auth import auth_bp from app.routes.user import user_bp from app.routes.dashboard import dashboard_bp from app.routes.subcontractor_routes import subcontractor_bp from app.routes.file_import import file_import_bp from app.routes.file_report import file_report_bp from app.routes.generate_comparison_report import generate_report_bp from app.routes.file_format import file_format_bp app.register_blueprint(auth_bp) app.register_blueprint(user_bp) app.register_blueprint(dashboard_bp) app.register_blueprint(subcontractor_bp) app.register_blueprint(file_import_bp) app.register_blueprint(file_report_bp) app.register_blueprint(generate_report_bp) app.register_blueprint(file_format_bp ) def register_error_handlers(app): @app.errorhandler(404) def page_not_found(e): return "Page Not Found", 404 @app.errorhandler(500) def internal_error(e): return "Internal Server Error", 500