🪄 Auto-generate Streamlit UI from Pydantic Models and Dataclasses.

Overview

Streamlit Pydantic

Auto-generate Streamlit UI elements from Pydantic models.

Getting StartedDocumentationSupportReport a BugContributionChangelog

Streamlit-pydantic makes it easy to auto-generate UI elements from Pydantic models. Just define your data model and turn it into a full-fledged UI form. It supports data validation, nested models, and field limitations. Streamlit-pydantic can be easily integrated into any Streamlit app.

Beta Version: Only suggested for experimental usage.


Try out and explore various examples in our playground here.


Highlights

  • 🪄  Auto-generated UI elements from Pydantic models.
  • 📇   Out-of-the-box data validation.
  • 📑   Supports nested Pydantic models.
  • 📏   Supports field limits and customizations.
  • 🎈   Easy to integrate into any Streamlit app.

Getting Started

Installation

Requirements: Python 3.6+.

pip install streamlit-pydantic

Usage

  1. Create a script (my_script.py) with a Pydantic model and render it via pydantic_form:

    import streamlit as st
    from pydantic import BaseModel
    import streamlit_pydantic as sp
    
    class ExampleModel(BaseModel):
        some_text: str
        some_number: int
        some_boolean: bool
    
    data = sp.pydantic_form(key="my_form", input_class=ExampleModel)
    if data:
        st.json(data.json())
  2. Run the streamlit server on the python script: streamlit run my_script.py

  3. You can find additional examples in the examples section below.

Examples


👉   Try out and explore these examples in our playground here


The following collection of examples demonstrate how Streamlit Pydantic can be applied in more advanced scenarios. You can find additional - even more advanced - examples in the examples folder or in the playground.

Simple Form

import streamlit as st
from pydantic import BaseModel

import streamlit_pydantic as sp


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

data = sp.pydantic_form(key="my_form", input_class=ExampleModel)
if data:
    st.json(data.json())

Date Validation

import streamlit as st
from pydantic import BaseModel, Field, HttpUrl
from pydantic.color import Color

import streamlit_pydantic as sp


class ExampleModel(BaseModel):
    url: HttpUrl
    color: Color
    email: str = Field(..., max_length=100, regex=r"^\S+@\S+$")


data = sp.pydantic_form(key="my_form", input_class=ExampleModel)
if data:
    st.json(data.json())

Complex Nested Model

from enum import Enum
from typing import Set

import streamlit as st
from pydantic import BaseModel, Field, ValidationError, parse_obj_as

import streamlit_pydantic as sp


class OtherData(BaseModel):
    text: str
    integer: int


class SelectionValue(str, Enum):
    FOO = "foo"
    BAR = "bar"


class ExampleModel(BaseModel):
    long_text: str = Field(..., description="Unlimited text property")
    integer_in_range: int = Field(
        20,
        ge=10,
        lt=30,
        multiple_of=2,
        description="Number property with a limited range.",
    )
    single_selection: SelectionValue = Field(
        ..., description="Only select a single item from a set."
    )
    multi_selection: Set[SelectionValue] = Field(
        ..., description="Allows multiple items from a set."
    )
    single_object: OtherData = Field(
        ...,
        description="Another object embedded into this model.",
    )


data = sp.pydantic_form(key="my_form", input_class=ExampleModel)
if data:
    st.json(data.json())

Render Input

from pydantic import BaseModel

import streamlit_pydantic as sp


class ExampleModel(BaseModel):
    some_text: str
    some_number: int = 10  # Optional
    some_boolean: bool = True  # Option


input_data = sp.pydantic_input("model_input", ExampleModel, use_sidebar=True)

Render Output

import datetime

from pydantic import BaseModel, Field

import streamlit_pydantic as sp


class ExampleModel(BaseModel):
    text: str = Field(..., description="A text property")
    integer: int = Field(..., description="An integer property.")
    date: datetime.date = Field(..., description="A date.")


instance = ExampleModel(text="Some text", integer=40, date=datetime.date.today())
sp.pydantic_output(instance)

Custom Form

import streamlit as st
from pydantic import BaseModel

import streamlit_pydantic as sp


class ExampleModel(BaseModel):
    some_text: str
    some_number: int = 10
    some_boolean: bool = True


with st.form(key="pydantic_form"):
    sp.pydantic_input(key="my_input_model", input_class=ExampleModel)
    submit_button = st.form_submit_button(label="Submit")

Support & Feedback

Type Channel
🚨   Bug Reports
🎁   Feature Requests
👩‍💻   Usage Questions
📢   Announcements

Documentation

