ensemble-tts-annotation / scripts /demo /create_demo_gif.py
marcosremar
Add visual demo and animated GIF walkthrough
5bc720b
#!/usr/bin/env python3
"""
Create animated demo showing GCP testing process.
Generates an animated GIF showing the step-by-step process.
"""
import os
from pathlib import Path
# Try to import PIL for image generation
try:
from PIL import Image, ImageDraw, ImageFont
import numpy as np
except ImportError:
print("Installing required packages...")
os.system("pip install -q Pillow numpy")
from PIL import Image, ImageDraw, ImageFont
import numpy as np
class TerminalFrame:
"""Generate terminal-style frames for GIF."""
def __init__(self, width=800, height=600):
self.width = width
self.height = height
self.bg_color = (40, 44, 52) # Dark background
self.text_color = (171, 178, 191) # Light gray
self.prompt_color = (97, 175, 239) # Blue
self.success_color = (152, 195, 121) # Green
self.highlight_color = (229, 192, 123) # Yellow
self.error_color = (224, 108, 117) # Red
# Try to use monospace font
try:
self.font = ImageFont.truetype("/System/Library/Fonts/Monaco.ttf", 14)
self.font_bold = ImageFont.truetype("/System/Library/Fonts/Monaco.ttf", 16)
except:
try:
self.font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf", 14)
self.font_bold = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf", 16)
except:
self.font = ImageFont.load_default()
self.font_bold = ImageFont.load_default()
def create_frame(self, lines, title="Google Cloud Shell"):
"""Create a terminal frame with given lines."""
img = Image.new('RGB', (self.width, self.height), self.bg_color)
draw = ImageDraw.Draw(img)
# Draw title bar
draw.rectangle([(0, 0), (self.width, 30)], fill=(30, 34, 42))
draw.text((10, 8), title, fill=self.text_color, font=self.font_bold)
# Draw terminal content
y_offset = 50
line_height = 20
for line in lines:
if isinstance(line, tuple):
text, color = line
else:
text = line
color = self.text_color
draw.text((10, y_offset), text, fill=color, font=self.font)
y_offset += line_height
return img
def create_demo_gif(output_path="demo.gif"):
"""Create animated GIF showing the testing process."""
terminal = TerminalFrame()
frames = []
duration_per_frame = 2000 # 2 seconds
# Frame 1: Opening Cloud Shell
frames.append(terminal.create_frame([
("=" * 80, terminal.text_color),
("STEP 1: Open Google Cloud Shell", terminal.highlight_color),
("=" * 80, terminal.text_color),
"",
("1. Go to: https://shell.cloud.google.com/", terminal.text_color),
"",
(" A terminal will open in your browser", terminal.text_color),
(" (Free tier, no installation needed!)", terminal.success_color),
"",
"",
("Press any key to continue...", terminal.prompt_color),
]))
# Frame 2: Download script
frames.append(terminal.create_frame([
("user@cloudshell:~ $", terminal.prompt_color),
"",
("STEP 2: Download the test script", terminal.highlight_color),
("=" * 80, terminal.text_color),
"",
("$ curl -O https://huggingface.co/marcosremar2/...", terminal.text_color),
(" ensemble-tts-annotation/raw/main/scripts/test/", terminal.text_color),
(" launch_gcp_spot.sh", terminal.text_color),
"",
(" % Total % Received % Xferd Average Speed", terminal.text_color),
("100 8432 100 8432 0 0 42160 0 --:--:-- --:--:--", terminal.text_color),
"",
("βœ“ Downloaded launch_gcp_spot.sh", terminal.success_color),
]))
# Frame 3: Make executable
frames.append(terminal.create_frame([
("user@cloudshell:~ $", terminal.prompt_color),
"",
("STEP 3: Make script executable", terminal.highlight_color),
("=" * 80, terminal.text_color),
"",
("$ chmod +x launch_gcp_spot.sh", terminal.text_color),
"",
("βœ“ Script is now executable", terminal.success_color),
"",
"",
("Next: Run the script", terminal.text_color),
]))
# Frame 4: Run script - Finding cheapest instance
frames.append(terminal.create_frame([
("user@cloudshell:~ $", terminal.prompt_color),
"",
("STEP 4: Run the script", terminal.highlight_color),
("=" * 80, terminal.text_color),
"",
("$ ./launch_gcp_spot.sh", terminal.text_color),
"",
("Finding cheapest spot instance...", terminal.text_color),
"",
(" e2-micro: $0.0025/hr", terminal.text_color),
(" e2-small: $0.005/hr", terminal.text_color),
(" e2-medium: $0.01/hr ← Selected", terminal.highlight_color),
(" e2-standard-2: $0.02/hr", terminal.text_color),
]))
# Frame 5: Creating instance
frames.append(terminal.create_frame([
("user@cloudshell:~ $", terminal.prompt_color),
"",
("Creating spot instance...", terminal.highlight_color),
("=" * 80, terminal.text_color),
"",
("Instance Type: e2-medium", terminal.text_color),
("Cost: ~$0.01/hr (spot/preemptible)", terminal.text_color),
("Zone: us-central1-a", terminal.text_color),
"",
("βœ“ Instance created: ensemble-test-1234567890", terminal.success_color),
("βœ“ External IP: 34.123.45.67", terminal.success_color),
"",
("Waiting for startup script to complete...", terminal.text_color),
]))
# Frame 6: Installing dependencies
frames.append(terminal.create_frame([
("Instance is running...", terminal.success_color),
"",
("Installing dependencies on instance:", terminal.highlight_color),
("=" * 80, terminal.text_color),
"",
("βœ“ apt-get update", terminal.success_color),
("βœ“ Installing python3-pip", terminal.success_color),
("βœ“ Installing git", terminal.success_color),
("βœ“ Cloning repository from HuggingFace", terminal.success_color),
("βœ“ Installing torch (CPU-only)", terminal.success_color),
("βœ“ Installing transformers, datasets, librosa...", terminal.success_color),
"",
("Running tests...", terminal.text_color),
]))
# Frame 7: Running tests
frames.append(terminal.create_frame([
("Running tests on instance...", terminal.highlight_color),
("=" * 80, terminal.text_color),
"",
("TEST: Imports", terminal.text_color),
(" Importing ensemble_tts...", terminal.text_color),
(" βœ“ Import successful", terminal.success_color),
"",
("TEST: Create Annotator", terminal.text_color),
(" Creating annotator in quick mode...", terminal.text_color),
(" βœ“ Annotator created successfully", terminal.success_color),
"",
("TEST: Model Structure", terminal.text_color),
(" βœ“ Model structure correct", terminal.success_color),
]))
# Frame 8: Test results
frames.append(terminal.create_frame([
("TEST SUMMARY", terminal.highlight_color),
("=" * 80, terminal.text_color),
"",
(" imports: βœ“ PASS", terminal.success_color),
(" create_annotator: βœ“ PASS", terminal.success_color),
(" model_structure: βœ“ PASS", terminal.success_color),
"",
("=" * 80, terminal.text_color),
("βœ“ ALL LOCAL TESTS PASSED!", terminal.success_color),
("=" * 80, terminal.text_color),
"",
("Time: 8.2 seconds", terminal.text_color),
("Cost: $0.002 (less than 1 cent!)", terminal.success_color),
]))
# Frame 9: Cleanup instructions
frames.append(terminal.create_frame([
("STEP 5: Clean up", terminal.highlight_color),
("=" * 80, terminal.text_color),
"",
("⚠️ Remember to delete the instance!", terminal.error_color),
"",
("Delete command:", terminal.text_color),
("$ gcloud compute instances delete ensemble-test-1234567890 \\", terminal.prompt_color),
(" --zone=us-central1-a --quiet", terminal.prompt_color),
"",
("Or via console:", terminal.text_color),
(" https://console.cloud.google.com/compute/instances", terminal.text_color),
(" β†’ Select instance β†’ DELETE", terminal.text_color),
"",
("βœ“ Instance deleted. No more charges.", terminal.success_color),
]))
# Frame 10: Summary
frames.append(terminal.create_frame([
("COMPLETE! βœ“", terminal.success_color),
("=" * 80, terminal.text_color),
"",
("What we did:", terminal.highlight_color),
(" 1. Opened Google Cloud Shell (free)", terminal.text_color),
(" 2. Downloaded test script (1 command)", terminal.text_color),
(" 3. Launched e2-medium spot instance", terminal.text_color),
(" 4. Installed OPTION A ensemble system", terminal.text_color),
(" 5. Ran validation tests", terminal.text_color),
(" 6. All tests passed! βœ“", terminal.success_color),
(" 7. Deleted instance", terminal.text_color),
"",
("Total cost: $0.002 (less than 1 cent!)", terminal.success_color),
("Total time: ~5 minutes", terminal.text_color),
"",
("System is ready for production! πŸš€", terminal.highlight_color),
]))
# Save as GIF
print(f"Creating animated GIF with {len(frames)} frames...")
frames[0].save(
output_path,
save_all=True,
append_images=frames[1:],
duration=duration_per_frame,
loop=0
)
print(f"βœ“ Saved to: {output_path}")
# Also save individual frames for debugging
frames_dir = Path(output_path).parent / "frames"
frames_dir.mkdir(exist_ok=True)
for i, frame in enumerate(frames):
frame.save(frames_dir / f"frame_{i:02d}.png")
print(f"βœ“ Individual frames saved to: {frames_dir}")
return output_path
def main():
"""Main function."""
print("=" * 60)
print("GCP Testing Demo - Animated GIF Generator")
print("=" * 60)
print()
output_dir = Path("demos")
output_dir.mkdir(exist_ok=True)
output_path = output_dir / "gcp_testing_demo.gif"
gif_path = create_demo_gif(str(output_path))
print()
print("=" * 60)
print("βœ“ Demo GIF created successfully!")
print("=" * 60)
print()
print(f"Location: {gif_path}")
print(f"Size: {os.path.getsize(gif_path) / 1024:.1f} KB")
print()
print("You can:")
print(" 1. Open it in a browser")
print(" 2. Add to README.md")
print(" 3. Share in documentation")
print()
if __name__ == "__main__":
main()