Spaces:
Running
π§ Fix persistent storage permission errors for HF Spaces
Browse filesπ¨ Critical Fix: Persistent storage now handles permission errors gracefully
β
What's Fixed:
β’ Handle /data directory permission denied errors
β’ Graceful fallback to local backup strategy when persistent storage unavailable
β’ Better error logging with warning emojis
β’ App continues to function even without /data access
π§ Technical Changes:
β’ Enhanced initialize_app() with proper permission error handling
β’ Updated _backup_to_persistent_storage() with try/catch for permissions
β’ Added conditional checks for persistent_db_path availability
β’ Better logging: β
success, β οΈ warnings, π local backup mode
π Result:
β’ App no longer crashes on HF Spaces with permission errors
β’ Still uses git + static file backup strategy
β’ Data persistence through multiple backup methods
β’ Graceful degradation when /data is inaccessible
Now works reliably in ANY environment!
@@ -424,12 +424,20 @@ def initialize_app():
|
|
424 |
persistent_db_path = Path("/data/trees.db")
|
425 |
local_db_path = Path("data/trees.db")
|
426 |
|
427 |
-
# Ensure
|
428 |
-
persistent_db_path.parent.mkdir(parents=True, exist_ok=True)
|
429 |
local_db_path.parent.mkdir(parents=True, exist_ok=True)
|
430 |
|
431 |
-
#
|
432 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
433 |
logger.info("Found persistent database, copying to local directory...")
|
434 |
shutil.copy2(persistent_db_path, local_db_path)
|
435 |
with sqlite3.connect(local_db_path) as conn:
|
@@ -449,7 +457,12 @@ def initialize_app():
|
|
449 |
if backup_path.exists():
|
450 |
logger.info(f"Found backup at {backup_path}, restoring...")
|
451 |
shutil.copy2(backup_path, local_db_path)
|
452 |
-
|
|
|
|
|
|
|
|
|
|
|
453 |
backup_restored = True
|
454 |
break
|
455 |
|
@@ -463,8 +476,11 @@ def initialize_app():
|
|
463 |
# Initialize database (creates tables if they don't exist)
|
464 |
init_db()
|
465 |
|
466 |
-
# Initial backup to persistent storage
|
467 |
-
|
|
|
|
|
|
|
468 |
|
469 |
# Log current status
|
470 |
if local_db_path.exists():
|
@@ -489,11 +505,15 @@ def _backup_to_persistent_storage():
|
|
489 |
persistent_db = Path("/data/trees.db")
|
490 |
|
491 |
if source_db.exists():
|
492 |
-
#
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
|
|
|
|
|
|
|
|
497 |
except Exception as e:
|
498 |
logger.error(f"Persistent storage backup failed: {e}")
|
499 |
return False
|
|
|
424 |
persistent_db_path = Path("/data/trees.db")
|
425 |
local_db_path = Path("data/trees.db")
|
426 |
|
427 |
+
# Ensure local directory exists
|
|
|
428 |
local_db_path.parent.mkdir(parents=True, exist_ok=True)
|
429 |
|
430 |
+
# Try to ensure persistent directory exists (may fail on some systems)
|
431 |
+
try:
|
432 |
+
persistent_db_path.parent.mkdir(parents=True, exist_ok=True)
|
433 |
+
logger.info("β
Persistent storage directory available at /data")
|
434 |
+
except (PermissionError, OSError) as e:
|
435 |
+
logger.warning(f"β οΈ Cannot create /data directory: {e}. Using local backup strategy.")
|
436 |
+
# Fallback to local backup strategy only
|
437 |
+
persistent_db_path = None
|
438 |
+
|
439 |
+
# Check if we have a persistent database in /data (if available)
|
440 |
+
if persistent_db_path and persistent_db_path.exists():
|
441 |
logger.info("Found persistent database, copying to local directory...")
|
442 |
shutil.copy2(persistent_db_path, local_db_path)
|
443 |
with sqlite3.connect(local_db_path) as conn:
|
|
|
457 |
if backup_path.exists():
|
458 |
logger.info(f"Found backup at {backup_path}, restoring...")
|
459 |
shutil.copy2(backup_path, local_db_path)
|
460 |
+
# Try to save to persistent storage if available
|
461 |
+
if persistent_db_path:
|
462 |
+
try:
|
463 |
+
shutil.copy2(backup_path, persistent_db_path)
|
464 |
+
except (PermissionError, OSError):
|
465 |
+
logger.warning("Cannot write to persistent storage")
|
466 |
backup_restored = True
|
467 |
break
|
468 |
|
|
|
476 |
# Initialize database (creates tables if they don't exist)
|
477 |
init_db()
|
478 |
|
479 |
+
# Initial backup to persistent storage (if available)
|
480 |
+
if persistent_db_path:
|
481 |
+
_backup_to_persistent_storage()
|
482 |
+
else:
|
483 |
+
logger.info("π Using local backup strategy only (no persistent storage)")
|
484 |
|
485 |
# Log current status
|
486 |
if local_db_path.exists():
|
|
|
505 |
persistent_db = Path("/data/trees.db")
|
506 |
|
507 |
if source_db.exists():
|
508 |
+
# Try to ensure /data directory exists
|
509 |
+
try:
|
510 |
+
persistent_db.parent.mkdir(parents=True, exist_ok=True)
|
511 |
+
shutil.copy2(source_db, persistent_db)
|
512 |
+
logger.info(f"β
Database backed up to persistent storage: {persistent_db}")
|
513 |
+
return True
|
514 |
+
except (PermissionError, OSError) as e:
|
515 |
+
logger.warning(f"β οΈ Cannot backup to persistent storage: {e}")
|
516 |
+
return False
|
517 |
except Exception as e:
|
518 |
logger.error(f"Persistent storage backup failed: {e}")
|
519 |
return False
|