The API documentation can be found here. To generate UI elements, you can use the high-level pydantic_form method. Or the more flexible lower-level pydantic_input and pydantic_output methods. See the examples section on how to use those methods.

Limitations

TBD

Contribution

Development

To build the project and run the style/linter checks, execute:

pip install universal-build
python build.py --make --check

Refer to our contribution guides for more detailed information on our build scripts and development process.


Licensed MIT. Created and maintained with ❤️   by developers from Berlin.

Comments
  • Handle Collection Type fields

    Handle Collection Type fields

    Feature description: Correctly handle fields such as List[str]

    Curently when a field is of a collection type such as dict, list, Mapping, Sequence etc. the behaviour is broken. For the model

    class ExampleModel(BaseModel):
            text: str
            many_texts: Sequence[str]
    

    the output is broken image and pressing the submit button results in the following error Whoops! There were some problems with your input: many_texts: field required

    Problem and motivation:

    I have forms where some of the inputs are an arbitrary number of strings. Up until now I have solved this with a text_area widget, and prompt the user to separate their inputs with commas. Then with a custom validator the strings can be put back into a list. While this kinda works, it is a very hacky solution, it prevents me from using this package without breaking up my model

    Is this something you're interested in working on?

    Currently I don't have the capacity but it is something that am willing to look into in the near future (in a couple of months)

    Stale 
    opened by papalotis 8
  • Populate generated form values from a pydantic model instance

    Populate generated form values from a pydantic model instance

    What kind of change does this PR introduce?

    • [ ] Bugfix
    • [x] New Feature
    • [ ] Feature Improvement
    • [ ] Refactoring
    • [ ] Documentation
    • [ ] Other, please describe:

    Description:

    This PR adds the capability to provide a pydantic model instance to sp.pydantic_input() and have the generated pydantic widgets be pre-populated with the instance property values.

    This allows for full CRUD operations to be performed on pydantic data using streamlit.

    I've been tinkering with this and some other changes in my fork and have made good use of it in a couple of projects now and it would be nice to get it merged upstream.

    To demonstrate the functionality I've added two additional examples to the playground:

    • complex_instance_model.py: A full demo that shows all of the major widget types and the difference in behaviour between an empty pydantic schema vs a fully populated instance
    • union_field_instance.py: An example to demonstrate a union field using an instance with Discriminated Unions

    Checklist:

    • [x] I have read the CONTRIBUTING document.
    • [x] My changes don't require a change to the documentation, or if they do, I've added all required information.
    opened by HIL340 7
  • Add full support for readOnly, max_items, min_items and other schema properties within rendered collections

    Add full support for readOnly, max_items, min_items and other schema properties within rendered collections

    What kind of change does this PR introduce?

    • [ ] Bugfix
    • [ ] New Feature
    • [x] Feature Improvement
    • [x] Refactoring
    • [ ] Documentation
    • [ ] Other, please describe:

    Description:

    Hello again 😄

    From a user/dev perspective the changes introduced by this PR are:

    1. Support the readOnly pydantic field property in all pydantic widgets by making use of streamlits disabled widget property (fully introduced in streamlit 1.5.0 and pinned to this version in setup.py)
    2. Enhance the new list add/remove/clear buttons to respect max_items and min_items pydantic field properties that might be present in the model.
    3. Add support for all existing widget types (eg. date, time, boolean etc..) to be rendered in lists and dicts with full validation and formatting options. This is a result of some refactoring to improve code re-use. eg. There is now only one function that rendered a number field, regardless of whether that field is a standalone property or contained within in a list, dict or complex object.

    A new showcase example complex_disabled_showcase.py has been added to test/demonstrate all of the major widgets in thier disabled form. complex_instance_model.py has also been updated to demonstrate some of the now supported collection properties and data types.

    Checklist:

    • [x] I have read the CONTRIBUTING document.
    • [x] My changes don't require a change to the documentation, or if they do, I've added all required information.
    Stale 
    opened by HIL340 6
  • Return pydantic object from function

    Return pydantic object from function

    Thanks for making this repo @LukasMasuch! Excited to start playing with it. Would you be open to a PR to modify the API so that sd.pydantic_input() returns the instantiated pydantic object, or None if the inputs are invalid? If so I can play around with that

    opened by benlindsay 3
  • Lists(except files list) do not work in sidebar forms

    Lists(except files list) do not work in sidebar forms

    Description:

    lists of integers or strings (or in my assumption any other primitive type) as datatype does not work when using in sidebar form. The above does not occur and we get the clear and add item buttons but they disappear when used insidebar forms

    Expected Behaviour:

    this should be consistent across all forms (for my use-case at least sidebar-form)

    Steps to reproduce:

    class IDsModel(BaseModel):
        ids: List[str] =  Field( [], max_items=8, description="Enter ids")
    
    with st.sidebar.form(key="dummy_form"):
        dummy_session_data = sp.pydantic_input(key="dummy_model", model=IDsModel)
    

    P.S. love the pydantic <-> streamlit integration <3

    bug Stale 
    opened by sidphbot 2
  • Double ended slider

    Double ended slider

    Feature description: Generate a double ended slider when providing a maximum and minimum argument to Field.

    Streamlit provides a double ended slider when setting value to a list of integers that specify the range in st.slider(). In _render_single_number_input you only check for min_value and set value accordingly. By replacing L610 with

    if "min_value" in streamlit_kwargs and "max_value" in streamlit_kwargs:
        streamlit_kwargs["value"] = [
               streamlit_kwargs["min_value"],
               streamlit_kwargs["max_value"],
        ]
    elif "min_value" in streamlit_kwargs:
    

    you would get a double ended slider. I can create a PR if you like, but I am struggling with building the project see #12.

    Problem and motivation:

    It is a feature of streamlit and in my work we often need to specify ranges. I think this is very common in a lot of fields.

    Is this something you're interested in working on? Yes, I already did.

    Stale 
    opened by Bartcardi 1
  • Building the project after clean fork fails with mypy error

    Building the project after clean fork fails with mypy error

    Describe the bug: When I try to build the project using the instructions under the section Development in README.md, one of the code checks fails.

    I forked your latest main branch and tried to run the instructions for development. After running PIPENV_IGNORE_VIRTUALENVS=1 python build.py --make --check mypy reports an error.

    src/streamlit_pydantic/ui_renderer.py:1070: error: Argument 1 to "join" of "str" has incompatible type "Tuple[Union[int, str], ...]"; expected "Iterable[str]"
    

    Expected behaviour:

    I would have expected all checks to pass on the master branch.

    Steps to reproduce the issue: Clone the repo and checkout master (1afd4e3)

    pip install universal-build
    python build.py --make --check
    

    In my case I used PIPENV_IGNORE_VIRTUALENVS=1 to ignore my current virtual environment.

    Technical details:

    • Host Machine Mac OS
    • Python 3.9.5

    Possible Fix:

    Have a look at the specified line in the mypy output.

    Additional context: When running pip install universal-build python build.py --make --check for the first time it complained about missing wheel and twine.

    bug Stale 
    opened by Bartcardi 1
  • Support for Union class.

    Support for Union class.

    Cool project @LukasMasuch, thank you!

    Feature description:

    I'm missing support for Unions. Ver simple example can be:

    class PostalAddress(BaseClass):
        street: str
        city: str
        house: int
        
    class EmailAddress(BaseClass):
        email: str
        send_news: bool
        
    class ContactMethod(BaseClass):
        contact: Union[PostalAddress, EmailAddress]
        ... other fields
        
        
    # rendring form for ClassMethod
    
    

    So far I'm doing it with radio button, depending on its output the right option is rendered.

    I'm not sure if there is more elegant solution, but let me know if you have ideas so I could help with implementing

    opened by arogozhnikov 1
  • Using non-beta streamlit functions now

    Using non-beta streamlit functions now

    What kind of change does this PR introduce?

    • [ ] Bugfix
    • [ ] New Feature
    • [ ] Feature Improvement
    • [x] Refactoring
    • [ ] Documentation
    • [ ] Other, please describe:

    Description:

    Changed all streamlit beta functions to their non-beta version. On 2021-11-02, the beta-versions will be removed anyway.

    Checklist:

    • [x] I have read the CONTRIBUTING document.
    • [x] My changes don't require a change to the documentation, or if they do, I've added all required information.
    opened by BenediktPrusas 1
  • Fix Union Discriminator functioanlity with Pydantic 1.10+

    Fix Union Discriminator functioanlity with Pydantic 1.10+

    What kind of change does this PR introduce?

    • [x] Bugfix
    • [ ] New Feature
    • [ ] Feature Improvement
    • [ ] Refactoring
    • [ ] Documentation
    • [ ] Other, please describe:

    Description:

    Pydantic's 1.10 release introduced a change to its union discriminator property from "anyOf" to "oneOf" (see https://github.com/pydantic/pydantic/pull/4335).

    This property is used by streamlit-pydantic to support the optional rendering of discriminated unions in forms and this is no longer working with pydantic 1.10+

    This PR adds support for the pydantic 1.10 "oneOf" property name and maintains backwards compatibility with"anyOf" (and therefore with pydantic < 1.10)

    Also included are some minor formatting updates to the Union playground example pages by making use of streamlit tabs for the different model/instance init styles.

    Checklist:

    • [x] I have read the CONTRIBUTING document.
    • [x] My changes don't require a change to the documentation, or if they do, I've added all required information.
    opened by HIL340 1
  • Add Streamlit Color Widget

    Add Streamlit Color Widget

    What kind of change does this PR introduce?

    • [ ] Bugfix
    • [x] New Feature
    • [ ] Feature Improvement
    • [ ] Refactoring
    • [x] Documentation
    • [ ] Other, please describe:

    Description:

    Add the streamlit colour widget as a valid representation and selector of a pydantic colour field type.

    I've added the widget in the "Complex Instance Model" and "Complex Disabled Showcase" playground pages and in the process did some tidy up of these two pages:

    • Complex Instance Model: Updated to make use of st.tabs to separate the two init styles.
    • Complex Disabled Showcase: Fixed inconsistencies between the model and instance fields (some were in the wrong order or missing entirely)

    Checklist:

    • [x] I have read the CONTRIBUTING document.
    • [x] My changes don't require a change to the documentation, or if they do, I've added all required information.
    opened by HIL340 0
  • How to populate a form with a model instance?

    How to populate a form with a model instance?

    Describe the issue: How can I populate a form with an instance of a model that e.g. is loaded from a database? I was hoping for sth. like this to work:

    model = ExampleModel(long_text="This is a long text property.", integer_in_range=24)
    
    data = sp.pydantic_form(key="my_form", model=model)
    

    Brilliant project though, exactly what I was looking for!

    enhancement 
    opened by TomTom101 4
  • Displaying Input Sections in Columns

    Displaying Input Sections in Columns

    Feature description: As far as I understand at the moment User Input will all be displayed in one colum. As seen here grafik But instead i would like to display the interactive fields in multile colums, As seen here: grafik

    Maybe one could specify the number of input columns as name-value pair:

    input_data = sp.pydantic_input(
        "model_input", model=ExampleModel, width=2
    )
    

    Additionaly if the width value equals None, the Number of Collums could be automaticly determined to approximate for e.g. a 3 by 4 aspect ratio. If the window size is to narrow streamlit rearranges the elements anyway.

    Problem and motivation: The motivation is clearly to make apps with a lot of user input more organised and utilize more of wide screen displays. This is espacially sensible, since streamlit-pydantic is a usefull tool espacially in applications with a lot of user input, to make code more organised and modular.

    Is this something you're interested in working on? Yes, although I am totally inexperienced

    opened by BenediktPrusas 6
