""" Personal Finance API - Application Factory This module implements the Flask application factory pattern following Flask 3.0 best practices. """ import os from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate from flask_cors import CORS from app.extensions import db, migrate from app.config import get_config def create_app(config_name=None): """ Application factory function that creates and configures a Flask application instance. Args: config_name (str): Configuration name ('development', 'testing', 'production') If None, uses FLASK_ENV environment variable or defaults to 'development' Returns: Flask: Configured Flask application instance """ app = Flask(__name__) # Load configuration if config_name is None: config_name = os.getenv('FLASK_ENV', 'development') config = get_config(config_name) app.config.from_object(config) # Initialize CORS for frontend integration CORS(app, origins=['*']) # Allow all origins for development # Initialize extensions db.init_app(app) migrate.init_app(app, db) # Import models so they are registered with SQLAlchemy from app.models import Category, Transaction # Register blueprints register_blueprints(app) # Register error handlers register_error_handlers(app) return app def register_blueprints(app): """Register Flask blueprints with the application.""" from app.api.categories import categories_bp from app.api.transactions import transactions_bp from app.api.analytics import analytics_bp # Register API blueprints with proper URL prefixes app.register_blueprint(categories_bp, url_prefix='/api/v1/categories') app.register_blueprint(transactions_bp, url_prefix='/api/v1/transactions') app.register_blueprint(analytics_bp, url_prefix='/api/v1/analytics') def register_error_handlers(app): """Register custom error handlers for the application.""" from flask import jsonify from marshmallow import ValidationError @app.errorhandler(ValidationError) def handle_validation_error(e): """Handle Marshmallow validation errors.""" return jsonify({ 'success': False, 'error': 'validation_failed', 'message': 'Input validation failed', 'details': e.messages }), 400 @app.errorhandler(404) def handle_not_found(e): """Handle 404 errors.""" return jsonify({ 'success': False, 'error': 'not_found', 'message': 'Resource not found' }), 404 @app.errorhandler(500) def handle_internal_error(e): """Handle 500 errors.""" return jsonify({ 'success': False, 'error': 'internal_server_error', 'message': 'An internal server error occurred' }), 500 @app.route('/health') def health_check(): """Health check endpoint for monitoring.""" return jsonify({ 'success': True, 'status': 'healthy', 'message': 'Personal Finance API is running' })