""" StarPunk package initialization Creates and configures the Flask application """ import logging from flask import Flask def configure_logging(app): """ Configure application logging based on LOG_LEVEL Args: app: Flask application instance """ log_level = app.config.get("LOG_LEVEL", "INFO").upper() # Set Flask logger level app.logger.setLevel(getattr(logging, log_level, logging.INFO)) # Configure handler with detailed format for DEBUG handler = logging.StreamHandler() if log_level == "DEBUG": formatter = logging.Formatter( "[%(asctime)s] %(levelname)s - %(name)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) # Warn if DEBUG enabled in production if not app.debug and app.config.get("ENV") != "development": app.logger.warning( "=" * 70 + "\n" + "WARNING: DEBUG logging enabled in production!\n" + "This logs detailed HTTP requests/responses.\n" + "Sensitive data is redacted, but consider using INFO level.\n" + "Set LOG_LEVEL=INFO in production for normal operation.\n" + "=" * 70 ) else: formatter = logging.Formatter( "[%(asctime)s] %(levelname)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S" ) handler.setFormatter(formatter) # Remove existing handlers and add our configured handler app.logger.handlers.clear() app.logger.addHandler(handler) def create_app(config=None): """ Application factory for StarPunk Args: config: Optional configuration dict to override defaults Returns: Configured Flask application instance """ app = Flask(__name__, static_folder="../static", template_folder="../templates") # Load configuration from starpunk.config import load_config load_config(app, config) # Configure logging configure_logging(app) # Initialize database from starpunk.database import init_db init_db(app) # Register blueprints from starpunk.routes import register_routes register_routes(app) # Error handlers @app.errorhandler(404) def not_found(error): from flask import render_template, request # Return HTML for browser requests, JSON for API requests if request.path.startswith("/api/"): return {"error": "Not found"}, 404 return render_template("404.html"), 404 @app.errorhandler(500) def server_error(error): from flask import render_template, request # Return HTML for browser requests, JSON for API requests if request.path.startswith("/api/"): return {"error": "Internal server error"}, 500 return render_template("500.html"), 500 # Health check endpoint for containers and monitoring @app.route("/health") def health_check(): """ Health check endpoint for containers and monitoring Returns: JSON with status and basic info Response codes: 200: Application healthy 500: Application unhealthy Checks: - Database connectivity - File system access - Basic application state """ from flask import jsonify import os try: # Check database connectivity from starpunk.database import get_db db = get_db(app) db.execute("SELECT 1").fetchone() db.close() # Check filesystem access data_path = app.config.get("DATA_PATH", "data") if not os.path.exists(data_path): raise Exception("Data path not accessible") return ( jsonify( { "status": "healthy", "version": app.config.get("VERSION", __version__), "environment": app.config.get("ENV", "unknown"), } ), 200, ) except Exception as e: return jsonify({"status": "unhealthy", "error": str(e)}), 500 return app # Package version (Semantic Versioning 2.0.0) # See docs/standards/versioning-strategy.md for details __version__ = "0.9.3" __version_info__ = (0, 9, 3)