FastUI:用 Python 轻松打造现代 Web 界面,告别 JavaScript 烦恼

FastUI:用 Python 轻松打造现代 Web 界面,告别 JavaScript 烦恼

from datetime import date

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

app = FastAPI()


class User(BaseModel):
    id: int
    name: str
    dob: date = Field(title='Date of Birth')


# define some users
users = [
    User(id=1, name='John', dob=date(1990, 1, 1)),
    User(id=2, name='Jack', dob=date(1991, 1, 1)),
    User(id=3, name='Jill', dob=date(1992, 1, 1)),
    User(id=4, name='Jane', dob=date(1993, 1, 1)),
]


@app.get("/api/", response_model=FastUI, response_model_exclude_none=True)
def users_table() -> list[AnyComponent]:
    """
    Show a table of four users, `/api` is the endpoint the frontend will connect to
    when a user visits `/` to fetch components to render.
    """
    return [
        c.Page(  # Page provides a basic container for components
            components=[
                c.Heading(text='Users', level=2),  # renders `<h2>Users</h2>`
                c.Table(
                    data=users,
                    # define two columns for the table
                    columns=[
                        # the first is the users, name rendered as a link to their profile
                        DisplayLookup(field='name', on_click=GoToEvent(url='/user/{id}/')),
                        # the second is the date of birth, rendered as a date
                        DisplayLookup(field='dob', mode=DisplayMode.date),
                    ],
                ),
            ]
        ),
    ]


@app.get("/api/user/{user_id}/", response_model=FastUI, response_model_exclude_none=True)
def user_profile(user_id: int) -> list[AnyComponent]:
    """
    User profile page, the frontend will fetch this when the user visits `/user/{id}/`.
    """
    try:
        user = next(u for u in users if u.id == user_id)
    except StopIteration:
        raise HTTPException(status_code=404, detail="User not found")
    return [
        c.Page(
            components=[
                c.Heading(text=user.name, level=2),
                c.Link(components=[c.Text(text='Back')], on_click=BackEvent()),
                c.Details(data=user),
            ]
        ),
    ]


@app.get('/{path:path}')
async def html_landing() -> HTMLResponse:
    """Simple HTML page which serves the React app, comes last as it matches all paths."""
    return HTMLResponse(prebuilt_html(title='FastUI Demo'))

作为一名科技博主,我来为大家介绍一个超级有趣且实用的开源项目——FastUI
https://github.com/pydantic/FastUI)。这个项目由 Pydantic 的创始人 Samuel Colvin 打造,旨在让开发者以更高效的方式构建现代 Web 用户界面(UI),尤其适合那些希望用 Python 定义 UI 逻辑而无需深入 JavaScript 的后端开发者。


FastUI 是什么?

FastUI 是一个创新的 Python 库,核心理念是通过声明式的 Python 代码来定义 Web 应用的界面,结合 Pydantic 的数据验证能力和 TypeScript 的类型安全,实目前前后端分离的同时保持高度一致性和开发效率。它的口号是“Build better UIs faster”(更快地构建更好的用户界面),目标是简化 Web 开发流程,让后端开发者也能轻松构建动态、交互式的 Web 应用。

FastUI 的核心特点是:

  • 前后端分离但高度协同:后端通过 Python 和 Pydantic 定义应用的结构和逻辑,前端则通过 React 和 TypeScript 实现界面渲染,双方通过 JSON Schema 确保数据一致性。
  • 无需编写 JavaScript:对于 Python 开发者来说,FastUI 的最大亮点是可以在不触碰 JavaScript 的情况下,通过 Python 代码定义 UI 组件和交互逻辑。
  • 类型安全与验证:利用 Pydantic 的模型验证和 TypeScript 的类型检查,FastUI 在构建时和运行时都能保证前后端数据结构的一致性,减少错误。
  • 与 FastAPI 无缝集成:虽然 FastUI 不依赖 FastAPI,但它与 FastAPI 的结合超级自然,能够快速构建高效的 Web 应用。

FastUI 的工作原理

FastUI 的核心是一个基于 Pydantic 模型和 TypeScript 接口的 UI 定义系统:

  1. 后端:开发者使用 Pydantic 模型定义 UI 组件(例如表格、表单、导航栏等)和交互逻辑。这些模型会被序列化为 JSON Schema,通过 API 传递给前端。
  2. 前端:FastUI 提供了配套的 React TypeScript 包(@pydantic/fastui),负责解析后端传来的 JSON 数据,并渲染成对应的 UI 组件。前端开发者可以专注于构建可复用的组件,而无需关心后端逻辑。
  3. 验证与一致性:Pydantic 在后端验证数据,TypeScript 在前端进行类型检查,确保前后端通信始终基于一致的 schema。

