streamlit-pydantic
streamlit-pydantic copied to clipboard
Expander for long Forms / inputs
Hey @LukasMasuch , @HIL340 ,
just a simple feature request: is it somehow possible to have (for long forms) expanders as option for the input? So one would somehow need to define the upper most level (in case of nested BaseModels) and enable expanders between each nested model. For example here:
class Address(BaseModel):
street: str
city: str
house: int
class GeneralData(BaseModel):
email: str
gender: bool
class ContactMethod(BaseModel):
text: str
Post: List[PostalAddress]
EmailAddress: List[GeneralData]
I would like to have an expander between Post and Email . Is that possible?
Best regards Chris
You may not be aware of it but a feature very close to this already exists.
Have a look at the "optional fields" demo in the playground.
Does it work for what your trying to achieve?
Hey @HIL340 ,
i actually checked this before i created the issue. In my case, it does not work.
I have a pydantic_input
which does not work with group_optional_fields="expander"
right?
Also in my ContactMethod
i have optional fields besides the Subclasses GeneralData
and Address
e.g. text
,
that is optional and therefore, it would also get expanded?
Adding something like sp.pydantic_input(group_optional_fields="subclasses")
would be the functionallity i am looking for!
You can group the inputs into an expander on a st.pydantic_input
(it doesn't have to be a st.pydantic_form
like the demo).
Translating the demo to a pydantic_input
version and using your data model:
import json
from typing import List, Optional
import streamlit as st
from pydantic import BaseModel
from pydantic.json import pydantic_encoder
import streamlit_pydantic as sp
class PostalAddress(BaseModel):
street: str
city: str
house: int
class GeneralData(BaseModel):
email: str
gender: bool
class ContactMethod(BaseModel):
text: str
Post: List[PostalAddress]
EmailAddress: Optional[List[GeneralData]]
data = sp.pydantic_input(
key="my_form", model=ContactMethod, group_optional_fields="expander"
)
if data:
st.json(json.dumps(data, default=pydantic_encoder))
Results in:
(after clicking Add Item
on each of the lists)
It does appear though that if you put the Optional
s on the subclass fields rather than the parent of the subclass it doesn't work.
eg.
class PostalAddress(BaseModel):
street: str
city: str
house: int
class GeneralData(BaseModel):
email: Optional[str]
gender: Optional[bool]
class ContactMethod(BaseModel):
text: str
Post: List[PostalAddress]
EmailAddress: List[GeneralData]
This is probably a mistake/bug but may actually work better for your purposes!
Exactly the latter is also the case with me.
Only that I have wrapped for safity reasons both on subclass level and the EmailAddress
with Optional.
In addition, I also initialize the whole thing via an instance. That means i get an error, as soon as one
field is not set, due to the fact, that field is not optional anymore.
Is this fixable, @HIL340 @LukasMasuch ?
Its very likely fixable.
Its not a feature I currently need for any of my projects right now so its a low priority for me at the moment.
If you have the motivation and specific expectations on how the feature should work the quickest way forward would be to code it up and submit a PR!