Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional[str] fields fail to render #50

Open
bruno-f-cruz opened this issue Dec 5, 2023 · 2 comments
Open

Optional[str] fields fail to render #50

bruno-f-cruz opened this issue Dec 5, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@bruno-f-cruz
Copy link

Describe the bug:

When attempting to run the provided test for optional fields:
https://github.com/LukasMasuch/streamlit-pydantic/blob/390a45aba7bf8caccc297c335715cc141db490af/examples/optional_fields.py

The library is not able to render anything with strings it seems like. This is also true for more complex classes. The library is able to render the text if the Optional typing is removed.

Expected behaviour:

The field should be rendered as any other string field.

Steps to reproduce the issue:

  1. Checkout the most recent commit 390a45a
  2. Install
  3. Run the optional_fields.py example provided in the repository

Technical details:

  • Windows
  • Chrome
@bruno-f-cruz bruno-f-cruz added the bug Something isn't working label Dec 5, 2023
@KirmTwinty
Copy link

This is True for any Optional field!
This is mainly because on an Optional field, the field can also be null, so something like:

  • {'anyOf': [{'type': '<type>'}, {'type': 'null'}]}
  • {'anyOf': [{'$ref': '<ref>'}, {'type': 'null'}]}

Therefore, we could filter the optional properties with only null types like:

def filter_nullable(property: Dict) -> Dict:
    # if it is optional and nullable, it may be
    # - {'anyOf': [{'type': '<type>'}, {'type': 'null'}]
    # - {'anyOf': [{'$ref': '<ref>'}, {'type': 'null'}]
    # we want to remove the "null" type
    union_prop = property.get("oneOf", property.get("anyOf"))
    if union_prop is not None:
        # Remove the null type, while keeping the `$ref` and other types
        where = [i for i,d in enumerate(union_prop) if d.get('type') == "null"]
        where.reverse()
        for i in where:
            del union_prop[i]
        if len(union_prop) == 1: # it is fine, we wrap the type to the original object
            for key in union_prop[0]:
                property[key] = union_prop[0][key]

            del property["anyOf"] # now we can delete the key

    return property

and in _render_property:

    def _render_property(self, streamlit_app: Any, key: str, property: Dict) -> Any:
        # filter the case of optional and nullable
        property = schema_utils.filter_nullable(property)

@MaxKasper
Copy link

Hi, is there any solution how to handle optional arguments?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants