Gradio
Gradio是一个基于Python的Web UI框架,常用于AI demo搭建,SD的webui就使用的Gradio
Gradio采用函数式编程,由组件和函数组成,声明组件即可绘制UI,为组件绑定函数可以修改组件内容
可以在Gradio Playground中预览体验
基本语法
Blocks
我不太喜欢 Interface
相较于Interface,Blocks可以使用gr.Row()
等排版方式,更灵活
Gradio可以渲染一个markdown、html文本,可以将一些大段文字写在资源里,运行时读资源文本
在某个层级声明一个组件(比如Button)就会渲染一个按钮,可以用循环等方式批量生成
组件可以绑定事件,事件由函数+输入+输出组成
import gradio as gr import shutil from pathlib import Path import zipfile
with gr.Blocks() as demo: gr.Markdown('# Hello Title') u = gr.UploadButton("Upload a file", file_count="single", file_types=[".zip"]) with gr.Row(): file_name_text = gr.Textbox(lines=1, label="File name") file_count_text = gr.Textbox(lines=1, label="File count") u.upload(process_upload_file, inputs=u, outputs=[file_name_text, file_count_text])
if __name__ == "__main__": demo.launch(server_name="0.0.0.0", server_port=7860) demo.queue(concurrency_count=3)
|
TabbedInterface
可以将多个Blocks和在一起,通过左上角的页签切换显示的Blocks,很适合多个平行功能的开发
with gr.Blocks() as demo: ... with gr.Blocks() as demo2: ...
app = gr.TabbedInterface([demo, demo2], ['Demo Name', 'Demo2 Name']) app.launch(server_name="0.0.0.0", server_port=7861)
|
函数
我感觉gradio的函数写法很神奇,你在函数外只能声明组件,不能拿到组件的值,不能修改组件,想做1+1也要使用函数
为组件绑定函数时,inputs和outputs均为组件(或组件数组),但函数的输入和输出是组件的值,而非组件本身,比如你为一个函数绑定了输出为一个Textbox,你只需要返回一个字符串就行
def process_upload_file(file): upload_dir = Path("./uploads") upload_dir.mkdir(parents=True, exist_ok=True) file_path = upload_dir / Path(file.name) shutil.copy(file, upload_dir) unzip_folder = upload_dir / Path(file).stem with zipfile.ZipFile(file_path, 'r') as zip_ref: zip_ref.extractall(unzip_folder) return Path(file).stem, len(zip_ref.namelist())
|
全局变量
在外部定义一个全局变量,在函数中可以访问
stop_animation = False
def play_animation(file_name, current_frame, file_count, frame_rate): global stop_animation stop_animation = False for i in range(int(current_frame), int(file_count)): if stop_animation: break time.sleep(1/float(frame_rate)) progress = (i+1)/int(file_count) with open(f'uploads/{file_name}/{i}.svg', 'r') as f: svg_content = f.read() yield svg_content, i, progress def stop_animation(): global stop_animation stop_animation = True
with gr.Blocks() as demo: ... html = gr.HTML() with gr.Row(): btn = gr.Button("Start") stop_btn = gr.Button("Stop") btn.click(play_animation, inputs=[file_name_text, frame_index, file_count_text, frame_rate], outputs=[html, frame_index, sl]) stop_btn.click(stop_animation)
|
组件
示例
可以给一些输入组件提供示例,点一下自动填充
input_image = gr.Image(type="filepath") gr.Examples( examples=[ [osp.join(example_portrait_dir, "hal.jpeg")], [osp.join(example_portrait_dir, "s7.jpg")], ], inputs=[input_image], cache_examples=False, )
|
其他
网络连接bug
https://github.com/gradio-app/gradio/issues/4332