108 lines
3.2 KiB
Python
108 lines
3.2 KiB
Python
"""
|
|
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'
|
|
})
|