Backups¶
The Konigle SDK provides comprehensive backup management for creating and restoring backups of various website resources. Backups support both transient (temporary) and durable (long-term) storage for pages, folders, blogs, products, and site-level templates.
Creating Backups¶
Basic Backup Creation¶
import konigle
from konigle.models.website import BackupCreate
client = konigle.Client(api_key="your-api-key")
# Create a backup of a page
backup_data = BackupCreate(
backup_type="page",
target_id="page_123456789",
description="Backup before major redesign",
trigger="manual"
)
backup = client.backups.create(backup_data)
print(f"Created backup: {backup.id}")
print(f"Status: {backup.status}")
print(f"Type: {backup.backup_type}")
Durable vs Transient Backups¶
# Durable backup - for long-term storage
# Can be restored weeks or months later
durable_backup = BackupCreate(
kind="durable", # Default
backup_type="page",
target_id="page_123456789",
description="Before major redesign",
trigger="manual"
)
backup = client.backups.create(durable_backup)
print(f"Durable backup created: {backup.id}")
# Transient backup - for temporary storage
# Typically created during editing sessions or AI chat
transient_backup = BackupCreate(
kind="transient",
backup_type="blog",
target_id="blog_987654321",
description="Quick save during editing",
trigger="auto_pre_edit"
)
temp_backup = client.backups.create(transient_backup)
print(f"Transient backup created: {temp_backup.id}")
Backup Different Resource Types¶
# Page backup
page_backup = client.backups.create(BackupCreate(
backup_type="page",
target_id="page_123456789",
description="Before content update",
trigger="manual"
))
# Blog backup
blog_backup = client.backups.create(BackupCreate(
backup_type="blog",
target_id="blog_987654321",
description="Before publishing",
trigger="auto_pre_publish"
))
# Folder backup (includes layout and settings)
folder_backup = client.backups.create(BackupCreate(
backup_type="folder",
target_id="folder_456789123",
description="Before folder restructure",
trigger="manual"
))
# Product backup
product_backup = client.backups.create(BackupCreate(
backup_type="product",
target_id="product_111222333",
description="Before price update",
trigger="manual"
))
Site Template Backup¶
# Site template backup (no target_id needed)
template_backup = client.backups.create(BackupCreate(
backup_type="site_template",
target_id=None, # Site-level backups don't have a specific target
description="Before template upgrade",
trigger="manual"
))
Backup Triggers¶
# Manual backup - created by user
manual_backup = client.backups.create(BackupCreate(
backup_type="page",
target_id="page_123",
trigger="manual"
))
# Auto pre-edit backup - created before editing
pre_edit_backup = client.backups.create(BackupCreate(
backup_type="page",
target_id="page_123",
trigger="auto_pre_edit",
kind="transient"
))
# Auto pre-publish backup - created before publishing
pre_publish_backup = client.backups.create(BackupCreate(
backup_type="blog",
target_id="blog_456",
trigger="auto_pre_publish"
))
# Scheduled backup - created by automated task
scheduled_backup = client.backups.create(BackupCreate(
backup_type="site_template",
trigger="scheduled"
))
Listing Backups¶
Basic Backup Listing¶
# List all backups with pagination
backups = client.backups.list(page=1, page_size=20)
print(f"Total backups: {backups.count}")
print(f"Current page: {backups.current_page}/{backups.num_pages}")
for backup in backups.payload:
print(f"- {backup.backup_type}: {backup.target_description}")
print(f" ID: {backup.id}")
print(f" Status: {backup.status}")
print(f" Created: {backup.created_at}")
Filtering Backups¶
from konigle.filters.website import BackupFilters
# Filter by backup type
page_backups = client.backups.list(
backup_type="page",
page_size=10
)
# Filter by status
completed_backups = client.backups.list(
status="completed",
ordering="-created_at" # Newest first
)
# Filter by kind
durable_backups = client.backups.list(kind="durable")
# Filter by target ID (all backups for a specific page)
target_backups = client.backups.list(
target_id="page_123456789",
ordering="-created_at"
)
# Using filter object (type-safe)
filters = BackupFilters(
kind="durable",
backup_type="page",
status="completed",
ordering="-created_at"
)
filtered_backups = client.backups.list(
page=1,
page_size=10,
filters=filters
)
Filter Multiple Criteria¶
# Get all completed page backups
completed_page_backups = client.backups.list(
backup_type="page",
status="completed",
kind="durable"
)
# Get all backups for a specific blog
blog_backups = client.backups.list(
backup_type="blog",
target_id="blog_987654321"
)
# Get failed backups for debugging
failed_backups = client.backups.list(status="failed")
for backup in failed_backups.payload:
print(f"Failed backup: {backup.id}")
print(f"Error: {backup.error_message}")
Getting a Specific Backup¶
# Get backup by ID
backup = client.backups.get("backup_123456789")
print(f"Backup ID: {backup.id}")
print(f"Type: {backup.backup_type}")
print(f"Kind: {backup.kind}")
print(f"Status: {backup.status}")
print(f"Target: {backup.target_description}")
print(f"Description: {backup.description}")
if backup.file_size_bytes:
size_mb = backup.file_size_bytes / (1024 * 1024)
print(f"Size: {size_mb:.2f} MB")
if backup.error_message:
print(f"Error: {backup.error_message}")
Restoring Backups¶
Basic Restore¶
# Restore a backup
result = client.backups.restore("backup_123456789")
print(f"Restoration status: {result.get('status')}")
# The restoration happens asynchronously on the server
# The current version will be overwritten with the backup
Restore with Safety Check¶
def restore_with_confirmation(backup_id: str):
"""Restore backup with safety check."""
# Get backup details first
backup = client.backups.get(backup_id)
print(f"Backup details:")
print(f" Type: {backup.backup_type}")
print(f" Target: {backup.target_description}")
print(f" Created: {backup.created_at}")
print(f" Description: {backup.description}")
# Confirm before restore
confirm = input("Restore this backup? (yes/no): ")
if confirm.lower() == "yes":
result = client.backups.restore(backup_id)
print(f"✓ Restoration started: {result.get('status')}")
else:
print("Restore cancelled")
# Usage
restore_with_confirmation("backup_123456789")
Restore Latest Backup for Resource¶
def restore_latest_backup(backup_type: str, target_id: str):
"""Restore the most recent completed backup for a resource."""
# Find the latest completed backup
backups = client.backups.list(
backup_type=backup_type,
target_id=target_id,
status="completed",
ordering="-created_at",
page_size=1
)
if not backups.payload:
print(f"No backups found for {backup_type} {target_id}")
return
latest_backup = backups.payload[0]
print(f"Restoring backup from {latest_backup.created_at}")
result = client.backups.restore(latest_backup.id)
print(f"Restoration status: {result.get('status')}")
# Usage
restore_latest_backup("page", "page_123456789")
Deleting Backups¶
# Delete a backup
success = client.backups.delete("backup_123456789")
if success:
print("Backup deleted successfully")
else:
print("Failed to delete backup")
Delete Old Backups¶
from datetime import datetime, timedelta
def delete_old_transient_backups(days_old: int = 7):
"""Delete transient backups older than specified days."""
backups = client.backups.list(
kind="transient",
ordering="created_at", # Oldest first
page_size=50
)
cutoff_date = datetime.now() - timedelta(days=days_old)
deleted_count = 0
for backup in backups.payload:
if backup.created_at < cutoff_date:
client.backups.delete(backup.id)
deleted_count += 1
print(f"Deleted old backup: {backup.id}")
print(f"Deleted {deleted_count} old transient backups")
# Usage
delete_old_transient_backups(days_old=7)
Iterating All Backups¶
# Memory-efficient iteration over all backups
for backup in client.backups.iter_all(page_size=50):
print(f"Processing backup: {backup.id}")
# With filtering - get all completed page backups
for backup in client.backups.iter_all(
page_size=50,
backup_type="page",
status="completed"
):
print(f"Page backup: {backup.target_description}")
Async Operations¶
import asyncio
import konigle
async def manage_backups():
async with konigle.AsyncClient(api_key="your-api-key") as client:
# Create backup
backup_data = BackupCreate(
backup_type="page",
target_id="page_123456789",
description="Async backup",
trigger="manual"
)
backup = await client.backups.create(backup_data)
# List backups with filtering
backups = await client.backups.list(
page_size=10,
backup_type="page",
status="completed"
)
# Get backup details
backup_detail = await client.backups.get(backup.id)
# Restore backup
result = await client.backups.restore(backup.id)
# Delete backup
await client.backups.delete(backup.id)
asyncio.run(manage_backups())
Common Backup Workflows¶
Pre-Edit Backup Workflow¶
def safe_page_edit(page_id: str, new_content: dict):
"""Create backup before editing, then update page."""
# Create backup before editing
backup = client.backups.create(BackupCreate(
kind="transient",
backup_type="page",
target_id=page_id,
description="Auto backup before edit",
trigger="auto_pre_edit"
))
print(f"Created backup: {backup.id}")
# Update the page
from konigle.models.website import PageUpdate
update_data = PageUpdate(content=new_content)
updated_page = client.pages.update(page_id, update_data)
print(f"Page updated: {updated_page.title}")
print(f"Backup available for rollback: {backup.id}")
return updated_page, backup
# Usage
new_content = {
"blocks": [
{"type": "paragraph", "data": {"text": "Updated content"}}
]
}
page, backup = safe_page_edit("page_123", new_content)
Bulk Backup Creation¶
def backup_all_published_pages():
"""Create backups for all published pages."""
# Get all published pages
pages = client.pages.list(
published=True,
page_size=50
)
backups_created = []
for page in pages.payload:
try:
backup = client.backups.create(BackupCreate(
backup_type="page",
target_id=page.id,
description=f"Scheduled backup of {page.title}",
trigger="scheduled"
))
backups_created.append(backup)
print(f"✓ Backed up: {page.title}")
except Exception as e:
print(f"✗ Failed to backup {page.title}: {e}")
print(f"Created {len(backups_created)} backups")
return backups_created
# Usage
backups = backup_all_published_pages()
Backup Monitoring¶
def monitor_backup_status(backup_id: str, max_wait: int = 60):
"""Monitor backup status until completion."""
import time
start_time = time.time()
while True:
backup = client.backups.get(backup_id)
if backup.status == "completed":
print(f"✓ Backup completed")
if backup.file_size_bytes:
size_mb = backup.file_size_bytes / (1024 * 1024)
print(f" Size: {size_mb:.2f} MB")
return backup
elif backup.status == "failed":
print(f"✗ Backup failed: {backup.error_message}")
return None
elapsed = time.time() - start_time
if elapsed > max_wait:
print(f"⧗ Backup still in progress after {max_wait}s")
return None
print(f"⧗ Backup in progress... ({int(elapsed)}s)")
time.sleep(5)
# Usage
backup = client.backups.create(BackupCreate(
backup_type="site_template",
trigger="manual"
))
completed_backup = monitor_backup_status(backup.id)
Error Handling¶
from konigle.exceptions import ValidationError
def create_backup_safely(backup_data: BackupCreate) -> bool:
try:
backup = client.backups.create(backup_data)
print(f"Successfully created backup: {backup.id}")
return True
except ValidationError as e:
print(f"Validation failed: {e}")
return False
except Exception as e:
print(f"Unexpected error: {e}")
return False
# Test backup creation
backup_data = BackupCreate(
backup_type="page",
target_id="page_123",
description="Test backup",
trigger="manual"
)
success = create_backup_safely(backup_data)
Best Practices¶
Organized Backup Descriptions¶
from datetime import datetime
def create_descriptive_backup(backup_type: str, target_id: str, reason: str):
"""Create backup with detailed description."""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M")
description = f"{reason} - {timestamp}"
backup = client.backups.create(BackupCreate(
backup_type=backup_type,
target_id=target_id,
description=description,
trigger="manual"
))
return backup
# Usage
backup = create_descriptive_backup(
"page",
"page_123",
"Before major redesign - removing old sections"
)
Backup Before Bulk Operations¶
def bulk_update_with_backup(page_ids: list, update_data: dict):
"""Backup all pages before bulk update."""
from konigle.models.website import PageUpdate
# Create backups first
backups = []
for page_id in page_ids:
backup = client.backups.create(BackupCreate(
backup_type="page",
target_id=page_id,
description="Before bulk update",
trigger="auto_pre_edit"
))
backups.append(backup)
print(f"Created {len(backups)} backups")
# Perform updates
updated_pages = []
for page_id in page_ids:
try:
page = client.pages.update(page_id, PageUpdate(**update_data))
updated_pages.append(page)
print(f"✓ Updated page: {page_id}")
except Exception as e:
print(f"✗ Failed to update {page_id}: {e}")
return updated_pages, backups
# Usage
page_ids = ["page_123", "page_456", "page_789"]
update_data = {"seo_meta": {"keywords": "new,keywords"}}
pages, backups = bulk_update_with_backup(page_ids, update_data)
Retention Policy¶
def cleanup_old_backups(keep_durable_days: int = 30,
keep_transient_days: int = 7):
"""Clean up old backups based on retention policy."""
from datetime import datetime, timedelta
now = datetime.now()
# Clean up old transient backups
transient_cutoff = now - timedelta(days=keep_transient_days)
transient_backups = client.backups.list(
kind="transient",
status="completed",
ordering="created_at"
)
transient_deleted = 0
for backup in transient_backups.payload:
if backup.created_at < transient_cutoff:
client.backups.delete(backup.id)
transient_deleted += 1
# Clean up old durable backups
durable_cutoff = now - timedelta(days=keep_durable_days)
durable_backups = client.backups.list(
kind="durable",
status="completed",
ordering="created_at"
)
durable_deleted = 0
for backup in durable_backups.payload:
if backup.created_at < durable_cutoff:
client.backups.delete(backup.id)
durable_deleted += 1
print(f"Deleted {transient_deleted} transient backups")
print(f"Deleted {durable_deleted} durable backups")
# Usage
cleanup_old_backups(keep_durable_days=30, keep_transient_days=7)