Skip to content

Bug in pydantic_form when the model is an instance and the model has an Enum. #72

Description

@pmareke

Checklist

  • I have searched the existing issues for similar issues.
  • I added a very descriptive title to this issue.
  • I have provided sufficient information below to help reproduce this issue.

Summary

First of all thanks for the library, I've been using it a lot and amazing!

The other day I found some bug when creating forms from classes that inherit from BaseModel.

The simplest, and working, solution it's the typical one:

from enum import Enum

import streamlit as st
import streamlit_pydantic as sp
from pydantic import BaseModel


class Status(Enum):
    PENDING = "pending"
    APPROVED = "approved"
    REJECTED = "rejected"


class ExampleModel(BaseModel):
    some_text: str
    some_number: int
    some_boolean: bool
    some_status: Status 

data = sp.pydantic_form(key=__name__, model=ExampleModel)
if data:
   st.json(data.model_dump())

Using the class, not the instance everything works as expected:

Image

But using this approach the form always has the same default values, so I need something more dynamic. In order to do that I pass an instance of the ExampleModel to the pydantic_form instead of the type:

from enum import Enum

import streamlit as st
import streamlit_pydantic as sp
from pydantic import BaseModel


class Status(Enum):
    PENDING = "pending"
    APPROVED = "approved"
    REJECTED = "rejected"


class ExampleModel(BaseModel):
    some_text: str
    some_number: int
    some_boolean: bool
    some_status: Status 

model = ExampleModel(
    some_text="Hello, World!",
    some_number=42,
    some_boolean=True,
    some_status=Status.PENDING,
 )
data = sp.pydantic_form(key=__name__, model=model)
if data:
   st.json(data.model_dump())

But something is not okay, as you can see the library complains about the Enum but the error is not true.:

Image

I also tried to use a Field with a default value:

from enum import Enum

import streamlit as st
import streamlit_pydantic as sp
from pydantic import BaseModel, Field


class Status(Enum):
    PENDING = "pending"
    APPROVED = "approved"
    REJECTED = "rejected"


class ExampleModel(BaseModel):
    some_text: str
    some_number: int
    some_boolean: bool
    some_status: Status  = Field(Status.PENDING)

model = ExampleModel(
    some_text="Hello, World!",
    some_number=42,
    some_boolean=True,
    some_status=Status.PENDING,
 )
data = sp.pydantic_form(key=__name__, model=model)
if data:
   st.json(data.model_dump())

But the field disappears:

Image

Fortunately there is a workaround in Pydantic that works perfectly!

In order to fix the error you need to use the use_enum_values config in the model and the form works as expected again:

from enum import Enum

import streamlit as st
import streamlit_pydantic as sp
from pydantic import BaseModel, Field


class Status(Enum):
    PENDING = "pending"
    APPROVED = "approved"
    REJECTED = "rejected"


class ExampleModel(BaseModel):
    model_config = ConfigDict(use_enum_values=True)

    some_text: str
    some_number: int
    some_boolean: bool
    some_status: Status

model = ExampleModel(
    some_text="Hello, World!",
    some_number=42,
    some_boolean=True,
    some_status=Status.PENDING,
 )
data = sp.pydantic_form(key=__name__, model=model)
if data:
   st.json(data.model_dump())

Reproducible Code Example

from enum import Enum

import streamlit as st
import streamlit_pydantic as sp
from pydantic import BaseModel, Field


class Status(Enum):
    PENDING = "pending"
    APPROVED = "approved"
    REJECTED = "rejected"


class ExampleModel(BaseModel):
    some_text: str
    some_number: int
    some_boolean: bool
    some_status: Status

model = ExampleModel(
    some_text="Hello, World!",
    some_number=42,
    some_boolean=True,
    some_status=Status.PENDING,
 )
data = sp.pydantic_form(key=__name__, model=model)
if data:
   st.json(data.model_dump())

Steps To Reproduce

Just run the script, you should see the error.

Expected Behavior

Render the form in the same way when you pass a class or an instance.

Current Behavior

The form is not properly made when the pydantic_form method receives an instance instead of a class.

Is this a regression?

  • Yes, this used to work in a previous version.

Debug info

  • streamlit-pydantic version:
  • Python version:

Additional Information

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions