Skip to content

JustinCBates/TUI_Form_Designer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

29 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

TUI Form Designer

Create beautiful, interactive command-line forms and configuration wizards using YAML flow definitions.

🚨 CRITICAL ISSUE ALERT

⚠️ PRODUCTION SAFETY WARNING: There is a critical signal handling issue that prevents users from exiting applications normally (Ctrl+C doesn't work). READ CRITICAL-SIGNAL-HANDLING-ISSUE.md BEFORE USING IN PRODUCTION.

Status: Documented with workarounds available. Fix is Priority 0 in backlog.

πŸ“¦ Dual Package Architecture

TUI Form Designer is split into two packages for optimal deployment flexibility:

πŸ”§ TUI Form Engine (Production Runtime)

  • Lightweight runtime for executing flows in production
  • Minimal dependencies - only questionary, pyyaml, pydantic
  • Fast startup and stable API
  • Perfect for production environments
pip install tui-form-engine

🎨 TUI Form Editor (Development Tools)

  • Complete development toolkit for creating and managing flows
  • Interactive designer, testing framework, validation tools
  • CLI interface with comprehensive commands
  • Perfect for development environments
pip install tui-form-editor  # Includes tui-form-engine

🎯 When to Use Which Package

Environment Package Use Case
Production tui-form-engine Running flows in deployed applications
Development tui-form-editor Creating, testing, and managing flows
CI/CD tui-form-editor Validation and testing in pipelines
Docker tui-form-engine Minimal container size for runtime

Python License PyPI

✨ Features

  • πŸ“‹ YAML-Defined Forms: Define interactive workflows in human-readable YAML
  • 🎨 Interactive Designer: Visual form creation using Questionary itself
  • πŸ” Comprehensive Validation: Syntax and logic validation with detailed error reporting
  • πŸ§ͺ Testing Framework: Automated testing with mock responses
  • ⚑ CLI Tools: Complete command-line toolkit for form management
  • 🎭 Theming Support: Multiple built-in themes and custom styling
  • πŸ”„ Conditional Logic: Advanced branching and conditional questions
  • πŸ“Š Real-time Validation: Input validation with immediate feedback
  • πŸ—‚οΈ Output Mapping: Transform responses to structured data
  • πŸš€ Easy Integration: Simple Python API for embedding in applications
  • 🎯 Rich UI Elements: 7 step types including text, select, multiselect, confirm, password, info, and computed
  • πŸ”’ Advanced Input Handling: Built-in validators, pattern matching, and custom error messages

πŸš€ Quick Start

Installation

pip install tui-form-designer

Basic Usage

# Interactive mode - explore all tools
tui-designer

# Create a new form interactively
tui-designer design

# Preview existing forms
tui-designer preview --list

# Validate form definitions
tui-designer validate

# Test forms with mock data
tui-designer test --interactive

# Run demo with examples
tui-designer demo

Python API

from tui_form_designer import FlowEngine

# Initialize the engine
engine = FlowEngine(flows_dir="my_tui_layouts")

# Execute a form
results = engine.execute_flow("user_registration")
print(f"User: {results['username']}")

# Execute with mock responses for testing
mock_data = {"username": "testuser", "email": "test@example.com"}
results = engine.execute_flow("user_registration", mock_responses=mock_data)

πŸ“– Example Flow

Create beautiful forms with simple YAML:

layout_id: "user_survey"
title: "User Satisfaction Survey"
description: "Quick survey to gather user feedback"
icon: "πŸ“‹"

steps:
  - id: "user_name"
    type: "text"
    message: "What's your name?"
    validate: "required"
    
  - id: "satisfaction"
    type: "select"
    message: "How satisfied are you with our service?"
    choices:
      - "😍 Very Satisfied"
      - "😊 Satisfied"
      - "😐 Neutral"
      - "😞 Dissatisfied"
      - "😑 Very Dissatisfied"
    
  - id: "feedback"
    type: "text"
    message: "Any additional feedback?"
    instruction: "Your thoughts help us improve"
    
  - id: "recommend"
    type: "confirm"
    message: "Would you recommend us to others?"
    default: true

output_mapping:
  user:
    name: "user_name"
    satisfaction: "satisfaction"
    feedback: "feedback"
    would_recommend: "recommend"

This creates an interactive form that looks like:

πŸ“‹ User Satisfaction Survey
   Quick survey to gather user feedback
────────────────────────────────────────

? What's your name? John Doe
? How satisfied are you with our service? 😊 Satisfied
? Any additional feedback? Great service, very helpful!
? Would you recommend us to others? Yes

βœ… Flow execution completed!

🎯 Use Cases

Perfect for:

  • πŸ”§ Application Configuration: Interactive setup wizards for complex applications
  • πŸš€ Deployment Workflows: Guided deployment configuration and environment setup
  • πŸ‘€ User Onboarding: Step-by-step user registration and profile creation
  • πŸ“‹ Surveys & Forms: Dynamic questionnaires with conditional logic
  • πŸ› οΈ Development Tools: Interactive code generators and project scaffolding
  • βš™οΈ System Administration: Server configuration and maintenance workflows
  • πŸ“Š Data Collection: Research surveys and feedback collection

πŸ› οΈ Available Tools

🎨 Design Tool

Create and edit forms interactively:

tui-designer design

πŸ” Validation Tool

Validate form syntax and logic:

tui-designer validate                # Validate all flows
tui-designer validate my_form.yml   # Validate specific form

πŸ§ͺ Testing Tool

Test forms with mock responses:

tui-designer test --flow user_survey
tui-designer test --flow user_survey --mock-data test_responses.json

πŸ‘οΈ Preview Tool

Preview form structure without execution:

tui-designer preview --list          # List all forms
tui-designer preview --flow my_form  # Preview specific form

πŸ“ Step Types

Text Input

- id: "username"
  type: "text"
  message: "Enter username:"
  validate: "required"
  default: "user123"
  instruction: "Must be unique"

Single Selection

- id: "theme"
  type: "select"
  message: "Choose a theme:"
  choices:
    - "Light"
    - "Dark"
    - "Auto"
  default: "Auto"

Multiple Selection

- id: "features"
  type: "multiselect"
  message: "Select features to enable:"
  choices:
    - "Email notifications"
    - "File attachments"
    - "Advanced reporting"
    - "API access"
  defaults: ["Email notifications"]
  instruction: "Use space to select, enter to confirm"

Confirmation

- id: "agree_terms"
  type: "confirm"
  message: "Agree to terms?"
  default: false
  instruction: "Required to proceed"

Password Input

- id: "password"
  type: "password"
  message: "Enter password:"
  validate: "password_length"
  instruction: "At least 8 characters"

Information Display

- id: "welcome"
  type: "info"
  title: "Welcome to Setup"
  message: |
    This wizard will guide you through configuration.
    All settings can be changed later if needed.
  instruction: "Press Enter to continue"

Computed Values

- id: "secret_key"
  type: "computed"
  compute: "discovered_data.environment.SECRET_KEY_BASE"
  when: "secret_key_generation == false"
  description: "Auto-generated from environment variables"

πŸ”§ Advanced Features

Conditional Logic

Show/hide steps based on previous answers:

- id: "enable_email"
  type: "confirm"
  message: "Enable email notifications?"
  
- id: "smtp_host"
  type: "text"
  message: "SMTP host:"
  condition: "enable_email == true"  # Only show if email enabled

Input Validation

Built-in validators for common patterns:

- id: "email"
  type: "text"
  message: "Email address:"
  validate: "email"           # Built-in email validation
  error_message: "Please enter a valid email address"
  
- id: "port"
  type: "text" 
  message: "Port number:"
  validate: "integer"         # Must be a valid integer
  
- id: "project_name"
  type: "text"
  message: "Project name:"
  validate: "required"        # Field cannot be empty
  pattern: "^[a-zA-Z][a-zA-Z0-9_-]*$"
  error_message: "Must start with letter, contain only letters, numbers, underscores, and hyphens"

Available validators:

  • required - Field cannot be empty
  • email - Valid email address format
  • domain - Valid domain name format
  • integer - Must be a valid integer
  • password_length - Minimum password length (default 8 characters)

Advanced Choice Formats

Enhanced choice definitions with labels and values:

- id: "smtp_port"
  type: "select"
  message: "SMTP port:"
  choices:
    - name: "587 (STARTTLS - Recommended)"
      value: "587"
    - name: "465 (SSL/TLS)"
      value: "465"
    - name: "25 (Unencrypted - Not recommended)"
      value: "25"
  default: "587"
  instruction: "Choose based on your email provider's settings"

Output Mapping

Transform flat responses to structured data:

steps:
  - id: "db_host"
    type: "text"
    message: "Database host:"
    
  - id: "db_port" 
    type: "text"
    message: "Database port:"

output_mapping:
  database:
    host: "db_host"      # Nested structure
    port: "db_port"
  # Results in: {"database": {"host": "localhost", "port": "5432"}}

Custom Themes

Choose from built-in themes or create custom styling:

from tui_form_designer import FlowEngine
from questionary import Style

# Built-in themes
engine = FlowEngine(theme="dark")     # dark, minimal, default

# Custom styling
custom_style = Style([
    ('question', 'bold cyan'),
    ('answer', 'bold green'),
    ('pointer', 'bold magenta')
])
engine = FlowEngine(style=custom_style)

πŸ“‚ Project Structure

tui_layouts/
β”œβ”€β”€ basic/              # Simple example flows
β”‚   β”œβ”€β”€ simple_survey.yml
β”‚   └── user_registration.yml
β”œβ”€β”€ advanced/           # Complex multi-step flows  
β”‚   β”œβ”€β”€ application_setup.yml
β”‚   └── docker_deployment.yml
└── templates/          # Reusable flow templates
    └── openproject_main_config.yml

πŸ§ͺ Testing Flows

Interactive Testing

tui-designer test --interactive

Mock Response Testing

Create a JSON file with test responses:

{
  "username": "testuser",
  "email": "test@example.com", 
  "account_type": "Premium",
  "agree_terms": true
}

Then test with mocked responses:

tui-designer test --flow registration --mock-data test_responses.json

Generate Mock Templates

Automatically generate mock response templates:

# This creates registration_mock_template.json
tui-designer test
# Select "Generate mock template" option

πŸ“‹ Complete Step Type Reference

Step Type Properties

All step types support these common properties:

Property Required Description Example
id βœ… Unique step identifier "username"
type βœ… Step type "text", "select", etc.
condition ❌ When to show this step "enable_email == true"
instruction ❌ Help text below question "Must be unique"

Text Input (text)

Required properties: id, type, message

- id: "project_name"
  type: "text"
  message: "Project name:"
  default: "my-project"              # Default value
  instruction: "Used for containers"  # Help text
  validate: "required"               # Validation rule
  pattern: "^[a-zA-Z][a-zA-Z0-9_-]*$"  # Regex pattern
  error_message: "Invalid format"    # Custom error message
  min_length: 3                      # Minimum length
  max_length: 50                     # Maximum length

Single Selection (select)

Required properties: id, type, message, choices

- id: "environment"
  type: "select"
  message: "Environment:"
  choices:
    - "Development"
    - "Staging"
    - "Production"
  default: "Development"
  instruction: "Choose deployment target"

# Advanced format with labels and values
- id: "database_port"
  type: "select"
  message: "Database port:"
  choices:
    - name: "5432 (PostgreSQL default)"
      value: "5432"
    - name: "3306 (MySQL default)"
      value: "3306"
  default: "5432"

Multiple Selection (multiselect)

Required properties: id, type, message, choices

- id: "features"
  type: "multiselect"
  message: "Enable features:"
  choices:
    - "Email notifications"
    - "File attachments"
    - "API access"
    - "Advanced reporting"
  defaults: ["Email notifications"]   # Pre-selected items
  instruction: "Space to select, Enter to confirm"
  min_selections: 1                  # Minimum required
  max_selections: 3                  # Maximum allowed

Confirmation (confirm)

Required properties: id, type, message

- id: "enable_ssl"
  type: "confirm"
  message: "Enable SSL?"
  default: true                      # Default choice
  instruction: "Recommended for production"

Password Input (password)

Required properties: id, type, message

- id: "admin_password"
  type: "password"
  message: "Admin password:"
  validate: "password_length"        # Built-in validator
  min_length: 8                      # Minimum length
  instruction: "At least 8 characters"
  confirm: true                      # Ask for confirmation

Information Display (info)

Required properties: id, type

- id: "welcome_message"
  type: "info"
  title: "Welcome to Setup"          # Header title
  message: |                         # Multi-line message
    This wizard will configure your application.
    
    All settings can be changed later.
  instruction: "Press Enter to continue"

Computed Values (computed)

Required properties: id, type, compute

- id: "generated_secret"
  type: "computed"
  compute: "secrets.token_hex(32)"   # Python expression
  when: "manual_secret == false"    # Condition for computation
  description: "Auto-generated secret key"

# Using discovered data
- id: "detected_port"
  type: "computed"
  compute: "discovered_data.system.available_ports[0]"
  fallback: "8080"                   # Default if computation fails

Validation Rules

Validator Description Example
required Field cannot be empty validate: "required"
email Valid email format validate: "email"
domain Valid domain name validate: "domain"
integer Must be integer validate: "integer"
password_length Min 8 characters validate: "password_length"

Conditional Logic

Show/hide steps based on previous answers:

# Simple condition
condition: "enable_email == true"

# Complex conditions
condition: "environment == 'Production' and ssl_enabled == true"

# Multiple value check
condition: "database_type in ['postgresql', 'mysql']"

🐍 Python Integration

Basic Integration

from tui_form_designer import FlowEngine

def setup_application():
    engine = FlowEngine(flows_dir="config_tui_layouts")
    config = engine.execute_flow("app_setup")
    
    # Use the configuration
    database_url = config['database']['url']
    debug_mode = config['application']['debug']
    return config

Custom Validation

import questionary
from tui_form_designer import FlowEngine

def custom_validator(value):
    if len(value) < 3:
        raise questionary.ValidationError("Too short!")
    return True

engine = FlowEngine()
engine.validators['custom'] = custom_validator

Error Handling

from tui_form_designer import FlowEngine, FlowValidationError, FlowExecutionError

try:
    engine = FlowEngine()
    results = engine.execute_flow("my_flow")
except FlowValidationError as e:
    print(f"Flow validation failed: {e}")
except FlowExecutionError as e:
    print(f"Flow execution failed: {e}")

🎨 Styling & Themes

Built-in Themes

Default Theme (Blue/Orange):

engine = FlowEngine(theme="default")

Dark Theme (Cyan/Green):

engine = FlowEngine(theme="dark")  

Minimal Theme (No colors):

engine = FlowEngine(theme="minimal")

Custom Styling

from questionary import Style

custom_style = Style([
    ('question', 'bold blue'),
    ('answer', 'fg:#ff9d00 bold'),
    ('pointer', 'fg:#673ab7 bold'),
    ('highlighted', 'fg:#673ab7 bold'),
    ('selected', 'fg:#cc5454'),
    ('instruction', 'italic'),
])

engine = FlowEngine(style=custom_style)

πŸš€ Examples

The package includes several example flows:

  • simple_survey: Basic user satisfaction survey
  • user_registration: Complete user account creation
  • application_setup: Complex app configuration with database, email, etc.
  • docker_deployment: Docker container configuration
  • openproject_main_config: Full OpenProject deployment setup

Try them out:

tui-designer demo

🀝 Contributing

Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.

Development Setup

git clone https://github.com/JustinCBates/TUI_Form_Designer.git
cd TUI_Form_Designer
pip install -e .[dev]

Running Tests

pytest

Code Formatting

black src/ tests/
isort src/ tests/

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • Built on the excellent Questionary library
  • Originally developed as part of the OpenProject configuration management system
  • Inspired by the need for better terminal user interfaces in DevOps and system administration tools

πŸ“Š Project Stats

  • Language: Python 3.8+
  • Dependencies: Questionary, PyYAML, Pydantic
  • UI Elements: 7 step types with advanced validation
  • Validators: 5 built-in validators + custom support
  • Size: Lightweight (~50KB)
  • Type: CLI Tool + Python Library
  • Status: Production Ready

Made with ❀️ for the terminal UI community

About

A general purpose designer to lay out a rich terminal interactive form input.

Resources

License

Stars

Watchers

Forks

Packages

No packages published