58 lines
1.8 KiB
Python
58 lines
1.8 KiB
Python
import os
|
|
from pathlib import Path
|
|
|
|
from flask import Flask
|
|
|
|
from config import CONFIGS
|
|
|
|
from .extensions import csrf, db, login_manager, migrate
|
|
|
|
|
|
def create_app(config_name: str | None = None) -> Flask:
|
|
"""Create and configure an isolated Steady application instance."""
|
|
|
|
app = Flask(__name__, instance_relative_config=True)
|
|
|
|
selected_config = config_name or os.environ.get("STEADY_ENV", "development")
|
|
try:
|
|
app.config.from_object(CONFIGS[selected_config])
|
|
except KeyError as exc:
|
|
valid_names = ", ".join(sorted(CONFIGS))
|
|
raise ValueError(
|
|
f"Unknown configuration {selected_config!r}; choose {valid_names}."
|
|
) from exc
|
|
|
|
Path(app.instance_path).mkdir(parents=True, exist_ok=True)
|
|
_validate_config(app)
|
|
_initialize_extensions(app)
|
|
_register_blueprints(app)
|
|
|
|
return app
|
|
|
|
|
|
def _validate_config(app: Flask) -> None:
|
|
if not app.config.get("SECRET_KEY"):
|
|
raise RuntimeError("SECRET_KEY must be set outside development and testing.")
|
|
|
|
|
|
def _initialize_extensions(app: Flask) -> None:
|
|
db.init_app(app)
|
|
migrate.init_app(app, db)
|
|
login_manager.init_app(app)
|
|
csrf.init_app(app)
|
|
|
|
login_manager.login_view = "auth.login"
|
|
login_manager.login_message_category = "info"
|
|
|
|
|
|
def _register_blueprints(app: Flask) -> None:
|
|
# Imports stay local so feature modules do not create circular imports.
|
|
from .auth import bp as auth_blueprint
|
|
from .core import bp as core_blueprint
|
|
from .settings import bp as settings_blueprint
|
|
from .tasks import bp as tasks_blueprint
|
|
|
|
app.register_blueprint(core_blueprint)
|
|
app.register_blueprint(auth_blueprint, url_prefix="/auth")
|
|
app.register_blueprint(tasks_blueprint, url_prefix="/tasks")
|
|
app.register_blueprint(settings_blueprint, url_prefix="/settings")
|