Code Monkey home page Code Monkey logo

fastui's Introduction

Pydantic

CI Coverage pypi CondaForge downloads versions license Pydantic v2

Data validation using Python type hints.

Fast and extensible, Pydantic plays nicely with your linters/IDE/brain. Define how data should be in pure, canonical Python 3.8+; validate it with Pydantic.

Pydantic Company ๐Ÿš€

We've started a company based on the principles that I believe have led to Pydantic's success. Learn more from the Company Announcement.

Pydantic V1.10 vs. V2

Pydantic V2 is a ground-up rewrite that offers many new features, performance improvements, and some breaking changes compared to Pydantic V1.

If you're using Pydantic V1 you may want to look at the pydantic V1.10 Documentation or, 1.10.X-fixes git branch. Pydantic V2 also ships with the latest version of Pydantic V1 built in so that you can incrementally upgrade your code base and projects: from pydantic import v1 as pydantic_v1.

Help

See documentation for more details.

Installation

Install using pip install -U pydantic or conda install pydantic -c conda-forge. For more installation options to make Pydantic even faster, see the Install section in the documentation.

A Simple Example

from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel

class User(BaseModel):
    id: int
    name: str = 'John Doe'
    signup_ts: Optional[datetime] = None
    friends: List[int] = []

external_data = {'id': '123', 'signup_ts': '2017-06-01 12:22', 'friends': [1, '2', b'3']}
user = User(**external_data)
print(user)
#> User id=123 name='John Doe' signup_ts=datetime.datetime(2017, 6, 1, 12, 22) friends=[1, 2, 3]
print(user.id)
#> 123

Contributing

For guidance on setting up a development environment and how to make a contribution to Pydantic, see Contributing to Pydantic.

Reporting a Security Vulnerability

See our security policy.

fastui's People

Contributors

0417taehyun avatar aekespong avatar almas-ali avatar cclauss avatar chaoyingz avatar cswamy avatar dejiah avatar dependabot[bot] avatar espenalbert avatar gem7318 avatar graingert avatar hramezani avatar ischaojie avatar justindhillon avatar kimvanwyk avatar lobaak avatar manimozaffar avatar omarmhaimdat avatar pablogamboa avatar paddymul avatar rgimen3z avatar samuelcolvin avatar sergue1 avatar shaikmoeed avatar sydney-runkle avatar tim-habitat avatar wolfdwyc avatar yihuangdb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fastui's Issues

Toast messages

Or at least some UI independent definition of "show something to the user after something has happened, even if they've navigated away from that page".

SASS compiling in Python

The idea is to let developers customise the style of their app without needing to resort to npm/node.

