From 74eed9a6e2918f62c49fd90ecc274ecdbd96ab82 Mon Sep 17 00:00:00 2001 From: Mark Liffiton Date: Fri, 8 Nov 2024 15:24:19 -0600 Subject: [PATCH] Fix temporary file conflicts on Windows. --- src/gened/admin.py | 5 +++-- src/gened/base.py | 47 +++++++++++++++++++++++----------------------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/gened/admin.py b/src/gened/admin.py index b9b40af..c98f9c0 100644 --- a/src/gened/admin.py +++ b/src/gened/admin.py @@ -334,12 +334,13 @@ def main() -> str: @register_admin_link("Download DB", right=True) @bp.route("/get_db") def get_db_file() -> Response: - db_backup_file = NamedTemporaryFile() + db_backup_file = NamedTemporaryFile(delete_on_close=False) + db_backup_file.close() # avoid double-open in the backup_db function (fails on Windows) backup_db(Path(db_backup_file.name)) db_name = current_app.config['DATABASE_NAME'] db_basename = Path(db_name).stem dl_name = f"{db_basename}_{date.today().strftime('%Y%m%d')}.db" - return send_file(db_backup_file, mimetype='application/vnd.sqlite3', as_attachment=True, download_name=dl_name) + return send_file(db_backup_file.name, mimetype='application/vnd.sqlite3', as_attachment=True, download_name=dl_name) @bp.route("/consumer/new") diff --git a/src/gened/base.py b/src/gened/base.py index 9f37243..389f234 100644 --- a/src/gened/base.py +++ b/src/gened/base.py @@ -164,29 +164,6 @@ def create_app_base(import_name: str, app_config: dict[str, Any], instance_path: # configure the application app.config.from_mapping(total_config) - # run setup and checks that depend on the database iff it is initialized - with app.app_context(): - db_conn = db.get_db() - try: - db_conn.execute("SELECT 1 FROM consumers LIMIT 1") - db_conn.execute("SELECT 1 FROM models LIMIT 1") - db_initialized = True - except sqlite3.OperationalError: - db_initialized = False - - if db_initialized: - # load consumers from DB - admin.reload_consumers() - - # validate that the default class model exists and is active - default_model_row = db_conn.execute( - "SELECT 1 FROM models WHERE active AND shortname = ?", - [app.config['DEFAULT_CLASS_MODEL_SHORTNAME']] - ).fetchone() - if not default_model_row: - app.logger.error(f"Default model shortname '{app.config['DEFAULT_CLASS_MODEL_SHORTNAME']}' not found in active models.") - sys.exit(1) - admin.init_app(app) db.init_app(app) filters.init_app(app) @@ -227,4 +204,28 @@ def landing() -> str: def well_known(path: Path) -> Response: return send_from_directory(Path(app.instance_path) / '.well-known', path) + # run setup and checks that depend on the database (iff it is initialized) + # requires that db.init_app() has been called to ensure db is closed at end of context manager + with app.app_context(): + db_conn = db.get_db() + try: + db_conn.execute("SELECT 1 FROM consumers LIMIT 1") + db_conn.execute("SELECT 1 FROM models LIMIT 1") + db_initialized = True + except sqlite3.OperationalError: + db_initialized = False + + if db_initialized: + # load consumers from DB + admin.reload_consumers() + + # validate that the default class model exists and is active + default_model_row = db_conn.execute( + "SELECT 1 FROM models WHERE active AND shortname = ?", + [app.config['DEFAULT_CLASS_MODEL_SHORTNAME']] + ).fetchone() + if not default_model_row: + app.logger.error(f"Default model shortname '{app.config['DEFAULT_CLASS_MODEL_SHORTNAME']}' not found in active models.") + sys.exit(1) + return app