xbot-form 0.4.0
Windows-only Python SDK for rendering JSON Schema forms in WebView2
License: MIT
Requires Python: <4.0,>=3.7
Keywords: webview, form, json-schema, windows, gui, rpa

# XBot Form

[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Windows](https://img.shields.io/badge/platform-Windows-lightgrey.svg)](https://www.microsoft.com/windows)

Windows-only Python SDK for rendering JSON Schema forms in WebView2.

## Features

- 🎨 **JSON Schema Forms** - Render dynamic forms from JSON Schema definitions
- 🖥️ **Native Windows UI** - Uses WebView2 for modern, native-feeling interfaces
- 🎯 **Type-Safe API** - Configuration classes with IDE autocompletion support
- 🔗 **Fluent Builder** - Chainable API for easy form configuration
- 🌙 **Theme Support** - Light and dark mode themes
- 🪟 **Frameless Windows** - Optional borderless windows with rounded corners
- ⏱️ **Timeout Support** - Auto-submit forms after specified duration
- 📝 **Pre-fill Data** - Initialize forms with default values

## Installation

```bash
pip install xbot-form
```

**Requirements:**
- Windows 10/11
- Python 3.8+
- WebView2 Runtime (usually pre-installed on Windows 10/11)

## Quick Start

### Basic Usage

```python
from xbot_form import show_form

# Define the JSON Schema
json_schema = {
    "type": "object",
    "title": "User Registration",  # <- This becomes the window title
    "properties": {
        "name": {"type": "string", "title": "Name"},
        "email": {"type": "string", "title": "Email", "format": "email"},
    },
    "required": ["name", "email"]
}

# Simple usage - window title auto-extracted from json_schema["title"]
result = show_form(json_schema=json_schema)
print(f"User submitted: {result}")

# With UI Schema for layout customization
ui_schema = {
    "ui:order": ["name", "email"],
    "email": {"ui:placeholder": "user@example.com"}
}
result = show_form(json_schema=schema, ui_schema=ui_schema)

# Pre-fill form with default values
result = show_form(
    json_schema=json_schema,
    form_data={"name": "John", "email": "john@example.com"}
)

# Auto-submit after 30 seconds timeout
result = show_form(json_schema=json_schema, timeout=30)
```

### Builder Pattern (Recommended)

```python
from xbot_form import form_builder, FormCancelledError

try:
    result = (
        form_builder()
        .json_schema({
            "type": "object",
            "properties": {
                "username": {"type": "string", "title": "Username"},
                "password": {"type": "string", "title": "Password"},
            }
        })
        .ui_schema({
            "password": {"ui:widget": "password"}
        })
        .form_data({
            "username": "admin"  # Pre-fill username
        })
        .title("Login")
        .size(600, 400)
        .frameless(corner_radius=16)
        .theme("dark")
        .timeout(120)  # Auto-submit after 2 minutes
        .show()
    )
    print(f"Login: {result}")
except FormCancelledError:
    print("Login cancelled")
```

### Configuration Classes

```python
from xbot_form import (
    show_form_with_config,
    FormConfig,
    WindowOptions,
    DisplayOptions,
    FormCancelledError
)

config = FormConfig(
    json_schema={
        "type": "object",
        "properties": {
            "task": {"type": "string", "title": "Task Name"},
            "priority": {
                "type": "string",
                "title": "Priority",
                "enum": ["Low", "Medium", "High"]
            }
        }
    },
    ui_schema={
        "ui:order": ["task", "priority"]
    },
    form_data={
        "priority": "Medium"  # Default value
    },
    window=WindowOptions(
        width=800,
        height=600,
        title="New Task",
        frameless=True,
        corner_radius=12
    ),
    display=DisplayOptions(
        theme="light",
        debug=False,
        timeout=60  # Auto-submit after 60 seconds
    )
)

try:
    result = show_form_with_config(config)
    print(f"Task created: {result}")
except FormCancelledError:
    print("Cancelled")
```

## UI Schema

UI Schema allows you to customize how form fields are rendered. Common options:

```python
ui_schema = {
    # Field order
    "ui:order": ["name", "email", "password"],

    # Password field
    "password": {
        "ui:widget": "password"
    },

    # Textarea for long text
    "description": {
        "ui:widget": "textarea",
        "ui:options": {
            "rows": 5
        }
    },

    # Placeholder text
    "email": {
        "ui:placeholder": "user@example.com"
    },

    # Help text
    "name": {
        "ui:help": "Enter your full name"
    },

    # Read-only field
    "id": {
        "ui:readonly": True
    },

    # Hidden field
    "internal": {
        "ui:widget": "hidden"
    }
}
```

## API Reference

### Functions

| Function                        | Description                                   |
| ------------------------------- | --------------------------------------------- |
| `show_form(...)`                | Display a form with individual parameters     |
| `show_form_with_config(config)` | Display a form using FormConfig object        |
| `form_builder()`                | Create a FormBuilder for fluent configuration |

### Configuration Classes

| Class            | Description                            |
| ---------------- | -------------------------------------- |
| `FormConfig`     | Complete form configuration            |
| `FormSchema`     | JSON Schema with optional UI schema    |
| `WindowOptions`  | Window size, title, frameless settings |
| `DisplayOptions` | Theme, debug mode, locale settings     |
| `FormBuilder`    | Fluent builder for form configuration  |

### Exceptions

| Exception                  | Description                       |
| -------------------------- | --------------------------------- |
| `XBotFormError`            | Base exception for all SDK errors |
| `FormCancelledError`       | User cancelled or closed the form |
| `FormTimeoutError`         | Form display timed out            |
| `WebViewError`             | WebView2 initialization error     |
| `WebViewNotAvailableError` | WebView2 runtime not installed    |
| `WindowError`              | Window creation error             |

## Parameters

### show_form()

| Parameter       | Type    | Default   | Description                                                      |
| --------------- | ------- | --------- | ---------------------------------------------------------------- |
| `schema`        | `dict`  | `None`    | JSON Schema for the form (supports `title` for window title)     |
| `ui_schema`     | `dict`  | `None`    | UI Schema for customizing form layout and widgets                |
| `form_data`     | `dict`  | `None`    | Initial form data to pre-fill the form fields                    |
| `title`         | `str`   | `None`    | Window title. Priority: `title` > `schema["title"]` > "应用配置" |
| `width`         | `int`   | `1000`    | Window width in pixels                                           |
| `height`        | `int`   | `800`     | Window height in pixels                                          |
| `frameless`     | `bool`  | `True`    | Borderless window mode                                           |
| `corner_radius` | `int`   | `32`      | Corner radius for frameless windows                              |
| `debug`         | `bool`  | `False`   | Enable DevTools and context menu                                 |
| `theme`         | `str`   | `"light"` | Color theme (`"light"` or `"dark"`)                              |
| `timeout`       | `float` | `None`    | Auto-submit timeout in seconds. `None` means no timeout          |

### FormConfig

| Parameter    | Type             | Default            | Description                             |
| ------------ | ---------------- | ------------------ | --------------------------------------- |
| `schema`     | `dict`           | Required           | JSON Schema for the form                |
| `ui_schema`  | `dict`           | `None`             | UI Schema for layout customization      |
| `form_data`  | `dict`           | `None`             | Initial form data                       |
| `window`     | `WindowOptions`  | `WindowOptions()`  | Window appearance options               |
| `display`    | `DisplayOptions` | `DisplayOptions()` | Display behavior options                |

### WindowOptions

| Parameter       | Type   | Default   | Description                        |
| --------------- | ------ | --------- | ---------------------------------- |
| `width`         | `int`  | `1000`    | Window width in pixels             |
| `height`        | `int`  | `800`     | Window height in pixels            |
| `title`         | `str`  | `None`    | Window title                       |
| `frameless`     | `bool` | `True`    | Borderless window mode             |
| `corner_radius` | `int`  | `32`      | Corner radius for frameless window |

### DisplayOptions

| Parameter | Type    | Default   | Description                             |
| --------- | ------- | --------- | --------------------------------------- |
| `debug`   | `bool`  | `False`   | Enable DevTools and context menu        |
| `theme`   | `str`   | `"light"` | Color theme (`"light"` or `"dark"`)     |
| `locale`  | `str`   | `"zh"`    | UI locale (e.g., `"zh"`, `"en"`)        |
| `timeout` | `float` | `None`    | Auto-submit timeout in seconds          |

## License

MIT License - see [LICENSE](LICENSE) for details.