import logging from flask import Flask, jsonify from . import config from .extensions import mongo, bcrypt, jwt, cors, session from .ai_features import ai_bp from .page_features import page_bp def create_app(): app = Flask(__name__) app.config.from_object(config) logging.basicConfig(level=logging.INFO) # Initialize extensions with the app instance mongo.init_app(app) bcrypt.init_app(app) jwt.init_app(app) cors.init_app(app, supports_credentials=True) session.init_app(app) # --- ZOHO SDK INITIALIZATION --- # We attempt initialization at startup. If the token file exists, the SDK # will be ready. If not, the login flow will trigger initialization later. with app.app_context(): from .xero_client import initialize_zoho_sdk initialize_zoho_sdk() # --- END ZOHO SDK INITIALIZATION --- # Register JWT error handlers @jwt.unauthorized_loader def unauthorized_callback(reason): return jsonify(message="Missing Authorization Header"), 401 @jwt.invalid_token_loader def invalid_token_callback(error): return jsonify(message="Signature verification failed. Token is invalid."), 401 @jwt.expired_token_loader def expired_token_callback(jwt_header, jwt_payload): return jsonify(message="Token has expired"), 401 # Register blueprints to organize routes from .api import api_bp from .xero_routes import zoho_bp app.register_blueprint(page_bp, url_prefix='/api/pages') app.register_blueprint(api_bp, url_prefix='/api') app.register_blueprint(ai_bp, url_prefix='/api') app.register_blueprint(zoho_bp) return app