Form.from_model().
Basic Usage
AForm groups labeled inputs with a submit action. Named inputs automatically sync their values to client state, so {{ name }} always reflects the current value of Input(name="name"). Wrap in a Card for visual structure.
Building forms by hand gives full control over layout and behavior, but requires wiring up every label, input type, and argument template yourself. For models with many fields, Form.from_model() handles all of that automatically.
Generating Forms Automatically
Form.from_model() introspects a Pydantic model and generates a complete form — labels, typed inputs, validation constraints, and a submit button — from the model’s field definitions. Pass a CallTool as the submit action, and from_model() automatically wires up the arguments from the model’s fields so you don’t have to write {{ template }} expressions for every field.
Notice that the CallTool only specifies the tool name — no arguments. from_model() generates them automatically, wrapping each field as {{ field_name }} under a data key. It also adds a default error toast so validation failures are visible without any extra configuration.
Custom Layout
The turnkeyfrom_model() handles everything: the Form wrapper, the submit button, and the CallTool argument wiring. When you need more control — a Card with a footer, a cancel button, a title — pass fields_only=True to generate just the labeled inputs, and take over the rest.
With fields_only, three things that were automatic become your responsibility. You create the Form yourself and provide on_submit with explicit arguments (the turnkey version auto-generates these from the model, but fields_only doesn’t touch your CallTool). You add your own submit button wherever it belongs in the layout. And you handle spacing — wrap the fields in a Column(gap=4) since they’re no longer inside a Form that provides gap for you.
Compare this to the turnkey version above: the CallTool now has explicit arguments, the buttons are placed in CardFooter, and the fields are wrapped in Column(gap=4) for spacing. The model still defines all the labels, input types, and validation — fields_only just stops short of deciding how to lay them out.
Type Mapping
Each field’s Python type determines which input component is rendered. A field namedemail gets an email input automatically, a bool becomes a checkbox, number types get number inputs with constraints, and so on.
The full type mapping:
| Python type | Input component |
|---|---|
str | Text input (auto-detects email, password, tel, url from field name) |
int, float | Number input |
bool | Checkbox |
Literal["a", "b", "c"] | Select dropdown |
SecretStr | Password input |
datetime.date | Date picker |
datetime.time | Time picker |
datetime.datetime | Datetime picker |
Field Metadata
PydanticField() parameters control labels, placeholders, and HTML validation constraints. In this example, title sets the label, description sets the placeholder, min_length enforces a minimum, and the ui hint overrides the default text input with a textarea.
The full metadata mapping:
| Field metadata | Form effect |
|---|---|
Field(title="...") | Label text (fallback: humanized field name) |
Field(description="...") | Placeholder text |
Field(min_length=..., max_length=...) | HTML input constraints |
Field(ge=..., le=...) | Number input min/max |
Field(json_schema_extra={"ui": {"type": "textarea", "rows": 4}}) | Textarea override |
Field(exclude=True) | Skip field entirely |
Error Handling
Whenon_submit is a CallTool with no explicit on_error, from_model() adds a default error toast that displays the server’s error message. You can override it with your own feedback.
The $error variable captures the error message from a failed tool call. When no on_error is provided, from_model() adds ShowToast("{{ $error }}", variant="error") automatically.
Unsupported Types
from_model() skips fields with complex types that have no natural form input mapping: list, dict, set, tuple, and nested BaseModel instances. If you need these, build those parts of the form manually and handle the arguments yourself.
API Reference
Form.from_model() Parameters
Pydantic model class to generate the form from.
When
True, returns a list of field components without a Form wrapper or submit button. The fields auto-parent to the active context manager. Use this for custom layouts where you provide your own Form, button, and CallTool arguments.Text for the submit button. Ignored when
fields_only=True.Action(s) fired on submit. A
CallTool with no arguments gets auto-filled from model fields under a data key.Additional CSS classes on the form container.
Protocol Reference
Form