Saved Objects Management Example¶
File: examples/saved_objects_management.py
Comprehensive example demonstrating all saved objects operations with production-ready patterns.
Overview¶
This example shows:
Creating objects with auto-generated and custom IDs
Retrieving and updating objects
Version control and optimistic concurrency
Space-scoped operations
Error handling
Key Features¶
SavedObjectsManager Class¶
class SavedObjectsManager:
"""Manager class for saved objects operations."""
def __init__(self, client):
self.client = client
self.created_objects = [] # Track for cleanup
Create Visualization¶
def create_visualization(self, title, obj_id=None, space_id=None):
"""Create a visualization saved object."""
attributes = {
"title": title,
"visState": json.dumps({"type": "line", "params": {}}),
"uiStateJSON": "{}",
"description": f"Visualization created via API: {title}",
"version": 1,
"kibanaSavedObjectMeta": {
"searchSourceJSON": json.dumps({"query": "", "filter": []})
},
}
response = client.saved_objects.create(
type="visualization",
attributes=attributes,
id=obj_id,
space_id=space_id,
)
saved_object = response.body
self.created_objects.append((saved_object["type"], saved_object["id"], space_id))
return saved_object
What the Example Demonstrates¶
Create with auto-generated ID
Create with specific ID
Retrieve objects
Update without version (simple update)
Update with version (optimistic concurrency)
Demonstrate version conflict
Delete object
Verify deletion
Space-scoped operations (optional)
Running the Example¶
python examples/saved_objects_management.py
Expected Output¶
================================================================================
SAVED OBJECTS MANAGEMENT DEMO
================================================================================
================================================================================
1. CREATE WITH AUTO-GENERATED ID
================================================================================
📝 Creating visualization: Auto-Generated ID Visualization
✓ Created: abc123-def456
================================================================================
2. CREATE WITH SPECIFIC ID
================================================================================
📝 Creating visualization: Custom ID Visualization
✓ Created: custom-viz-12345678
================================================================================
3. RETRIEVE OBJECTS
================================================================================
🔍 Retrieving visualization: abc123-def456
✓ Retrieved: Auto-Generated ID Visualization
Version: WzEsMV0=
🔍 Retrieving visualization: custom-viz-12345678
✓ Retrieved: Custom ID Visualization
Version: WzEsMV0=
================================================================================
4. UPDATE WITHOUT VERSION
================================================================================
✏️ Updating visualization: abc123-def456
✓ Updated: Updated Auto-Generated Visualization
New version: WzIsMV0=
================================================================================
5. UPDATE WITH VERSION (OPTIMISTIC CONCURRENCY)
================================================================================
🔍 Retrieving visualization: custom-viz-12345678
✓ Retrieved: Custom ID Visualization
Version: WzEsMV0=
✏️ Updating visualization: custom-viz-12345678
✓ Updated: Updated Custom Visualization
New version: WzIsMV0=
================================================================================
6. DEMONSTRATE VERSION CONFLICT
================================================================================
Attempting update with old version...
✓ Conflict detected as expected
================================================================================
7. DELETE OBJECT
================================================================================
🗑️ Deleting visualization: abc123-def456
✓ Deleted: abc123-def456
================================================================================
8. VERIFY DELETION
================================================================================
Attempting to retrieve deleted object...
✓ Object not found as expected
================================================================================
9. SPACE-SCOPED OPERATIONS (OPTIONAL)
================================================================================
Creating a test space...
✓ Created space: test-space-12345678
📝 Creating visualization: Space-Scoped Visualization
✓ Created: xyz789-abc123
Space: test-space-12345678
🔍 Retrieving visualization: xyz789-abc123
✓ Retrieved: Space-Scoped Visualization
Verifying object is not in default space...
✓ Object not found in default space (as expected)
Cleaning up test space...
✓ Deleted space: test-space-12345678
================================================================================
DEMO COMPLETE
================================================================================
🎉 All operations completed successfully!
2 object(s) were created during this demo.
Delete all created objects? (y/N):
Production Patterns¶
Pattern 1: Object Factory¶
class SavedObjectFactory:
@staticmethod
def create_visualization(title, vis_type="line"):
return {
"title": title,
"visState": json.dumps({"type": vis_type, "params": {}}),
"uiStateJSON": "{}",
"description": f"{title} visualization",
"version": 1,
"kibanaSavedObjectMeta": {"searchSourceJSON": "{}"}
}
Pattern 2: Bulk Operations¶
def create_multiple_visualizations(titles):
"""Create multiple visualizations efficiently."""
created = []
for title in titles:
try:
viz = manager.create_visualization(title)
created.append(viz)
except Exception as e:
logger.error(f"Failed to create {title}: {e}")
return created
Pattern 3: Safe Updates¶
def safe_update(obj_type, obj_id, new_attributes, max_retries=3):
"""Update with automatic retry on version conflict."""
for attempt in range(max_retries):
try:
current = client.saved_objects.get(type=obj_type, id=obj_id)
return client.saved_objects.update(
type=obj_type,
id=obj_id,
attributes=new_attributes,
version=current.body["version"]
)
except ConflictError:
if attempt == max_retries - 1:
raise
time.sleep(0.1 * (2 ** attempt))
Best Practices¶
Track created objects for cleanup
Use versions for updates
Handle conflicts gracefully
Validate attributes before creation
Clean up test objects