initial: novel-app snapshot
This commit is contained in:
84
app.py
Normal file
84
app.py
Normal file
@@ -0,0 +1,84 @@
|
||||
"""Flask backend for novel-writer.
|
||||
|
||||
Application factory only — routes live in routes/, business logic in
|
||||
services/, queries in repositories/. See config.py for env overrides.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import uuid
|
||||
|
||||
from flask import Flask, g, has_request_context, request
|
||||
|
||||
import config
|
||||
import security
|
||||
from extensions import close_db
|
||||
from routes import api_bp, pages_bp
|
||||
|
||||
|
||||
class _RequestIdFilter(logging.Filter):
|
||||
"""Inject `request_id` into every LogRecord so the formatter can print it.
|
||||
|
||||
Reads Flask `g.request_id` when a request context is active; falls back
|
||||
to "-" for log lines emitted outside a request (startup, daemon threads).
|
||||
"""
|
||||
|
||||
def filter(self, record):
|
||||
if has_request_context():
|
||||
record.request_id = getattr(g, "request_id", "-")
|
||||
else:
|
||||
record.request_id = "-"
|
||||
return True
|
||||
|
||||
|
||||
_LOG_FORMAT = "%(asctime)s [%(process)d] [%(request_id)s] %(levelname)s: %(message)s"
|
||||
|
||||
_handler = logging.StreamHandler()
|
||||
_handler.setFormatter(logging.Formatter(_LOG_FORMAT))
|
||||
_handler.addFilter(_RequestIdFilter())
|
||||
|
||||
_root = logging.getLogger()
|
||||
_root.setLevel(logging.INFO)
|
||||
if not any(isinstance(h, logging.StreamHandler) and h.formatter for h in _root.handlers):
|
||||
_root.addHandler(_handler)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def create_app():
|
||||
app = Flask(
|
||||
__name__,
|
||||
template_folder=os.path.join(config.BASE_DIR, "templates"),
|
||||
static_folder=os.path.join(config.BASE_DIR, "static"),
|
||||
)
|
||||
app.secret_key = config.SECRET_KEY
|
||||
|
||||
@app.before_request
|
||||
def _assign_request_id():
|
||||
g.request_id = uuid.uuid4().hex[:8]
|
||||
|
||||
@app.after_request
|
||||
def _log_request(response):
|
||||
logger.info(
|
||||
"%s %s -> %s (%s)",
|
||||
request.method,
|
||||
request.path,
|
||||
response.status_code,
|
||||
g.request_id,
|
||||
)
|
||||
return response
|
||||
|
||||
app.teardown_appcontext(close_db)
|
||||
security.init_app(app)
|
||||
|
||||
app.register_blueprint(api_bp)
|
||||
app.register_blueprint(pages_bp)
|
||||
|
||||
return app
|
||||
|
||||
|
||||
app = create_app()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0", port=config.PORT, debug=False)
|
||||
Reference in New Issue
Block a user