为了账号安全,请及时绑定邮箱和手机立即绑定

谷歌刚刚终结了Streamlit吗?

坐在沙发上浏览YouTube推荐时,我看到了Prompt Engineering发布的一个视频(Prompt Engineering),介绍了Google最新开源的Python框架‘Mesop’。这个框架被Google团队用于内部工具开发和快速原型设计。如果你想知道‘Mesop’这个名字意味着什么,就别想太多了。生活中不是所有东西都有意义。Will,如果你看到这条信息,请在评论区留言。

我觉得也许我应该试一试,看看它是否真的比Streamlit更好。虽然我喜欢Streamlit,因为它有着极其直观的编码体验,能够像魔法一样从无到有生成应用程序,但只要一看界面,就知道这是Streamlit。

为了解决这个问题,我写了一篇博客,介绍了如何仅使用Python和Tailwind CSS开发美观的Web应用,这篇文章意外地火了。你可以在这里阅读它:这里。这个过程更适用于生产环境,但如果你还想构建可定制的原型呢?

那正是Mesop所做的。

TL;DR: Mesop 仍处于初期阶段,所以不要急着用它来构建 SaaS 启动项目。此外,它也没有得到 Google 的官方支持。

Mesop 的特性
  1. 开源。

  2. 使用预构建组件轻松上手。

  3. 使用符合Python习惯的代码。

  4. 热重载。

  5. 组件基本上是Python函数。

  6. 基于Angular构建。
使用Mesop入门

由于我不喜欢用冗长的文献来介绍各种技术特性,让我们直接开始使用Mesop构建一些基本的用户界面。在使用Mesop构建时,你主要需要了解三个组件:

  1. State 类: 这将作为你的会话状态,并提供在不同组件之间共享数据的能力。
  2. 页面和事件: 应用的主要用户界面。
  3. 样式元素: CSS 样式(Tailwind 支持即将推出)

在开始之前,请确保使用 pip install mesop 安装 mesop。

状态类

所有在应用中使用的模型都是通过带有装饰器 @me.stateclass 的状态类实例化的。假设你正在构建一个GenAI应用来根据标题和提纲生成文章,你需要创建一个名为 ‘Article’ 的状态类,它看起来像这样:

    import mesop as me  

    @me.stateclass  
    class Article:  
        title: str  
        outline: str  
        response: str

在我们创建的每个函数或组件中,这个状态类数据将会在整个过程中保持持久,并且全局可访问。

页面和事件

类似于状态类,Mesop 中的所有页面都使用 @me.page() 装饰器进行标记。

    @me.page()  
    def app():  
        me.input(label="标题", type="text")  
        me.input(label="大纲", type="text")

上述代码会生成一个包含两个输入字段的基本页面。为了能够将数据存储在我们之前创建的状态类中,每个字段都需要一个单独的函数。

    def on_title_input(title: me.InputEvent):  
        s = me.state(Article)  
        s.title = title.value  

    def on_outline_input(outline: me.InputEvent):  
        s = me.state(Article)  
        s.outline = outline.value  

    @me.page()  
    def app():  
        me.input(label="标题", on_input=on_title_input, type="text")  
        me.input(label="概要", on_input=on_outline_input, type="text")

为了访问状态类,使用的函数是 me.state()。然后将实例存储在变量 s 中。

在 Mesop 中,事件的处理是通过诸如 InputEventClickEvent 等类来实现的。

我们可以通过调用另一个函数来提交ClickEvent的输入数据。

    # 响应模式  
    class Blog(typing_extensions.TypedDict):  
        title: str  
        content: str  

    def on_title_input(title: me.InputEvent):  
        s = me.state(Article)  
        s.title = title.value  

    def on_outline_input(outline: me.InputEvent):  
        s = me.state(Article)  
        s.outline = outline.value  

    def on_click(click: me.ClickEvent):  
        s = me.state(Article)  
        prompt = f"撰写一篇关于以下文章标题和大纲的博客: <article_title>{s.title}</article_title><article_outline>{s.outline}</article_outline>。仅返回最终的博客内容和标题,格式为Markdown。"  
        # 添加环境变量以存储钩子URL  
        response = model.generate_content(  
                    prompt,  
                    generation_config=genai.GenerationConfig(  
                        response_mime_type="application/json",  
                        response_schema=Blog,  
                        temperature=0.8  
                    ))  
        data = json.loads(response.text)  
        s.response = data  

    @me.page()  
    def app():  
        me.input(label="标题", on_input=on_title_input, type="text")  
        me.input(label="大纲", on_input=on_outline_input, type="text")  
        me.button("生成博客", on_click=on_click)

