Skip to content

fix: keep Gradio 4 compatible with Starlette and containers - #200

Merged
LauraGPT merged 2 commits into
modelscope:mainfrom
higkoo:patch-1
Aug 3, 2026
Merged

fix: keep Gradio 4 compatible with Starlette and containers#200
LauraGPT merged 2 commits into
modelscope:mainfrom
higkoo:patch-1

Conversation

@higkoo

@higkoo higkoo commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • constrain the supported Gradio 4 runtime to starlette<1.0;
  • keep local launch behavior unchanged and skip Gradio's localhost probe only for explicit --listen mode;
  • preserve the user's --share choice instead of automatically creating a public tunnel;
  • add regression tests and a read-only pull-request workflow for the real Gradio index route.

Root cause

Gradio 4.44.1 still calls Jinja2Templates.TemplateResponse(name, context). Starlette 1.x requires TemplateResponse(request, name, context), so the same signature mismatch can surface as either TypeError: unhashable type: 'dict' or AttributeError: 'dict' object has no attribute 'split'.

This is resolved at dependency resolution time rather than by globally monkey-patching Gradio/Starlette or disabling Jinja's template cache.

User impact

Existing FunClip installations using the supported Gradio 4 range render the web UI again after reinstalling/upgrading requirements.txt. Container users can explicitly pass --listen without the internal localhost probe preventing startup. FunClip never turns on Gradio's public sharing tunnel unless the user passes --share.

Validation

  • regression tests before the safe fix: 5 failed;
  • CI-equivalent Gradio 4.44.1 / FastAPI 0.141.1 / Starlette 0.52.1: 6 passed;
  • full maintained test suite: 67 passed, 1 skipped (the skip is the live TwelveLabs test requiring TWELVELABS_API_KEY);
  • Gradio index smoke tests return HTTP 200 with gradio_config for both supported endpoints:
    • Gradio 4.31.3 / FastAPI 0.141.1 / Starlette 0.52.1;
    • Gradio 4.44.1 / FastAPI 0.141.1 / Starlette 0.52.1;
  • pip check, Ruff for new files, workflow YAML parsing, py_compile, and git diff --check pass.

Notes for reviewers

The only private Gradio argument used is _frontend=False, scoped to explicit --listen mode. In Gradio 4.31.3 and 4.44.1 it only bypasses the localhost reachability probe; binding and public sharing remain controlled by server_name and the explicit --share flag.

## 背景

FunClip 在以下环境中启动后访问页面报 500 错误:

| 依赖 | 版本 |
|------|------|
| gradio | 4.44.1 |
| starlette | 1.3.1 |
| fastapi | 0.141.1 |
| jinja2 | 3.1.6 |

## 问题

### 问题 1:`TypeError: unhashable type: 'dict'`
Jinja2 的 LRUCache 在缓存模板时,cache key 因 Starlette/Jinja2 版本矩阵
不兼容而变为不可哈希的 dict,导致模板渲染阶段直接崩溃。

### 问题 2:`AttributeError: 'dict' object has no attribute 'split'`(核心问题)
Starlette >= 1.0 破坏性变更了 `Jinja2Templates.TemplateResponse` 的签名:

- 旧签名:`TemplateResponse(name, context, ...)`
- 新签名:`TemplateResponse(request, name, context, ...)`

Gradio 4.44.x 仍按旧签名调用,导致 context dict 被当作模板名传入
`split("/")`,触发 AttributeError。

### 问题 3:`ValueError: When localhost is not accessible`
容器/无头环境中 Gradio 的 localhost 自检(HTTP HEAD)失败,直接抛异常
阻止启动。

## 修复

所有修复集中在 `funclip/launch.py`,不改动第三方库源码:

1. **禁用 Jinja2 模板缓存**:`templates.env.cache = None`,
   规避不可哈希 key 问题。

2. **猴子补丁 TemplateResponse**:通过首参类型自动判定新旧签名,
   对旧式 `(name, context)` 调用做参数适配后转发给新版 Starlette,
   实现 backward-compatible。

3. **启动容错**:传入 `_frontend=False` 跳过 localhost 自检;
   增加 `ValueError` 捕获,检测失败时自动降级为 `share=True`。

## 测试验证

| 路径 | 状态码 | 说明 |
|------|--------|------|
| `/` | 200 | 81455 bytes HTML,含 `gradio_config` |
| `/info` | 200 | API 元数据正常 |
| `/config` | 200 | UI 配置正常 |

启动命令:`python funclip/launch.py -p 12235 --listen`
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

Signed-off-by: zhifu gao <zhifu.gzf@alibaba-inc.com>
@LauraGPT LauraGPT changed the title fix: compatibility with Starlette>=1.0 and container/CI environments fix: keep Gradio 4 compatible with Starlette and containers Aug 3, 2026
@LauraGPT
LauraGPT merged commit 109f44f into modelscope:main Aug 3, 2026
1 check passed
@LauraGPT LauraGPT mentioned this pull request Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants