start project

This commit is contained in:
Hemmat
2026-08-07 21:17:17 +03:30
commit ea1e1eead6
121 changed files with 8108 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
"""Application factory (Chapter 02 / Chapter 04)."""
from __future__ import annotations
from flask import Flask, jsonify, redirect, request, url_for
from flask_login import current_user
from sqlalchemy import text
from app.budget import validate_budget_config
from app.config import get_config
from app.extensions import cache, csrf, db, limiter, login_manager, migrate
from app.logging_setup import configure_logging
from app.utils.assets import register_asset_helper
def create_app(config_name: str | None = None) -> Flask:
"""Build and configure the Flask application instance."""
app = Flask(__name__)
app.config.from_object(get_config(config_name))
validate_budget_config(app) # Chapter 03: fail loudly on out-of-budget config
configure_logging(app) # Chapter 02 factor 11 / Chapter 12
if not app.config.get("SECRET_KEY") and not app.testing:
raise RuntimeError("SECRET_KEY must be set via environment variable")
db.init_app(app)
cache.init_app(app)
csrf.init_app(app)
login_manager.init_app(app)
migrate.init_app(app, db)
limiter.init_app(app) # Chapter 12: rate limiting
register_blueprints(app)
register_cli(app)
register_asset_helper(app)
@login_manager.unauthorized_handler
def handle_unauthorized():
"""Chapter 11 envelope compliance: JSON 401 for /api/... paths
instead of Flask-Login's default redirect (which would hand back
login HTML to a fetch()/HTMX JSON caller). Full-page routes still
redirect to the login form as normal.
"""
if request.path.startswith("/api/"):
return jsonify(error={"code": "unauthorized", "message": "Authentication required."}), 401
return redirect(url_for("auth.login", next=request.path))
@app.get("/healthz")
def healthz():
"""Liveness/readiness check (Chapter 12) — DB reachable, no long-running work."""
db.session.execute(text("SELECT 1"))
return {"data": {"status": "ok"}, "meta": {}}
@app.get("/")
def index():
"""Root URL: authenticated -> Overview, otherwise -> the login page."""
if current_user.is_authenticated:
return redirect(url_for("overview.overview"))
return redirect(url_for("auth.login"))
return app
def register_blueprints(app: Flask) -> None:
"""Register one blueprint per dashboard section + support area (Ch. 04)."""
from app.blueprints.api import bp as api_bp
from app.blueprints.auth import bp as auth_bp
from app.blueprints.overview import bp as overview_bp
from app.blueprints.security import bp as security_bp
from app.blueprints.seo import bp as seo_bp
from app.blueprints.uploads import bp as uploads_bp
app.register_blueprint(overview_bp)
app.register_blueprint(seo_bp)
app.register_blueprint(security_bp)
app.register_blueprint(uploads_bp)
app.register_blueprint(api_bp)
app.register_blueprint(auth_bp)
def register_cli(app: Flask) -> None:
"""Attach `flask <command>` admin processes (factor 12)."""
from app.cli import register_commands
register_commands(app)