MicroFish/backend/app/__init__.py

82 lines
2.7 KiB
Python

"""
MiroFish Backend - Flask application factory
"""
import os
import warnings
# Suppress multiprocessing resource_tracker warnings (from third-party libraries like transformers)
# Must be set before all other imports
warnings.filterwarnings("ignore", message=".*resource_tracker.*")
from flask import Flask, request
from flask_cors import CORS
from .config import Config
from .utils.logger import setup_logger, get_logger
def create_app(config_class=Config):
"""Flask application factory function"""
app = Flask(__name__)
app.config.from_object(config_class)
# Set JSON encoding: ensure Chinese characters display directly (instead of \uXXXX format)
# Flask >= 2.3 uses app.json.ensure_ascii, older versions use JSON_AS_ASCII config
if hasattr(app, "json") and hasattr(app.json, "ensure_ascii"):
app.json.ensure_ascii = False
# Set up logging
logger = setup_logger("mirofish")
# Only log startup info in the reloader child process (avoid duplicate logs in debug mode)
is_reloader_process = os.environ.get("WERKZEUG_RUN_MAIN") == "true"
debug_mode = app.config.get("DEBUG", False)
should_log_startup = not debug_mode or is_reloader_process
if should_log_startup:
logger.info("=" * 50)
logger.info("MiroFish Backend starting...")
logger.info("=" * 50)
# Enable CORS
CORS(app, resources={r"/api/*": {"origins": "*"}})
# Register simulation process cleanup function (ensure all simulation processes terminate on server shutdown)
from .services.simulation_runner import SimulationRunner
SimulationRunner.register_cleanup()
if should_log_startup:
logger.info("Registered simulation process cleanup function")
# Request logging middleware
@app.before_request
def log_request():
logger = get_logger("mirofish.request")
logger.debug(f"Request: {request.method} {request.path}")
if request.content_type and "json" in request.content_type:
logger.debug(f"Request body: {request.get_json(silent=True)}")
@app.after_request
def log_response(response):
logger = get_logger("mirofish.request")
logger.debug(f"Response: {response.status_code}")
return response
# Register blueprints
from .api import graph_bp, simulation_bp, report_bp
app.register_blueprint(graph_bp, url_prefix="/api/graph")
app.register_blueprint(simulation_bp, url_prefix="/api/simulation")
app.register_blueprint(report_bp, url_prefix="/api/report")
# Health check
@app.route("/health")
def health():
return {"status": "ok", "service": "MiroFish Backend"}
if should_log_startup:
logger.info("MiroFish Backend startup complete")
return app