start project
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
"""Singleton Flask extension instances — initialized, not configured, here.
|
||||
|
||||
Configuration happens in create_app() via .init_app(), so nothing here
|
||||
holds app- or request-scoped state that must survive a process restart
|
||||
(factor 6: stateless processes).
|
||||
"""
|
||||
from flask_caching import Cache
|
||||
from flask_limiter import Limiter
|
||||
from flask_limiter.util import get_remote_address
|
||||
from flask_login import LoginManager
|
||||
from flask_migrate import Migrate
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_wtf import CSRFProtect
|
||||
|
||||
db = SQLAlchemy()
|
||||
cache = Cache()
|
||||
csrf = CSRFProtect()
|
||||
login_manager = LoginManager()
|
||||
login_manager.login_view = "auth.login"
|
||||
migrate = Migrate()
|
||||
|
||||
# In-memory storage (Chapter 12: "in-memory or DB-backed... do not require
|
||||
# Redis"). CAVEAT (flagged): each of up to 60 entry processes (Ch03) keeps
|
||||
# its own counters, so the effective ceiling across the whole app is up to
|
||||
# (per-process limit x concurrent processes hit), not one hard global cap.
|
||||
# Acceptable for this app's threat model (slowing down /login and /uploads
|
||||
# brute-forcing), but not a strict global rate guarantee.
|
||||
limiter = Limiter(key_func=get_remote_address, storage_uri="memory://")
|
||||
Reference in New Issue
Block a user