From 13a9969885e7a7841e93c6bd5a898240fa7da35c Mon Sep 17 00:00:00 2001 From: sergue1 Date: Tue, 28 May 2024 17:25:58 +0200 Subject: [PATCH 1/2] Make bool form fields optional. --- demo/forms.py | 14 +++++----- src/python-fastui/fastui/json_schema.py | 3 ++- src/python-fastui/tests/test_forms.py | 34 +++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/demo/forms.py b/demo/forms.py index 886ae77e..94a88479 100644 --- a/demo/forms.py +++ b/demo/forms.py @@ -122,10 +122,12 @@ class ToolEnum(str, enum.Enum): class SelectForm(BaseModel): - select_single: ToolEnum = Field(title='Select Single') - select_multiple: list[ToolEnum] = Field(title='Select Multiple') - search_select_single: str = Field(json_schema_extra={'search_url': '/api/forms/search'}) - search_select_multiple: list[str] = Field(json_schema_extra={'search_url': '/api/forms/search'}) + human: bool = Field(title='Is human', description='Are you human?', json_schema_extra={'mode': 'switch'}) + is_foo: bool = Field(title='some check box') + # select_single: ToolEnum = Field(title='Select Single') + # select_multiple: list[ToolEnum] = Field(title='Select Multiple') + # search_select_single: str = Field(json_schema_extra={'search_url': '/api/forms/search'}) + # search_select_multiple: list[str] = Field(json_schema_extra={'search_url': '/api/forms/search'}) @router.post('/select', response_model=FastUI, response_model_exclude_none=True) @@ -151,9 +153,7 @@ class BigModel(BaseModel): None, description='Upload multiple images' ) dob: date = Field(title='Date of Birth', description='Your date of birth, this is required hence bold') - human: bool | None = Field( - None, title='Is human', description='Are you human?', json_schema_extra={'mode': 'switch'} - ) + human: bool = Field(title='Is human', description='Are you human?', json_schema_extra={'mode': 'switch'}) size: SizeModel position: tuple[ diff --git a/src/python-fastui/fastui/json_schema.py b/src/python-fastui/fastui/json_schema.py index 53ee526d..bb761ae8 100644 --- a/src/python-fastui/fastui/json_schema.py +++ b/src/python-fastui/fastui/json_schema.py @@ -154,7 +154,8 @@ def json_schema_obj_to_fields( required = set(schema.get('required', [])) if properties := schema.get('properties'): for key, value in properties.items(): - yield from json_schema_any_to_fields(value, loc + [key], title, key in required, defs) + is_bool = value.get('type') == 'boolean' + yield from json_schema_any_to_fields(value, loc + [key], title, key in required and not is_bool, defs) def json_schema_any_to_fields( diff --git a/src/python-fastui/tests/test_forms.py b/src/python-fastui/tests/test_forms.py index d73e3c10..4c937fff 100644 --- a/src/python-fastui/tests/test_forms.py +++ b/src/python-fastui/tests/test_forms.py @@ -522,3 +522,37 @@ def test_form_description_leakage(): 'submitUrl': '/foobar/', 'type': 'ModelForm', } + + +class FormFieldsBool(BaseModel): + human: bool = Field(title='Is human', description='Are you human?', json_schema_extra={'mode': 'switch'}) + is_foo: bool + + +def test_form_description_leakage(): + m = components.ModelForm(model=FormFieldsBool, submit_url='/foobar/') + + assert m.model_dump(by_alias=True, exclude_none=True) == { + 'formFields': [ + { + 'description': 'Are you human?', + 'locked': False, + 'mode': 'switch', + 'name': 'human', + 'required': False, + 'title': ['Is human'], + 'type': 'FormFieldBoolean', + }, + { + 'locked': False, + 'mode': 'checkbox', + 'name': 'is_foo', + 'required': False, + 'title': ['Is Foo'], + 'type': 'FormFieldBoolean', + }, + ], + 'method': 'POST', + 'submitUrl': '/foobar/', + 'type': 'ModelForm', + } From 915a2993b68bf853242ad82c539896135cdca40d Mon Sep 17 00:00:00 2001 From: sergue1 Date: Tue, 28 May 2024 17:31:03 +0200 Subject: [PATCH 2/2] revert demo form --- demo/forms.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/demo/forms.py b/demo/forms.py index 94a88479..e56d05af 100644 --- a/demo/forms.py +++ b/demo/forms.py @@ -122,12 +122,10 @@ class ToolEnum(str, enum.Enum): class SelectForm(BaseModel): - human: bool = Field(title='Is human', description='Are you human?', json_schema_extra={'mode': 'switch'}) - is_foo: bool = Field(title='some check box') - # select_single: ToolEnum = Field(title='Select Single') - # select_multiple: list[ToolEnum] = Field(title='Select Multiple') - # search_select_single: str = Field(json_schema_extra={'search_url': '/api/forms/search'}) - # search_select_multiple: list[str] = Field(json_schema_extra={'search_url': '/api/forms/search'}) + select_single: ToolEnum = Field(title='Select Single') + select_multiple: list[ToolEnum] = Field(title='Select Multiple') + search_select_single: str = Field(json_schema_extra={'search_url': '/api/forms/search'}) + search_select_multiple: list[str] = Field(json_schema_extra={'search_url': '/api/forms/search'}) @router.post('/select', response_model=FastUI, response_model_exclude_none=True)