8188985029
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
44 lines
1.3 KiB
Python
44 lines
1.3 KiB
Python
"""Quart app factory."""
|
|
|
|
import logging
|
|
from pathlib import Path
|
|
|
|
from quart import Quart
|
|
|
|
from .api import all_blueprints
|
|
from .config import get_config
|
|
from .frontend import frontend_bp
|
|
from .services.credential_crypto import CredentialCrypto
|
|
|
|
_CREDENTIAL_KEY_PATH = Path("/images/secrets/credential_key.b64")
|
|
|
|
|
|
def create_app() -> Quart:
|
|
cfg = get_config()
|
|
logging.basicConfig(level=cfg.log_level)
|
|
|
|
# Bootstrap the credential encryption key file (mode 0600) before
|
|
# any request can land. FC-3b: file-based system-generated key.
|
|
CredentialCrypto(_CREDENTIAL_KEY_PATH)
|
|
|
|
app = Quart(__name__)
|
|
app.secret_key = cfg.secret_key
|
|
# FC-5: legacy IR ingest JSON can run to tens of MB (hundreds of
|
|
# thousands of image_tag_associations). Werkzeug's default form
|
|
# memory cap is 500KB; raise both ceilings so the multipart upload
|
|
# for /api/migrate/ir_ingest doesn't 413.
|
|
app.config["MAX_CONTENT_LENGTH"] = 1024 * 1024 * 1024 # 1 GB
|
|
app.config["MAX_FORM_MEMORY_SIZE"] = 1024 * 1024 * 1024 # 1 GB
|
|
|
|
for bp in all_blueprints():
|
|
app.register_blueprint(bp)
|
|
# Registered last so /api/* routes win over the SPA catch-all.
|
|
app.register_blueprint(frontend_bp)
|
|
|
|
@app.after_serving
|
|
async def _dispose_db_engine() -> None:
|
|
from .extensions import dispose_engine
|
|
await dispose_engine()
|
|
|
|
return app
|