Dash Pydantic Form
Dash-pydantic-form is a Python library that enables rapid creation of interactive forms within Plotly Dash applications, powered by Pydantic models. It leverages dash-mantine-components (DMC) for a rich set of input fields and seamlessly handles complex data structures like nested models and lists. The library is actively maintained, with frequent minor and patch releases, and is currently at version 0.18.3.
Warnings
- breaking The library explicitly requires Pydantic V2. Using Pydantic V1 will lead to incompatibility issues and errors.
- deprecated Directly passing `repr_type` and `repr_kwargs` to `pydantic.Field` is deprecated. For future compatibility, use `json_schema_extra={'repr_type': ..., 'repr_kwargs': ...}` for customizing input rendering.
- gotcha For versions 0.15.0 and above, when using list fields with accordion or modal titles, you might need to define the `__str__` method on your Pydantic models. This is due to performance improvements in `MATCH` callbacks setting `prevent_initial_call`, affecting how initial names are displayed.
- gotcha Conditional field visibility operates client-side and requires a specific 3-tuple format `(field, operator, value)`. Python lambda functions or direct Python logic for visibility conditions are not supported.
- gotcha Earlier versions (prior to 0.17.5) had known issues with multiple `ModelForm` instances on a single page causing update problems. While fixed, it's a complexity to be aware of in large applications.
Install
-
pip install dash-pydantic-form
Imports
- ModelForm
from dash_pydantic_form import ModelForm
- BaseModel, Field
from pydantic import BaseModel, Field
- Dash, html, callback, Input, Output
from dash import Dash, html, callback, Input, Output
Quickstart
import os
from datetime import date
from typing import Literal
from dash import Dash, html, callback, Input, Output
from dash_pydantic_form import ModelForm
from pydantic import BaseModel, Field, ValidationError
# Define a Pydantic model
class Employee(BaseModel):
first_name: str = Field(title="First name")
last_name: str = Field(title="Last name")
office: Literal["au", "uk", "us", "fr"] = Field(title="Office")
joined: date = Field(title="Employment date")
# Initialize the Dash app
app = Dash(__name__)
# Define the app layout
app.layout = html.Div([
html.H1("Employee Form"),
ModelForm(
Employee,
aio_id="employees_form_id",
form_id="new_employee_form"
),
html.Div(id="form-output")
])
# Define a callback to process form data
@callback(
Output("form-output", "children"),
Input(ModelForm.ids.main("employees_form_id", "new_employee_form"), "data")
)
def use_form_data(form_data: dict):
if form_data is None:
return html.Pre("Waiting for form data...")
try:
employee = Employee(**form_data)
return html.Pre(f"Validated Employee: {employee.model_dump_json(indent=2)}")
except ValidationError as exc:
return html.Pre(f"Validation Error:\n{exc.errors()}\nRaw Data: {form_data}", style={'color': 'red'})
if __name__ == '__main__':
app.run(debug=True)