Skip to content

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)