Gradio 非侵入式修改的离线使用方案

网上很多方案都是直接更换采用gradio-offline的包。但这个包很久不更新了并且是直接修改源码,所以自己打包也比较麻烦。因此这里提供了一种非侵入式的方法,动态替换部分资源的使用并重定向到本地静态资源,根据需要自己下载资源到本地就可以了。

本方案在gradio 5.34.0上测试通过。理论上兼容一个大版本应该没问题,如果有其他需求可以自己改一下。

使用方法

  1. gr_offline.py 放到你的项目中
  2. 导入补丁并在使用gradio之前调用 patch 函数
  3. 下载离线的静态资源到 ./static

使用样例

python 复制代码
import gr_offline
import gradio as gr

# 必须在使用gradio前调用一次
gr_offline.patch()

# 这个自己根据需要修改
gr.set_static_paths("./static")

def greet(name, intensity):
    return "Hello, " + name + "!" * int(intensity)

demo = gr.Interface(
    fn=greet,
    inputs=["text", "slider"],
    outputs=["text"],
)

demo.launch()

资源替换

  • CDN

    旧: https://cdnjs.cloudflare.com/{}

    新: ./static/{}

  • Google Font

    旧: https://fonts.googleapis.com/css2?family={file_name}:wght@{weight}&display=swap

    新: ./static/fonts/{file_name}/{file_name}-{weight}.woff2

原始资源下载链接

  • https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.1/iframeResizer.contentWindow.min.js
  • https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600&display=swap

gr_offline.py

python 复制代码
def _patch_env() -> None:
    import os

    os.environ["GRADIO_ANALYTICS_ENABLED"] = "False"


def _patch_font() -> None:
    from gradio.themes.utils.fonts import GoogleFont, LocalFont

    GoogleFont.__init__ = LocalFont.__init__  # type: ignore
    GoogleFont.stylesheet = LocalFont.stylesheet  # type: ignore


def _patch_templates() -> None:
    import re
    import types
    import jinja2
    from gradio import routes
    from fastapi.templating import Jinja2Templates

    remove_regex: list[re.Pattern] = [
        re.compile(
            r'<meta\b[^>]*?property=["']og:[^"'>]*["'][^>]*?>',
            flags=re.IGNORECASE | re.DOTALL,
        ),
        re.compile(
            r'<meta\b[^>]*?name=["']twitter:[^"'>]*["'][^>]*?>',
            flags=re.IGNORECASE | re.DOTALL,
        ),
        re.compile(
            r'<link\b[^>]*?href=["']?[^"'>]*fonts.googleapis.com[^"'>]*["']?[^>]*?>',
            flags=re.IGNORECASE | re.DOTALL,
        ),
        re.compile(
            r'<link\b[^>]*?href=["']?[^"'>]*fonts.gstatic.com[^"'>]*["']?[^>]*?>',
            flags=re.IGNORECASE | re.DOTALL,
        ),
    ]
    cdn_regex: list[re.Pattern] = [re.compile(r"https?://cdnjs.cloudflare.com/.*?")]

    def _do_patch(html: str) -> str:
        for pattern in remove_regex:
            html = re.sub(pattern, "", html)
        for pattern in cdn_regex:
            html = re.sub(pattern, "static/", html)
        return html

    def _patched_render(self: jinja2.Template, *args, **kwargs) -> str:
        html = jinja2.Template.render(self, *args, **kwargs)
        return _do_patch(html)

    async def _patched_render_async(self: jinja2.Template, *args, **kwargs) -> str:
        html = await jinja2.Template.render_async(self, *args, **kwargs)
        return _do_patch(html)

    class PatchedJinja2Templates(Jinja2Templates):
        def get_template(self, name: str) -> jinja2.Template:
            template: jinja2.Template = super().get_template(name)
            template.render = types.MethodType(_patched_render, template)
            template.render_async = types.MethodType(_patched_render_async, template)
            return template

    routes.templates = PatchedJinja2Templates(directory=routes.STATIC_TEMPLATE_LIB)
    routes.templates.env.filters["toorjson"] = routes.toorjson


def patch() -> None:
    _patch_env()
    _patch_font()
    _patch_templates()

Github:Gist

相关推荐
张3蜂6 分钟前
Python 四大 Web 框架对比解析:FastAPI、Django、Flask 与 Tornado
前端·python·fastapi
2601_9483745715 分钟前
商用电子秤怎么选
大数据·python
Volunteer Technology21 分钟前
Sentinel的限流算法
java·python·算法
七夜zippoe32 分钟前
Python统计分析实战:从描述统计到假设检验的完整指南
开发语言·python·统计分析·置信区间·概率分布
2601_9491465339 分钟前
Python语音通知API示例代码汇总:基于Requests库的语音接口调用实战
开发语言·python
去码头整点薯条9844 分钟前
python第五次作业
linux·前端·python
有代理ip1 小时前
Python 与 Golang 爬虫的隐藏优势
爬虫·python·golang
数研小生1 小时前
1688商品列表API:高效触达批发电商海量商品数据的技术方案
大数据·python·算法·信息可视化·json
Coder_Boy_1 小时前
基于SpringAI的在线考试系统-企业级教育考试系统核心架构(完善版)
开发语言·人工智能·spring boot·python·架构·领域驱动
铁蛋AI编程实战1 小时前
AI调用人类服务入门与Python实现(30分钟搭建“AI+真人”协作系统)
开发语言·人工智能·python