趁热记录下,给未来的自己
需求澄清
当前应用中心的应用在非运行时(休眠、运行出错)状态下,无法查看其UI界面。
虽然,在休眠的情况下,任何用户都可以点击 重新启动 按钮来加载应用,但部分应用由于各个原因(如模型很大,导致加载时间过长;如依赖huggingface资源,但网络访问不稳定),重新启动的时间会比较长或者启动失败。
此时,如果用户想了解这个应用是干什么的(功能),长什么样子(界面),就无法快速直观地获取信息从而判断对这个应用是否有进一步探究的兴趣。
针对这种场景,可以新增一个快照功能,来实现gradio应用在非运行时提供界面预览功能。
本文将聚焦在如何提供gradio应用的快照方案和具体实施。
方案选择
快照方案有两个选择,前端路线和后端路线
2.1 前端路线
可以使用页面截图功能,比较常见的开源截图npm库:
2.1.1 dom-to-image
dom-to-image库主要使用的是SVG实现方式,简单来说就是先把DOM转换为SVG然后再把SVG转换为图片。
大致流程:
2.1.2 html2canvas
html2canvas库主要使用的是Canvas实现方式,主要过程是手动将dom重新绘制成canvas,因此,它只能正确渲染可以理解的属性,有许多CSS属性无法正确渲染。
大致流程:
2.2 后端路线
gradio应用是一个前后端一体的框架,在启动的时候,gradio应用会在线构建 前端 代码,构建成功的前端文件( html , js , css等),会放到运行gradio框架的python版本的lib库的特定目录下:xxx/lib/python3.x/site-packages/gradio/templates/frontend。
那么,是不是只需要将这个前端文件目录通过web服务器(如nginx)serving,就能通过浏览器访问了呢?理论上来说,是这样的,但还是有一些坑点,后面会展开讲。
2.3 比较
优点 | 缺点 | |
---|---|---|
前端路线 | 1. 业界有成熟的方案,来实现页面截图 | 1. 是静态的图片,不可交互,如果有tab页的话,无法展示; |
2. 交互比较复杂,需要后端配合提供接口 | ||
后端路线 | 1. 非静态图片,可交互; | 1. 通用性不强,只适用于gradio应用 |
2. 纯后端实现,无需前端参与 |
通过比较可以看到,前端路线缺点较多,最主要的是不可交互,会导致部分含有tab页的gradio应用的快照展示不全。
所以,快照调研的路线会选择后端路线(但是前端截图的功能是一个高频的需求,虽然在这个业务场景下不太实用,但还是值得前端团队进行调研的)
实施验证
首先,需要搭建一个nginx服务,来提供基本的web serving能力, nginx.conf关键配置如下:
ini
http {
server {
listen 881;
server_name 0.0.0.0;
location / {
root /path/to/gradio;
index index.html;
}
}
}
接着,在本地启动 gradio 应用,将目录 xxx/lib/python3.x/site-packages/gradio/templates/frontend 拷贝到 /path/to/gradio,包含文件和文件夹如下:
然后启动nginx服务,访问http://0.0.0.0:881, 你会看到:
没错,这个就是上文提到的坑点。分析了gradio的启动逻辑,发现其在启动时,除了需要依赖frontend下的前端资源文件外,还需要三个文件(通过get请求调用获得):
- config.json <- http://0.0.0.0:881/config
- info.json <- http://0.0.0.0:881/info
- theme.css <- http://0.0.0.0:881/theme.css
这三个文件可以通过本地启动gradio应用,调用如上接口获得。
为了能让浏览器获得以上三个文件,需要将其放到/path/to/gradio目录下,并修改nginx.conf如下:
ini
http {
server {
listen 881;
server_name 0.0.0.0;
location / {
root /path/to/gradio;
index index.html;
}
location /config {
root /path/to/gradio;
try_files /config.json =405;
}
location /info {
root /path/to/gradio;
try_files /info.json =405;
}
location /theme.css {
root /path/to/gradio;
try_files /theme.css =405;
}
}
}
再次访问,可成功获得前端页面,支持前端交互:
换一个应用尝试拿去快照成功:
如何集成到应用中心?
应用中心的python环境是通过pyenv管理的,所以gradio库在这个路径下:/usr/local/share/python/.pyenv/versions/3.9.16/lib/python3.9/site-packages/gradio/templates/frontend
如何将这个路径下的文件拿出来,统一管理,实现方法很多,不展开讲,但是可以用一个统一的nginx服务作为快照服务(可复用现有应用中心app-center-proxy服务),然后将各个应用的快照文件放到统一的目录纳管。
需要注意的点:
-
需要确认用户最近成功部署的gradio应用是基于哪个python版本(版本号会决定路径)
-
什么时机去该路径下拿前端文件?成功启动后?
-
info.json、config.json以及themes.css是通过接口调用时组装&生成json后返回给前端的的,本身这三个文件是不以文件形式存在。需要通过接口调用获取,同2,也涉及到时机问题
以上。