Releases(v0.5.0)
  • v0.5.0(Nov 17, 2021)

    PyPi Release

    🎁 Features & Improvements

    • Add support for union class (see example)
    • Add support for overwriting streamlit args (see example)
    • Add support for read only string fields.
    • Using non-beta streamlit functions now (#8) by @BenediktPrusas

    👥 Contributors

    Thanks to @BenediktPrusas, @LukasMasuch for the contributions.

    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Jul 19, 2021)

    PyPi Release

    🎁 Features & Improvements

    • Add support for dataclasses
    • Introduce multi-line format option for text area
    • Add option to ignore_empty_values (applied on "" string or 0 int value)
    • Change input_class parameter to model

    👥 Contributors

    Thanks to @LukasMasuch for the contributions.

    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Jul 17, 2021)

    PyPi Release

    🎁 Features & Improvements

    • Add support for literal expression for enums.
    • Support default values for enum sets (multiselect).

    👥 Contributors

    Thanks to @LukasMasuch for the contributions.

    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Jul 11, 2021)

    PyPi Release

    🎁 Features & Improvements

    • Add support for pydantic_form method as proposed by @benlindsay here.
    • Allow creating multiple forms within the same Streamlit application.
    • Implement playground application to showcase examples.

    📝 Documentation

    • Update documentation with lots of examples.
    • Improve API documentation.

    👥 Contributors

    Thanks to @LukasMasuch and @benlindsay for the contributions.

    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Jul 11, 2021)

    🎁 Features & Improvements

    • Extract UI-generation logic from opyrator
    • Create initial API for usage within Streamlit App.

    👥 Contributors

    Thanks to @LukasMasuch for the contributions.

    Source code(tar.gz)
    Source code(zip)
