# backend/myapp/__init__.py import sys import os from flask import Flask, jsonify # --- 1. Import Extensions --- # Import specific extension instances defined in extensions.py # Avoid 'import *' try: from .extensions import mongo, cors # Add other extensions like jwt, ma if used except ImportError as e: print(f"Error importing extensions: {e}. Make sure extensions.py exists and defines instances.") # Provide dummy instances or raise an error if extensions are critical mongo = None cors = None # --- 2. Import Default Config --- # Assumes config.py is in the parent 'backend' directory. Adjust if moved. try: # This relative import works if 'backend' is treated as a package or is in sys.path from .config import Config, config as config_options # Assuming config.py has a 'config' dict for selection except ImportError: print("Warning: Could not import default config from parent directory.") # Define a minimal fallback Config class class Config: SECRET_KEY = os.environ.get('SECRET_KEY') or 'a-default-fallback-secret-key' DEBUG = False config_options = {'default': Config} def create_app(config_name='default') -> Flask: """ Creates and configures the Flask application instance. Uses the Application Factory pattern. """ # === Step 1: Create Flask App === # Enable loading from the instance/ folder relative to the 'backend' directory app = Flask(__name__, instance_relative_config=True) # === Step 2: Load Configuration === # Load default config based on config_name (if using different configs) selected_config = config_options.get(config_name, Config) app.config.from_object(selected_config) # Load instance config (/instance/config.py) - Overrides defaults # silent=True prevents errors if the file doesn't exist app.config.from_pyfile('config.py', silent=True) # === Step 3: Initialize Extensions === if mongo: try: mongo.init_app(app) print("PyMongo initialized successfully.") except Exception as e: print(f"Error initializing PyMongo: {e}") if cors: try: # Configure CORS using settings from app.config frontend_origin = "http://localhost:5173" cors.init_app(app, resources={r"/api/*": {"origins": app.config.get('FRONTEND_ORIGIN', '*')}}, supports_credentials=True) print("CORS initialized successfully.") except Exception as e: print(f"Error initializing CORS: {e}") # if jwt: # try: # jwt.init_app(app) # print("JWTManager initialized successfully.") # except Exception as e: # print(f"Error initializing JWTManager: {e}") # Add init_app calls for other extensions (ma, migrate, etc.) here # === Step 4: Register Blueprints === # Use unique variable names and appropriate prefixes try: # Assuming each blueprint's __init__.py defines an object named 'bp' from .auth import bp as auth_bp # checked from .ai_services import bp as ai_services_bp from .activity import bp as activity_bp from .dialog import bp as dialog_bp from .projects import bp as projects_bp # checked from .urls import bp as urls_bp # Register with potentially more specific prefixes app.register_blueprint(auth_bp, url_prefix='/api') app.register_blueprint(ai_services_bp, url_prefix="/api/ai") # Changed prefix app.register_blueprint(activity_bp, url_prefix='/api/activity') app.register_blueprint(projects_bp, url_prefix='/api/projects') app.register_blueprint(dialog_bp, url_prefix="/api/dialog") app.register_blueprint(urls_bp, url_prefix="/api/urls") print("Blueprints registered successfully.") except (ModuleNotFoundError, ImportError) as e: print(f"Error importing or registering blueprints: {e}. Check blueprint structure and 'bp' variable names.") except Exception as e: print(f"An unexpected error occurred during blueprint registration: {e}") # === Step 5: Add Root Route (Optional) === @app.route("/") def index(): # You could add a check here to see if mongo connection is working db_status = "disconnected" if mongo: try: # The ismaster command is cheap and does not require auth. mongo.cx.admin.command('ismaster') db_status = "connected" except Exception: db_status = "connection error" return jsonify({"message": "Backend service is running!", "database_status": db_status}) # You can also add other app-wide error handlers here if needed @app.errorhandler(404) def page_not_found(e): return jsonify(error=str(e)), 404 print(f"App created with config: {config_name}") print(f"Instance path: {app.instance_path}") # Check instance path return app