We would need to:

  • add libsass as a local dependency
  • provide a utility for downloading scss libraries like bootstrap (I aleady have this logic in either harrier or grablib, can't remember)
  • provide a utility for building the sass/scss
  • provide an option to remove the default css import in prebuilt_html

`bytes` is currently rendered wrong

Currently bytes becomes 'format': 'binary' in JSON Schema, which in turn means it get's rendered as a file input.

I'm not sure what the best solution is, maybe we just support the base64 types and solve it that way.

Trigger server event on input set/change

it's not just bound choice field but ill put it as an example

ex 1:
trigger server event when choice field selected, for my case i want to use the choice field value and filter data to generate another choice field based on it

ex 2:
Trigger server event when for example input1 and input2 are present

`fastui-bootstrap` allow more customisation

fastui-bootstrap should take functions matching CustomRender and ClassNameGenerator to those functions respectively, so you can use fastui-bootstrap while still overriding some components.

class_name.py throws TypeError

Hi,

Interesting library! I am a newby and tried a hello-world app, with the default code. I run the code in a Docker container on Python 3.9. I get this TypeError:

File "/usr/local/lib/python3.9/site-packages/fastui/class_name.py", line 6, in
ClassName = Annotated[str | list[str] | dict[str, bool | None] | None, Field(serialization_alias='className')]
TypeError: unsupported operand type(s) for |: 'type' and 'types.GenericAlias'

Any suggestions?

Kind regards, Harmen

Chart component

Hi,

I think it would be great if we had a chart component (e.g. think 2D bar charts or scatter plots).

Guess the mechanism of supplying data in the backend could be similar as it is implemented for the Table component.
For frontend implementation I think we could leverage something like Chart.js to do the charting work itself for us.

Not sure if this use case is common enough such that it would fit into FastUI itself or whether this should rather be considered a custom component and be separate from the package.

Any thoughts?

Custom Head Component

Make custom head tag with meta, title, script, and link tags.

For example, it looks like the one below.

class Head(pydanctic.BaseModel,  extra='forbid')
    elements: list[AnyHeadElement]


def render_head_element(head: Head) -> str:
    additional_tags: str = "\n".join([element in element in head.elements])
    return f"""
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      {additional_tags}
      <script type="module" crossorigin src="{_PREBUILT_CDN_URL}/index.js"></script>
      <link rel="stylesheet" crossorigin href="{_PREBUILT_CDN_URL}/index.css">        
    </head>
"""


def prebuilt_html(head: Head):
    """
    Returns a simple HTML page which includes the FastUI react frontend, loaded from https://www.jsdelivr.com/.

    Arguments:
        title: page title

    Returns:
        HTML string which can be returned by an endpoint to serve the FastUI frontend.
    """
    # language=HTML
    head: str = render_head_element(head=head)
    return f"""\
<!doctype html>
<html lang="en">
  {head}
  <body>
    <div id="root"></div>
  </body>
</html>
"""

If it is reasonable, can I contribute as pull request?

Why prefer FastUI over HTMX?

From #48 issue:

Rather than middleware or a reverse proxy [via Jinja2], we could have a function that renders the HTML at return time, so you do something like

@app.get('/api/')
async def my_view(...) -> HTMLResponse:
    components = FastUI(root=[...])
    return render_fastui_response_with_template_engine(components)

Is it main advantage? Are there any other considerations? Just reading the README.md is not clear.

More form constraints

Currently we don't apply many common constraints from pydantic/json schema to forms:

  • max length / min length
  • gt, lt, ge, le
  • multiple of

Shouldn't be too hard to add these to the form field pydantic models, populate them in json_schema.py and add them to the input in the frontend.

Why not using Svelte to create web components?

Always been a fan of pydantic (kudos @samuelcolvin), I'm glat to explore this new project

Have you considered making the frontend components in Svelte?
It's a pretty stable framework now, and it can actually compile to web components.

Web components could be fairly easy to use with a jinja(or mini-jinja)-based templated composer (#48)

I think it could be even possible to use Svelte stores as FastUI components, allowing cool interactions between displayed contents

JSON Schema equivalence tests

The whole point of FastUI is that we give some level of guarantee that the Pydantic models in the backend match the TS interfaces in the react app, but currently there's no test to catch if that's not the case.

To check consistency, we should generate JSON Schema for the component props interfaces, and for the pydantic models, and check they match. There will probably need to be some edge cases skipped or specially accounted for.

The tests should be written in Python, as little code as possible should be in node/ts.

Deployment instructions

Just wanted to say that project looks very exciting, but I'm wondering about the following:

  • How to deploy a FastUI application?
  • Things to consider during deployment.
  • Requirements for the server which will run the application.

arrays in forms

For lists and variable length tuples in forms we should have something roughly akin to django's formsets - basically a button to say "and another".

Initial values of form fields in frontend are not visible

Hi,

FastUI is really a great package, many thanks for providing a first version, it really simplifies the development process and allows to focus on backend developments.

I took the demo provided to test the functionality in the frontend "select a user defined form data (FormUserQuery), click on a button and then automatically populate the actual form fields (SelectForm)". For my "M"WE, please see below.

I do so by calling the "/get_user_endpoint" to get the user form data and then setting the initial values of SelectForm to the values stored in the user form data (in the endpoint ""). The issue is that in the frontend I cannot see the initial values for the fields of SelectForm for a given user defined form select (only for the field user_query, but not for tool). However, when looking at the response of the endpoint "/api", the initial values are in the API response and thus, are sent to the frontend. Similarly, when looking into the logs of npm, I also see that the initial values are there and populated in npm-fastui.src.components.form.FormComp in the fieldProps[].initial.

Though, when directly calling the URL, e.g., "http://localhost:3000/example?query_config=%7B%22tool%22%3A%22hammer%22%2C%22user_query%22%3A%22test%22%7D" from the browser (and not from "http://localhost:3000/example" and selecting the user query), then the user specific form data is available in the frontend. (This assumes the router endpoints below have the prefix example.)

Has anyone faced a similar issue and has an idea how to solve this issue? As I spent quite some time on investigating this issue, any help is appreciated.

Best,
Timo

from fastapi import APIRouter

from fastui import FastUI, AnyComponent, components as c
from fastui.forms import SelectSearchResponse, FormResponse, fastui_form
from fastui.events import GoToEvent
from shared import demo_page
from enum import StrEnum
from pydantic import Field, BaseModel
from typing import Annotated, List
import json

router = APIRouter()


@router.get("/get_user_queries", response_model=SelectSearchResponse)
def get_fonds() -> SelectSearchResponse:
    user_queries = {"test": {"tool": "hammer"}}
    options = [{"label": k, "value": k} for k, _ in user_queries.items()]
    return SelectSearchResponse(options=options)


class ToolEnum(StrEnum):
    hammer = "hammer"
    screwdriver = "screwdriver"


class SelectForm(BaseModel):
    tool: ToolEnum = Field(title="Select Tool")
    user_query: str | None = Field(title="Enter the name of your query.")


class FormUserQuery(BaseModel):
    query_name: str = Field(
        json_schema_extra={"search_url": "/api/example/get_user_queries"},
    )


@router.post("/get_user_query")
async def get_user_query(
    form: Annotated[FormUserQuery, fastui_form(FormUserQuery)]
) -> FormResponse:
    user_queries = {"test": {"tool": "hammer"}}
    query_config_dict = user_queries[form.query_name]
    query_config_dict["user_query"] = form.query_name
    return FormResponse(
        event=GoToEvent(
            url="",
            query={"query_config": SelectForm(**query_config_dict).model_dump_json()},
        )
    )


@router.post("/post_form_data")
async def post_form_data(form: Annotated[SelectForm, fastui_form(SelectForm)]) -> FormResponse:
    return FormResponse(event=GoToEvent(url="", query={"post_text": f"You selected {form.tool}."}))


@router.get("", response_model=FastUI, response_model_exclude_none=True)
def forms_view(query_config: str | None = None, post_text: str | None = None) -> list[AnyComponent]:
    query_config_dict = None
    if query_config:
        query_config_dict = json.loads(query_config)
    return demo_page(
        c.ModelForm[FormUserQuery](
            submit_url="/api/example/get_user_query"
        ),
        c.ModelForm[SelectForm](
            submit_url="/api/example/post_form_data",
            initial=query_config_dict,
        ),
        c.Text(text=post_text if post_text else "Nothing posted yet."),
        title="Example",
    )

Cleanup `fastui` exports

Currently it's a bit piecemeal based on what I needed for fastui-bootstrap, we should do something like bootstrap-react to export all components and their props in a nicely sorted way.

Backport PEP 585 + PEP 604 to Python 3.8 and 3.9

Hey FastUI project maintainers, could you please share your opinion on python/typing_extensions#315 ?
I think introducing it in typing_extensions would make working with built-in generics slightly more convenient and easier to document for the new Python programmers that would be interested in trying out FastUI. Not even mentioning the simplification in defining pydantic models with the newest-fashion type annotations.

I need your opinion on the issue so that there is a good rationale behind officially backporting or NOT backporting PEP 585 and PEP 604 in Python <3.10. I, alone, probably won't convince anyone about it...

Thanks!

tuples in forms

E.g. for the case of

class MyModel(BaseModel):
    size: tuple[int, int, int]

For fixed length tuples in forms, we should flatten the fields into top level inputs, like we do with nested models.

Dynamic form components

Hi
Is there a way to create dynamic form components, for now the form field only accept
FormField = FormFieldInput | FormFieldCheckbox | FormFieldFile | FormFieldSelect | FormFieldSelectSearch

cannot use ServerLoad in the form

Templating options

Great project!

Would it be possible to enable templating in JSX? The upside is potentially easier integration into JavaScript modules and I also find the code simpler to view.

DataTablesJS Component

Hi,

I discovered Starlette Admin in these last months and started to use in production. It uses DataTables/DataTables for tables which is quite powerfull.

My proposal is basically this: a component/field to use DataTables within FastUI.

`autocomplete` on Forms

We should support autocomplete on forms via json_schema_extra, e.g.:

class LoginForm(BaseModel):
    email: EmailStr = Field(title='Email Address', description="Enter whatever value you like")
    password: SecretStr = Field(
        title='Password', 
        description="Enter whatever value you like", 
        json_schema_extra={'autocomplete': 'current-password'}
    )

add `FormattedText` component

Defined as something like

class FormattedText(pydantic.BaseModel, extra='forbid'):
    text: str
    text_format: typing.Literal['bold', 'italic', 'underline', 'strikethrough'] | None = pydantic.Field(None, serialization_alias='textFormat')
    # TODO, use pydantic-extra-types Color?
    text_color: str | None = pydantic.Field(None, serialization_alias='textColor')
    background_color: str | None = pydantic.Field(None, serialization_alias='backgroundColor')
    type: typing.Literal['FormattedText'] = 'FormattedText'

The items in components like Button and Link become list[str | FormattedText | Link]. We might want too provide a few more components specifically for typography, like Bullets and Numbers

Two reasons to do this over relying on Markdown:

  1. Markdown is a relatively heave lazy module, that it would be nice not to have to load
  2. Markdown by it's definition is terrible for templating or user defined values - it's virtually impossible to escape. Providing these types would allow text to be defined which included uses values safely

fastui requires fastapi

Hi, first this looks like a cool project! I was trying your basic person list demo using litestar as the framework rather than fastapi. When I tried to the code I get an error saying that fastui.dev required fastapi to the installed. The exact error is:

from fastui import FastUI, AnyComponent, prebuilt_html, components as c
  File "/home/jc/.cache/pypoetry/virtualenvs/fastui-ls-4yKqtn9D-py3.11/lib/python3.11/site-packages/fastui/__init__.py", line 3, in <module>
    from .components import AnyComponent
  File "/home/jc/.cache/pypoetry/virtualenvs/fastui-ls-4yKqtn9D-py3.11/lib/python3.11/site-packages/fastui/components/__init__.py", line 17, in <module>
    from .forms import (
  File "/home/jc/.cache/pypoetry/virtualenvs/fastui-ls-4yKqtn9D-py3.11/lib/python3.11/site-packages/fastui/components/forms.py", line 9, in <module>
    from .. import forms
  File "/home/jc/.cache/pypoetry/virtualenvs/fastui-ls-4yKqtn9D-py3.11/lib/python3.11/site-packages/fastui/forms.py", line 19, in <module>
    raise ImportError('fastui.dev requires fastapi to be installed, install with `pip install fastui[fastapi]`') from e
ImportError: fastui.dev requires fastapi to be installed, install with `pip install fastui[fastapi]`

I did not install fastapi because I wanted to use litestar rather than fastapi.

HTML + HTMX frontend - AKA Jinja frontend

The swifties of HTMX on twitter are asking "why not HTMX?".

While I'm not as enamoured by HTMX as some, there is a good argument to build a frontend that requires no javascript, with optional improvement via HTMX.

The main advantage as I see it is to end users of the applications - less JS to download, less chance of clientside bugs that go unfixed, less chance of something built with this silently breaking in 10 years time when the maintainer is dead.

The real question is how to render the HTML, there are three options:

  1. Jinja2 (or other python template rendering engine), running as middleware or a reverse proxy to take models returned by the endpoint and render them to HTML
  2. something at the edge that takes the models and renders them to HTML, I tried to build something like this 3 years ago using wasm but the performance was too bad, AFAIK that's still an issue unless the app is very high volume, so you'd need to somehow render the HTML with pure javascript and no eval, doesn't sound easy, though it would be awesome
  3. I have a very experimental template rendering engine that uses JSX syntax and is written in Rust with Python bindings called psx, maybe one day if I get rich or end up in prison I'll finish it

In the mean time, the only realistic way to do this is option 1.

Are there are python bindings for one of the rust ports of jinja, like minijinja? (@mitsuhiko I seem to remember you talking about this on twitter, does it exist?)

Rather than middleware or a reverse proxy, we could have a function that renders the HTML at return time, so you do something like

@app.get('/api/')
async def my_view(...) -> HTMLResponse:
    components = FastUI(root=[...])
    return render_fastui_response_with_template_engine(components)

One very nice feature of returning JSON from an app is that unit tests are far easier than when returning HTML, therefore whatever solution we end up with (if we end up with on at all ๐Ÿคท), we should be able to switch off the rendering and return JSON for tests.

Custom Components

Currently only the white listed set of components can be rendered, while we can and should extend that list, we should also allow custom components.

The idea would be to define a component like

class Custom(BaseModel):
    data: Any
    class_name: _class_name.ClassName = None
    sub_type: str = Field(serializeation_alias='subType')
    type: typing.Literal['Custom'] = 'Custom'

subType let's implementing code do a nice switch thing when deciding how to render custom components.

The default implementation should just show data as JSON with a message saying "not implemented".

Nested models

I have a model like this (code below), how do I access for instance the name in TeamModel ?

This does not work:

columns=[
    DisplayLookup(field="position"),
    DisplayLookup(field="team.name"),

class TeamModel(BaseModel):
    id: int
    name: str
    shortName: str
    tla: str
    crest: str

class Standing(BaseModel):
    position: Optional[int] = None
    team: Dict[str, str|int]
    playedGames: Optional[int] = None
    form: Any
    won: Optional[int] = None
    draw: Optional[int] = None
    lost: Optional[int] = None
    points: Optional[int] = None

SQLModel with FastUI

Is there someone who try FastUI with SQLModel by tiangolo ?

I think it would be a good idea to use them together.

Proposal: New Syntax for components declaration

I've been exploring a new way of writing FastUI components that aims to make the code shorter and easier to understand.

Overview

The current way of writing components involves a lot of indentation and detailed structures:

c.Div(
    components=[
        c.Heading(text='Link List', level=2),
        c.Markdown(
            text=(
                'This is a simple unstyled list of links, '
                'LinkList is also used in `Navbar` and `Pagination`.'
            )
        ),
        c.LinkList(
            links=[
                c.Link(
                    components=[c.Text(text='Internal Link - go to the home page')],
                    on_click=GoToEvent(url='/'),
                ),
                c.Link(
                    components=[c.Text(text='Pydantic (External link)')],
                    on_click=GoToEvent(url='https://pydantic.dev'),
                ),
            ],
        ),
    ],
    class_name='border-top mt-3 pt-1',
)

On the other hand, the new way simplifies things:

c.Div(class_name='border-top mt-3 pt-1')[
    c.Heading(level=2)['Link List'],
    c.Markdown[
        'This is a simple unstyled list of links, '
        'LinkList is also used in `Navbar` and `Pagination`.'
    ],
    c.LinkList[
        c.Link(on_click=GoToEvent(url='/'))[
            c.Text['Internal Link - go to the home page']
        ],
        c.Link(on_click=GoToEvent(url='https://pydantic.dev'))[
            c.Text['Pydantic (External link)']
        ],
    ],
]

Advantages

The new way of writing components is easier to read and requires less code. It makes the code more straightforward and easier to manage.

Example

Take a look at how it could be implemented and used with FastUI components: Usage with FastUI Components.

Remarks

It's crucial to recognize that this approach is highly opinionated and involves breaking changes. It's presented as a proposal, not an ideal or universally accepted solution. Consider the implications and potential challenges before adopting this syntax in a production environment.

named styles

The idea is to provide something a bit like bootstrap's "primary", "secondary", "success" etc. to customise components without resorting the the sledge hammer of CSS.

I think we have:

  • primary - default
  • secondary - for "not the main thing to do"
  • warning - for "this does bad/irreversible" stuff

That should be enough for now.

Expanding the components in /docs hang the server

When expanding any components /docs hang the server and make it unresponsive, a restart for the server and a page kill is needed.

there's no logs on the console, it produced on the sample of the fastapi app in the doc

Browsers:
Chrome Version 119.0.6045.199 (Official Build) (arm64)
Firefox version 120 mac

Screenshot 2023-12-03 at 11 27 07 AM

Dark Mode

I know, I know, but still - it is nice to have.

Shouldn't be too hard to implement - the default implementations just need to change color and background-color, and bootstrap already has support for dark mode via css variables.

Using external components like Stripe Elements or other client interactions

Background
First of all I am ecstatic that @samuelcolvin you started this project. With all the developments happening around NextJS the change back to a modern stack based around web standards is the way forward. Our hearts still lie with Python and love using SQLAlchemy, alembic, pydantic and FastAPI (having moved to it from our home grown API building framework) to build out the backend of our applications.

you can build responsive web applications using React without writing a single line of JavaScript, or touching npm.

would be a state or nirvana.

JSON APIs aren't going anywhere, specially with services like Stripe calling back and the general need for integration between services. FastAPI is well suited for that.

At present our approach is using NextJS to build a front end, which speaks to a Python backend. We maintain our working template of our server infrastructure, if you wish to have a look at it.

Context
This might already be catered for but might be a question because FastUI is still being developed and formal documentation is yet to come.

I have also noticed questions (which also came to mind) around using Tailwind #36 and if a question like that is a misunderstanding of how FastUI components work.

I am yet to get my head around how the machinery works between us writing Python and the frontend using React? So please pardon my ignorance.

Question
To add to the discussions around others asking for additional components. More often than not we need to vendor in things like Stripe Elements which offers React support.

Extending the same thought to little client side sprinkles where you wish to call the server side from a client interaction e.g video play back calls the server back to save progress time.

How would this fit into the FastUI paradigm?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.