#!/usr/bin/env python3 """ Example demonstrating SelectUI with Pydantic models. This shows how to use SelectItem for type safety and validation. """ import os import sys sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src')) from selectui import SelectItem, SelectUI def example_basic_pydantic(): """Basic usage with Pydantic models.""" print("Example 1: Basic Pydantic models\n", file=sys.stderr) items = [ SelectItem( title="Python", subtitle="High-level programming language", info="1991", data={"website": "python.org", "typing": "dynamic"} ), SelectItem( title="Rust", subtitle="Systems programming language", info="2010", data={"website": "rust-lang.org", "typing": "static"} ), SelectItem( title="Go", subtitle="Concurrent programming language", info="2009", data={"website": "go.dev", "typing": "static"} ), ] app = SelectUI(items=items, oneshot=True) app.run() return app.selected_item def example_validation(): """Demonstrate validation with Pydantic.""" print("Example 2: Pydantic validation\n", file=sys.stderr) items = [] # Valid item try: item = SelectItem(title="Valid Item", subtitle="This works") items.append(item) print("✓ Created valid item", file=sys.stderr) except Exception as e: print(f"✗ Error: {e}", file=sys.stderr) # Try to create item with empty title (will fail validation) try: item = SelectItem(title="", subtitle="Empty title") items.append(item) print("✓ Created item with empty title", file=sys.stderr) except Exception as e: print(f"✓ Validation caught empty title: {e}", file=sys.stderr) # Try to create item with whitespace-only title (will fail) try: item = SelectItem(title=" ", subtitle="Whitespace title") items.append(item) print("✓ Created item with whitespace title", file=sys.stderr) except Exception as e: print(f"✓ Validation caught whitespace title: {e}", file=sys.stderr) # Add more valid items items.extend([ SelectItem(title="Item 2", subtitle="Second item"), SelectItem(title="Item 3", subtitle="Third item"), ]) if items: app = SelectUI(items=items, oneshot=True) app.run() return app.selected_item return None def example_from_dict(): """Convert dictionaries to SelectItem with custom key mappings.""" print("Example 3: Converting from dicts with custom keys\n", file=sys.stderr) raw_data = [ {"name": "Alice", "role": "Engineer", "team": "Backend", "level": "Senior"}, {"name": "Bob", "role": "Designer", "team": "Product", "level": "Mid"}, {"name": "Charlie", "role": "Manager", "team": "Engineering", "level": "Staff"}, ] # Convert to SelectItem with custom key mappings items = [ SelectItem.from_dict( data, title_key="name", subtitle_key="role", info_key="team" ) for data in raw_data ] # Show what we got for item in items: print(f" {item.title} - {item.subtitle} [{item.info}]", file=sys.stderr) print(f" Full data: {item.data}", file=sys.stderr) print("", file=sys.stderr) app = SelectUI(items=items, oneshot=True) app.run() return app.selected_item def example_mixed_usage(): """Mix Pydantic models and dicts (automatically converted).""" print("Example 4: Mixed Pydantic and dict usage\n", file=sys.stderr) # Create some items as Pydantic models pydantic_items = [ SelectItem(title="Pydantic Item 1", subtitle="Type-safe item"), SelectItem(title="Pydantic Item 2", subtitle="Validated item"), ] # These will be automatically handled by SelectUI # Note: When using dicts, you need to pass them directly to SelectUI # SelectUI will handle both types app = SelectUI(items=pydantic_items, oneshot=True) app.run() return app.selected_item def example_custom_data(): """Use the data field for additional information.""" print("Example 5: Custom data field\n", file=sys.stderr) items = [ SelectItem( title="Config A", subtitle="Development configuration", data={ "path": "/etc/app/dev.conf", "environment": "dev", "port": 8000, "debug": True } ), SelectItem( title="Config B", subtitle="Production configuration", data={ "path": "/etc/app/prod.conf", "environment": "prod", "port": 80, "debug": False } ), ] app = SelectUI(items=items, oneshot=True) app.run() if app.selected_item: print("\nSelected configuration:", file=sys.stderr) print(f" Path: {app.selected_item.get('path')}", file=sys.stderr) print(f" Environment: {app.selected_item.get('environment')}", file=sys.stderr) print(f" Port: {app.selected_item.get('port')}", file=sys.stderr) print(f" Debug: {app.selected_item.get('debug')}", file=sys.stderr) return app.selected_item if __name__ == "__main__": examples = { "1": ("Basic Pydantic models", example_basic_pydantic), "2": ("Pydantic validation", example_validation), "3": ("Converting from dicts", example_from_dict), "4": ("Mixed usage", example_mixed_usage), "5": ("Custom data field", example_custom_data), } if len(sys.argv) < 2: print("Usage: python pydantic_example.py ", file=sys.stderr) print("\nAvailable examples:", file=sys.stderr) for num, (desc, _) in examples.items(): print(f" {num} - {desc}", file=sys.stderr) sys.exit(1) example_num = sys.argv[1] if example_num not in examples: print(f"Error: Example {example_num} not found", file=sys.stderr) sys.exit(1) desc, func = examples[example_num] result = func() if result: print(f"\n{'='*60}", file=sys.stderr) print("RESULT:", file=sys.stderr) import json print(json.dumps(result, indent=2), file=sys.stderr)