Салют! Не так давно создатели знаменитого pydantic выпустили новый фреймворк — FastUI, который позволяет создавать пользовательские интерфейсы с помощью декларативного кода на Python. В этой статье рассмотрим создание простого приложения и деплой его в Cloud Apps.

Обзор


По заявлению авторов фреймворка, фронтенду не нужно (и не следует) знать ничего о приложении, которое вы создаете, вместо этого он должен просто предоставить все компоненты, необходимые для создания интерфейса, а затем бэкенд может предоставить необходимые данные и параметры компонентов.

Реализовано это таким образом, что FastUI инкапсулирует описание компонентов интерфейса и в виде классов, затем запускается простое React приложение, которое обращается к эндпоинтам за данными и компонентами.

Пример


Для примера давайте напишем простое приложение, предоставляющее информацию о городах из списка с возможностью пагинации.

Данные для экспериментов любезно предоставили создатели фреймворка. Для начала опишем pydantic модель и функцию для чтения данных.

from pydantic import BaseModel, Field, TypeAdapter
import json
from pathlib import Path

class City(BaseModel):
    id: int
    city: str = Field(title="Name")
    city_ascii: str = Field(title="City Ascii")
    lat: float = Field(title="Latitude")
    lng: float = Field(title="Longitude")
    country: str = Field(title="Country")
    iso2: str = Field(title="ISO2")
    iso3: str = Field(title="ISO3")
    admin_name: str = Field(title="Admin Name")
    capital: str = Field(title="Capital")
    population: float = Field(title="Population")

def cities_list() -> list[City]:
    cities_file = Path(__file__).parent / "cities.json"
    with open(cities_file, "r", encoding="utf-8") as f:
        data = json.load(f)
    cities = [City(**city) for city in data]
    return cities


Далее напишем каркас для нашего примера, с помощью FastAPI. Опишем два роута, первый возвращает необходимые компоненты и данные, а второй — простое React приложение, которое отвечает за запрос и отображение компонентов, полученных из предыдущего.

from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from fastui import AnyComponent, FastUI
from fastui import components as c, prebuilt_html
from fastui.components.display import DisplayLookup, DisplayMode
from fastui.events import BackEvent, GoToEvent

app = FastAPI()

@app.get("/api/cities", response_model=FastUI, response_model_exclude_none=True)
def cities_view(page: int = 1, country=None):
    cities = cities_list()
    page_size = 10 # Количество записей в таблице, отображаемых на странице
    filter_form_initial = {}
    return c.Page( # Page - базовый контейнер для остальных компонентов
        components=[
            c.Table( # Table - базовая разметка таблицы
                data=cities[(page - 1) * page_size : page * page_size], #Создаём срез данных для заполнения таблицы
                data_model=City, #Передаём модель данных
                columns=[ # Описываем столбцы таблицы
                    DisplayLookup( #Указываем содержимое и размер столбца в процентах
                        field="city",
                        table_width_percent=33
                    ),
                    DisplayLookup(field="country", table_width_percent=33),
                    DisplayLookup(field="population", table_width_percent=33),
                ],
            ),
            c.Pagination(page=page, page_size=page_size, total=len(cities)), #Кнопки для пагинации
        ]
    )


@app.get("/{path:path}")
async def html_landing() -> HTMLResponse:
    """Простое React приложение, идёт последним, т.к. соответствует всем маршрутам"""
    return HTMLResponse(prebuilt_html(title="Большие города"))

Результат работы представлен на рисунке ниже:



Деплой


Для деплоя приложений на FastUI можно воспользоваться сервисом Apps, к сожалению рассмотренный фреймворк только набирает популярность, поэтому мы воспользуемся опцией: «деплой из Dockerfile». Для этого достаточно создать Dockerfile и разместить его в корне репозитория.

FROM python:3.11
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
EXPOSE 8000

Обратите внимание, что при отсутствии в Dockerfile параметра EXPOSE, APPS будет слушать порт 8080 контейнера.

Далее достаточно предоставить сервису доступ к аккаунту на github.


Затем остаётся следить за логами деплоя:



В случае успешного развёртывания появиться удобный дашборд с графиками нагрузки на виртуальную машину:



Заключение


В данной статье мы рассмотрели лишь малую часть возможностей фреймворка, однако можно отметить, что FastUI предоставляет новый подход к созданию веб-приложений и позволяет существенно ускорить разработку.



Возможно, захочется почитать и это:

Новости, обзоры продуктов и конкурсы от команды Timeweb.Cloud — в нашем Telegram-канале

Комментарии (4)


  1. mgis
    05.06.2024 13:20
    +1

    Пытаюсь придумать область практического применения такому фреймворку, но что то, как то не выходит.

    Разве что "черновая" визуализация данных Rest Api.


  1. Kahelman
    05.06.2024 13:20
    +1

    Товарищи пытаются переизобрести tcl/tk?

    :)

    Проблема подобных фреймфорков что пока делаем hello-world пример- все работает.

    Как только надо что-то более сложное -начинаются проблемы.

    Кстати, есть ещё более простой и универсальный Фреймворк: просто генерим html код а браузер его отображает. И без react-а.

    Server-rendering-html.

    Не благодарите :)


    1. oldd
      05.06.2024 13:20

      Весь сервер-сайд рендеринг вся работает до того момента, когда заказчик спросит - "а чего это при нажатии на кнопку страница перезагружается? Нам этого не надо"
      Не ребят, всё эти игрушки-перделки только для ну совсем простых интерфейсов. Чуть посложнее, малейшая реактивность и понеслось.. js, ts, jquery, react. Плавали, напарывались, знаем


  1. rasperepodvipodvert
    05.06.2024 13:20

    сервер сайд это похоже на php