这种设计让 FastUI 实现了真正的“关注点分离”:后端定义应用的逻辑和结构,前端专注于呈现方式。相比 GraphQL(前端驱动扩展),FastUI 更倾向于让后端开发者掌控应用的扩展,而无需频繁修改前端代码。


FastUI 的优势

  1. 对后端开发者的友善性 如果你是 Python 开发者,尤其是熟悉 FastAPI 和 Pydantic 的开发者,FastUI 让你可以用熟悉的工具快速构建 Web 应用,而无需学习复杂的 JavaScript 生态。它特别适合快速原型开发或需要展示数据的场景。
  2. 组件化与可复用性 FastUI 鼓励开发者创建可复用的 UI 组件,前端开发者可以基于 @pydantic/fastui 或 @pydantic/fastui-bootstrap(基于 Bootstrap 的组件库)构建自定义组件,减少重复开发。
  3. RESTful 哲学 FastUI 遵循 Roy Fielding 提出的原始 REST 原则(与 htmx 的理念有些类似),即前端不需了解应用的业务逻辑,只需根据后端指令渲染界面。这种“后端驱动”模式简化了开发流程,适合快速迭代。
  4. 开源与社区驱动 FastUI 是 MIT 许可的开源项目,目前已有 8.8k+ 的 GitHub Star,社区活跃度较高。项目还处于早期阶段,未来有望发展出更丰富的组件生态。

使用场景

FastUI 特别适合以下场景:

  • 快速原型开发:后端开发者可以快速构建交互式界面,用于展示 API 数据或验证功能。
  • 数据驱动应用:如仪表盘、管理面板或数据可视化工具,FastUI 能高效地将后端数据渲染为前端界面。
  • 跨团队协作:前后端团队可以基于 JSON Schema 独立工作,减少沟通成本。
  • 避免 JavaScript 复杂性:对于不熟悉 React 或前端生态的开发者,FastUI 提供了低学习曲线的解决方案。

如何开始使用 FastUI?

  1. 安装 Python 包
  2. bash
  3. pip install fastui
  4. 这会安装 FastUI 的 Python 部分,包含 Pydantic 模型和工具。
  5. 安装前端包(可选): 如果需要自定义前端,可以通过 npm 安装:
  6. bash
  7. npm install @pydantic/fastui
  8. 或者使用预构建版本 @pydantic/fastui-prebuilt,无需自己构建前端:
  9. bash
  10. npm install @pydantic/fastui-prebuilt
  11. 简单示例: 以下是一个简单的 FastUI 应用(结合 FastAPI):
  12. python
  13. from fastapi import FastAPI
  14. from fastui import AnyComponent, FastUI
  15. from fastui.components import Text, Div
  16. from pydantic import BaseModel
  17. app = FastAPI()
  18. class Page(BaseModel):
  19. components: list[AnyComponent]
  20. @app.get(“/api/”, response_model=FastUI)
  21. def home():
  22. return FastUI(components=[
  23. Div(components=[
  24. Text(text=“欢迎使用 FastUI!”),
  25. ])
  26. ])
  27. 运行后,访问 localhost:8000 即可看到一个简单的页面,显示“欢迎使用 FastUI!”。
  28. 查看官方 Demo: 你可以访问 FastUI 的官方 Demo(https://fastui-demo.onrender.com)来体验它的实际效果。

FastUI 的局限与未来

虽然 FastUI 超级有潜力,但作为新兴项目,它也有一些局限:

  • 生态尚不成熟:正如官方文档提到的,FastUI 还很新,社区组件库尚未完全丰富,可能需要开发者自行扩展。
  • 功能覆盖有限:目前 FastUI 更适合数据驱动的界面,对于复杂交互(如实时协作工具)可能需要额外的定制。
  • 学习曲线:虽然对 Python 开发者友善,但前端开发者需要了解 TypeScript 和 React 来定制组件。

未来,随着社区贡献的增加(目前已有 340+ forks 和多位活跃贡献者),FastUI 有望发展出更强劲的组件库和更广泛的框架支持(不仅限于 FastAPI 和 React)。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 共4条

请登录后发表评论