嗨,你好哈,今天介绍一个可以快速搭建一套 UI 界面 Python 库,为快速搭建一个有界面的聊天机器人做准备。
Gradio 是什么
上一次分享中,我们创建了一个对话机器人,但是只能通过终端的方式进行交互。今天介绍一个 Python 库,可以快速搭建一套 UI 界面,不需要去学习 JavaScript、TypeScript 以及相关的前端技术了。并且,Gradio 渲染出来的界面可以直接在 Jupyter Notebook 里面显示出来,适合场景相对简单,想要快速部署应用的开发者快速体验产品效果。
如果你已经在 AI 领域深入多年,可以略过哈。
Hello World
每一个应用程序,快速体验一下,使用 https://colab.research.google.com/
安装 gradio 库
pip install gradio
image-20230426235814422
import gradio as gr def greet(name): return "Hello " + name + "!" demo = gr.Interface(fn=greet, inputs="text", outputs="text") demo.launch()
image-20230427000040696
创建了两个文本框,输入一个 name,输出内容为:Hello xxx !如下图:
image-20230427000449941
从上面例子我们看到,简单的基于文本创建的 demo。但这个函数还可以处理很多类型。
Interface 类通过以下三个参数进行初始化:
- fn:包装的函数
- inputs:输入组件类型,(例如:“text”、"image)
- ouputs:输出组件类型,(例如:“text”、"image)
组件介绍
最常用的基础模块由以下几部分构成:
- 应用界面:gr.Interface(简易场景), gr.Blocks(定制化场景)
- 输入输出:gr.Image(图像), gr.Textbox(文本框), gr.DataFrame(数据框), gr.Dropdown(下拉选项),,gr.Number(数字), gr.Markdown, gr.Files
- 控制组件:gr.Button(按钮)
- 布局组件:gr.Tab(标签页), gr.Row(行布局),,gr.Column(列布局)
Textbox 组件
输入框为多行,使用占位符提示用户输入,并且设置了输入框的标签名称。
import gradio as gr def greet(name): return "Hello " + name + "!" demo = gr.Interface( fn=greet, inputs=gr.Textbox(lines=2, placeholder="Name Here...", label="Input Your Name"), outputs="text", ) demo.launch()
image-20230427002010216
多个输入和输出
对于复杂程序,输入列表中的每个组件按顺序对应于函数的一个参数。输出列表中的每个组件按顺序排列对应于函数返回的一个值。
import gradio as gr def greet(name, is_morning, temperature): salutation = "Good morning" if is_morning else "Good evening" greeting = f"{salutation} {name}. It is {temperature} degrees today" celsius = (temperature - 32) * 5 / 9 return greeting, round(celsius, 2) demo = gr.Interface( fn=greet, inputs=["text", "checkbox", gr.Slider(0, 100)], outputs=["text", "number"], ) demo.launch(debug=True)
image-20230427002852835
greet 函数有3个输入参数和2个输出参数,与 inputs 、 outputs 相对应。
图像组件
用图像生成图像的功能
import numpy as np import gradio as gr def sepia(input_img): sepia_filter = np.array([ [0.393, 0.769, 0.189], [0.349, 0.686, 0.168], [0.272, 0.534, 0.131] ]) sepia_img = input_img.dot(sepia_filter.T) sepia_img /= sepia_img.max() return sepia_img demo = gr.Interface(sepia, gr.Image(shape=(200, 200)), "image") demo.launch()
image-20230427003302912
更多的灵活性和控制
Grdio 提供了两个类来构建应用程序:
- Interface,一个高级抽象的 API,我们到目前为止一直在用它在演示。
- Blocks,用于设计具有更灵活布局和数据流的 Web 应用程序的低级 API。Blocks 可以让我们做一些事情,比如提供多个数据流和演示,控制组件出现在页面的哪个位置,处理复杂的数据流(例如输出可以作为其他函数的输入) ,以及基于用户交互更新组件的属性/可见性ーー仍然全部使用 Python。
如果您需要这种可定制性,请尝试使用 Block!
相对复杂点的示例
import numpy as np import gradio as gr def flip_text(x): return x[::-1] def flip_image(x): return np.fliplr(x) with gr.Blocks() as demo: gr.Markdown("Flip text or image files using this demo.") with gr.Tab("Flip Text"): text_input = gr.Textbox() text_output = gr.Textbox() text_button = gr.Button("Flip") with gr.Tab("Flip Image"): with gr.Row(): image_input = gr.Image() image_output = gr.Image() image_button = gr.Button("Flip") with gr.Accordion("Open for More!"): gr.Markdown("Look at me...") text_button.click(flip_text, inputs=text_input, outputs=text_output) image_button.click(flip_image, inputs=image_input, outputs=image_output) demo.launch()
image-20230427004521739
- Blocks 是用 with 子句创建的,在这个子句中创建的任何组件都会自动添加到应用程序中。
- 组件按照创建的顺序垂直出现在应用程序中。
- 创建了一个 Button,然后向该按钮添加了一个 click 事件监听器。这个 API 应该看起来很熟悉!与 Interface 类似,click 方法接受 Python 函数、输入组件和输出组件。
- 任何输入的组件内容都是可编辑的,而输出组件默认是不能编辑的。如果想要使得输出组件内容可编辑,设置interactive=True 即可。
布局
Blocks 默认情况下组件垂直排列。
组件水平排列:使用 Row 函数会将组件按照水平排列,但是在Row函数块里面的组件都会保持同等高度。
import gradio as gr with gr.Blocks() as demo: with gr.Row(): img1 = gr.Image() text1 = gr.Text() btn1 = gr.Button("button") demo.launch()
image-20230427005547995
组件垂直排列与嵌套:组件通常是垂直排列,可以通过 Row 函数和 Column 函数生成不同复杂的布局。
import gradio as gr with gr.Blocks() as demo: with gr.Row(): text1 = gr.Textbox(label="Textbox1") slider2 = gr.Textbox(label="Textbox2") drop3 = gr.Dropdown(["选项一", "选项二", "选项三"], label="Dropdown") with gr.Row(): # scale与相邻列相比的相对宽度。例如,如果列A的比例为2,列B的比例为1,则A的宽度将是B的两倍。 # min_width设置最小宽度,防止列太窄 with gr.Column(scale=2, min_width=600): text1 = gr.Textbox(label="prompt 1") text2 = gr.Textbox(label="prompt 2") inbtw = gr.Button("Between") text4 = gr.Textbox(label="prompt 4") text5 = gr.Textbox(label="prompt 5") with gr.Column(scale=1, min_width=600): img1 = gr.Image() btn = gr.Button("Go") demo.launch()
image-20230427010326263
修改样式
可以设置行内 css 属性将任何样式给应用程序
import gradio as gr #修改blocks的背景颜色 with gr.Blocks(css=".gradio-container {background-color: black}") as demo: box1 = gr.Textbox(value="Good Job") demo.launch()
image-20230427010653014
可以向任何组件添加HTML元素。通过 elem_id 选择对应的 css 元素。
import gradio as gr # 这里用的是id属性设置 with gr.Blocks(css="#warning{background-color: yellow} #sucess{background-color: green} #failure{background-color: red}") as demo: box1 = gr.Textbox(value="Good Job", elem_id="sucess") box2 = gr.Textbox(value="Failure", elem_id="failure") box3 = gr.Textbox(value="None", elem_id="warning") demo.launch()
image-20230427011142695