Dash pydantic form

I’ve started a proper documentation website for this package: https://pydf-docs.onrender.com

Heavily bootstrapped from dmc-docs, thanks @snehilvj :saluting_face:

I will be adding more to the docs later on.

2 Likes

Thank you for adding docs to this package @RenaudLN .
I’m at PyCon 2024 in Pennsylvania currently, but when I’m back next week, I’ll upload this to the community component index.

2 Likes

The docs look great @RenaudLN! I like how you created prop definitions. I’ll take inspiration from this for dmc. I don’t like its current form.

4 Likes

Just also wanted to say that I love this!! Really cool stuff and will definitely check this out further! This might be really cool to add to Vizro as well (I am one of the devs there :stuck_out_tongue: )

Anyway, super cool!!

3 Likes

Wow, this is really a phenomenal package, amazing work @RenaudLN! :star: Thank you for making it available for everyone. Love the use of discriminated unions to make the form flexible, it’s very clever.

I’m just wondering what was your inspiration for this? It reminds me of a few different things and I’m curious whether you came across any of them before or had other packages that inspired you? e.g. I know of WTForms and FastUI from the authors of pydantic who actually have a model called exactly ModelForm in fact! Neither of these is tied to Dash though of course. You’ve done a really beautiful job combining a declarative form syntax with Dash :clap:

I’m also curious about a couple of design decisions:

  • representation of a form field is changed using ModelForm(fields_repr=...). Did you think about doing this within the Field itself, e.g. the Password field in this example might be done with something like class LoginData(BaseModel): password: str = Field(title="Password", description="Make it strong", min_length=6, repr=fields.Password())
  • for the visibility of a form field, you have a sort of mini-language like "visible": ("country", "==", "fr"). Did you think about doing this with visible = lambda form: form.country == "fr" or similar?
  • did you ever think about non-pydantic ways to declare a form? Something like in html - Wiki or Markdown-like syntax for simple forms? - Stack Overflow

Any further insight you can give would be very interesting! :slight_smile:

Oh, I should also say that like @maxschulz-COL I’m one of the developers of Vizro so very interested in pydantic + Dash :smiley:

1 Like

Hey @antony.milne glad you like the package! I haven’t really looked at what others are doing to be honest, it started small from some requirements at work and then it grew until it looked like it would be a good standalone package.

Regarding your questions:

  • I initially did this by subclassing pydantic’s Field for the different types of representations but this approach doesn’t do well in terms of separation of concerns. You need to define how the field is going to be represented in your form at the same time as what the data should look like. With the current approach, you can create 2 different forms for a same object depending on what context it needs to be displayed. You can also have a backend service that doesn’t need to have Dash dependencies etc.
  • For the visibility, it is all done client side so can’t really use Python syntax for it. The 3-tuple approach is pretty common in other libraries (e.g. Firestone, Odoo)
  • I’ll have a look, always keen for new ideas on how to develop this more :slight_smile:

And happy to explore how this could be used with Vizro if that’s something you’re interested in!

That’s interesting you developed it completely independently of those other packages. There’s so much closely related thinking across different packages here that it must be a good idea I think :smiley: (Similarly, FastUI also looks incredibly close to Vizro in many ways but they were developed completely independently of each other)

Thanks for all the answers, that all makes sense! When we come to developing our form components more on Vizro (it’s been on our roadmap for a while) I’ll let you know :slight_smile: Fundamentally what I’m interested in is some kind of easy declarative method for a relatively non-technical user to describe a form. One possibility is to write pydantic models like you do but another might be some kind of simplified form markup language like in that stackoverflow post. There’s going to be some kind of balance here between power vs. ease of use obviously. Please do keep this topic updated since I’d love to see where your package goes and any new ideas you have!

Edit: just for completeness, I’m sure you’re already aware of them but for anyone else reading, let me also note markdown2dash and dash-down which both parse markdown + directives into Dash components. They don’t have any form components built in but are both extensible so could probably be made to do so.

1 Like

Hi @RenaudLN ! Really awesome library, makes life much easier, so thanks a lot!
Just one question, what is the easiest/proposed way of resetting the values of the form elements ?

Thanks in advance!

Hey @Datenschubse, glad it’s useful :slight_smile: at this stage there isn’t a built-in way to do this. I would simply use a callback to update the children of the form parent with a new instance of ModelForm.

Alright sounds good, thank you very much for your fast response!

Hey all, just wanted to give an update on this project. Quite a few more features have been added:

  • More DMC inputs based on later DMC releases
  • Dict fields
  • Read-only mode for the form
  • Quantity field for value & unit data
  • Path field to explore local or bucket data (leveraging fsspec)
  • More input types in Table fields (date, time, datetime)
  • Possibility to change the base number of columns in the form
  • Strong focus on discriminated unions, they can be used for list of model union or as the base form model
  • Store/restore form data entry to/from local or session storage
  • Custom form layout flow

This last one allows to create very customisable forms like the example below:
pydf-tree-layout

This includes a few community contributions, thanks all!

7 Likes

@RenaudLN Fantastic work. Love being able to edit a pydantic model to revise a form input.

Preformatted textOne question, is it possible to set the col width on a single FormSection? Hoping to build 2 columns for most of the form but have one section that spans the width of the form for a large Textarea. I see you have a todo in the docs on this subject. So, apologies if this is premature.

Solved by setting the n_cols on each of the fields. It took me a minute to realize that needed to go inside the json_schema_extra={"repr_type": "Textarea", "repr_kwargs":{"n_cols": 1.0}}.

Looks fantastic.

Thanks for effort here.

Hi @RenaudLN ! I was just about to start writing a package for this but i’m glad i found yours first! This is a GAME CHANGER for us python dash developers, thanks so much.

5 Likes