为了使内容更有趣,我们将使用Gemini模型来生成一个博客,使用Mesop框架。on_click函数将从Article实例中获取titleoutline数据,并将其注入我们创建的提示中。LLM的响应将是一个包含博客内容的JSON。

样式设置

在 Mesop 中对元素进行样式设置类似于现有的 CSS 属性,但所有的属性都是 me.style() 函数的参数。

在使用 me.style() 定义样式后,可以将这些样式存储在变量中,并作为组件参数调用。

    _STYLE_INPUT_WIDTH = me.Style(width="100%")  

    _STYLE_BUTTON = me.Style(  
        background="#1976D2",  
        color="#fff",  
        padding=me.Padding.symmetric(horizontal=20, vertical=10),  
        font_size="16px",  
        cursor="pointer",  
        margin=me.Margin(bottom=20),  
    )  

    @me.page()  
    def app():  
        with me.box(style=_STYLE_CONTAINER):  
            s = me.state(Article)  
            with me.box(style=_STYLE_MAIN_COLUMN):  
                me.input(label="标题", on_input=on_title_input, type="text", style=_STYLE_INPUT_WIDTH)  
                me.input(label="概要", on_input=on_outline_input, type="text", style=_STYLE_INPUT_WIDTH)  
                me.button("生成博客", on_click=on_click, style=_STYLE_BUTTON)  
        with me.box(style=_STYLE_PREVIEW_CONTAINER):  
            if s.response:  
                me.markdown(f"{s.response['content']}", style=_STYLE_PREVIEW)
最终界面

界面并不算美观,但这主要是因为我没有花足够的时间去美化它。即使只是稍微调整一下,它看起来也比纯粹的HTML要好得多。由于可以为组件使用所有的CSS属性,你可以让UI变得独一无二。

Streamlit 是否已经不再活跃?

不,绝对不是这样。Mesop 仍然处于开发阶段,而且文档在某些方面还不够完善。部署一个 Mesop 应用程序并不直接简单,除非你直接将其部署到 Google Cloud,否则需要进行容器化。

Streamlit 仍然具有其自身的优势,并且在与 Mesop 比较时,特别是在构建数据可视化项目时,Streamlit 更加出色。此外,Streamlit Cloud 对于希望免费分享应用程序的任何人来说都是一个巨大的福音。

然而,Mesop 有着成长的潜力,并且每天都在接收更新,这使得它更适合用于快速工具开发和基于 REST API 的简单原型设计,这都要归功于它的轻量级特性。

感谢Will以及所有为Mesop框架开发和维护付出时间和努力的贡献者。

我们需要更多的UI框架

总是很高兴看到新的Python UI框架出现,比如Streamlit、Nicegui、Gradio,现在还有Mesop。Python的惯用语法使得编码更加易学易用,这一点从现在涌现的大量Streamlit项目中就可以看出。

幸运或不幸的是,Python 是我最早学习的编程语言,我立刻就爱上了它。随着更多类似框架的出现,Python 的使用将迅速增长,我希望未来能看到更多高质量的 Python 应用程序。

希望你喜欢这篇关于Mesop的简短博客,它能帮助你开始使用。由于时间有限,我只能简要介绍,同时也考虑到大家的注意力可能就像金鱼一样短暂。如果你喜欢这篇帖子,希望你能为它点赞,并在Python和Google社区中与更多用户分享。另外,你也可以关注我,获取更多类似的文章。

链接
  1. Github

  2. Mesop
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消