2025-06-09 17:53:19 +08:00

124 lines
4.9 KiB
Python

# 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/auth')
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