Creates infinite amount of guilded accounts in seconds.

Guilded Cookie Creator [fuck guilded i quit working on this, they patch like every fucking method after 2/3 days i release shit] Optimizations Asynchr

scripted 7 Feb 28, 2022
A 100% python file organizer. Keep your computer always organized!

PythonOrganizer A 100% python file organizer. Keep your computer always organized! To run the project, just clone the folder and run the installation

3 Dec 02, 2022
An AI-powered device to stop people from stealing my packages.

Package Theft Prevention Device An AI-powered device to stop people from stealing my packages. Installation To install on a raspberry pi, clone the re

rydercalmdown 157 Nov 24, 2022
A little tool that uses LLVM to extract simple "what does this do" level instruction information from all architectures.

moirai: MOre InstRuctions and Information Backcronym. Anyway, this is a small project to extract useful instruction definitions from LLVM's platform d

2 Jul 30, 2022
A set of simple functions to upload and fetch pastes on paste.uploadgram.me

pastegram-py A set of simple functions to upload and fetch pastes on paste.uploadgram.me. API Documentation Methods upload_paste(contents: bytes, file

Uploadgram 3 Sep 13, 2022
Python plugin for Krita that assists with making python plugins for Krita

Krita-PythonPluginDeveloperTools Python plugin for Krita that assists with making python plugins for Krita Introducing Python Plugin developer Tools!

18 Dec 01, 2022
An osu! cheat made in c++ rewritten in python and currently undetected.

megumi-python An osu! cheat made in c++ rewritten in python and currently undetected. Installation Guide Download python 3.9 from https://python.org C

Elaina 2 Nov 18, 2022
使用clash核心,对服务器进行Netflix解锁批量测试。

注意事项 测速及解锁测试仅供参考,不代表实际使用情况,由于网络情况变化、Netflix封锁及ip更换,测速具有时效性 本项目使用 Python 编写,使用前请完成环境安装 首次运行前请安装pip及相关依赖,也可使用 pip install -r requirements.txt 命令自行安装 Net

11 Dec 07, 2022
The tool helps to find hidden parameters that can be vulnerable or can reveal interesting functionality that other hunters miss.

The tool helps to find hidden parameters that can be vulnerable or can reveal interesting functionality that other hunters miss. Greater accuracy is achieved thanks to the line-by-line comparison of

197 Nov 14, 2022
python DroneCAN code generation, interface and utilities

UAVCAN v0 stack in Python Python implementation of the UAVCAN v0 protocol stack. UAVCAN is a lightweight protocol designed for reliable communication

DroneCAN 11 Dec 12, 2022
Generates images with semantic content from distribution A in the style of distribution B

A2B Generates images with semantic content from distribution A in the style of d

Richard Herbert 2 Dec 27, 2021
The fastest way to copy to (not from) high speed flash storage.

FastestCopy The fastest way to copy to (not from) high speed flash storage. This is about 3-6x faster than file copy on explorer.exe to usb flash driv

Derek Frombach 0 Nov 03, 2021
Python project that aims to discover CDP neighbors and map their Layer-2 topology within a shareable medium like Visio or Draw.io.

Python project that aims to discover CDP neighbors and map their Layer-2 topology within a shareable medium like Visio or Draw.io.

3 Feb 11, 2022
Monitoring of lake dynamics

slamcore_utils Description This repo contains the slamcore-setup-dataset script. It can be used for installing a sample dataset for offline testing an

10 Jun 23, 2022
🐍 A Python lib for (de)serializing Python objects to/from JSON

Turn Python objects into dicts or (json)strings and back No changes required to your objects Easily customizable and extendable Works with dataclasses

Ramon Hagenaars 253 Dec 14, 2022
IST-Website - IST Tutoring Portal for python

IST Tutoring Portal This portal is a web based interface to handle student help

Jean 3 Jan 03, 2022
The dynamic code loading framework used in LocalStack

localstack-plugin-loader localstack-plugin-loader is the dynamic code loading framework used in LocalStack. Install pip install localstack-plugin-load

LocalStack 5 Oct 09, 2022
Experimental Brawl Stars v36.218 server emulator written in Python.

Brawl Stars v36 Experimental Brawl Stars v36.218 server emulator written in Python. Requirements: Python 3.7 or higher colorama Running the server In

8 Oct 31, 2021
Open source tools to allow working with ESP devices in the browser

ESP Web Tools Allow flashing ESPHome or other ESP-based firmwares via the browser. Will automatically detect the board type and select a supported fir

ESPHome 195 Dec 31, 2022
Script to work around some quirks of the blender obj importer

ObjFix 1.0 (WIP) Script to work around some quirks of the blender obj importer Installation Download this repo In Blender, press "Edit" on the top-bar

Red_3D 4 Nov 20, 2021