Skip to content

Commit b5c74ff

Browse files
authored
Fix HTTPX package crash for some values of "article" parameter in the interface (#7389)
1 parent 1095110 commit b5c74ff

File tree

4 files changed

+48
-11
lines changed

4 files changed

+48
-11
lines changed

.changeset/eight-candies-stick.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"gradio": patch
3+
---
4+
5+
fix:Fix HTTPX package crash for some values of "article" parameter in the interface

gradio/interface.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def __init__(
134134
live: Whether the interface should automatically rerun if any of the inputs change.
135135
title: A title for the interface; if provided, appears above the input and output components in large font. Also used as the tab title when opened in a browser window.
136136
description: A description for the interface; if provided, appears above the input and output components and beneath the title in regular font. Accepts Markdown and HTML content.
137-
article: An expanded article explaining the interface; if provided, appears below the input and output components in regular font. Accepts Markdown and HTML content.
137+
article: An expanded article explaining the interface; if provided, appears below the input and output components in regular font. Accepts Markdown and HTML content. If it is an HTTP(S) link to a downloadable remote file, the content of this file is displayed.
138138
thumbnail: String path or url to image to use as display image when the web demo is shared on social media.
139139
theme: A Theme object or a string representing a theme. If a string, will look for a built-in theme with that name (e.g. "soft" or "default"), or will attempt to load a theme from the Hugging Face Hub (e.g. "gradio/monochrome"). If None, will use the Default theme.
140140
css: Custom css as a string or path to a css file. This css will be included in the demo webpage.
@@ -295,7 +295,7 @@ def __init__(
295295
self.simple_description = utils.remove_html_tags(description)
296296
self.description = description
297297
if article is not None:
298-
article = utils.readme_to_html(article)
298+
article = utils.download_if_url(article)
299299
self.article = article
300300

301301
self.thumbnail = thumbnail

gradio/utils.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,13 +286,24 @@ def is_zero_gpu_space() -> bool:
286286
return os.getenv("SPACES_ZERO_GPU") == "true"
287287

288288

289-
def readme_to_html(article: str) -> str:
289+
def download_if_url(article: str) -> str:
290+
try:
291+
result = urllib.parse.urlparse(article)
292+
is_url = all([result.scheme, result.netloc, result.path])
293+
is_url = is_url and result.scheme in ["http", "https"]
294+
except ValueError:
295+
is_url = False
296+
297+
if not is_url:
298+
return article
299+
290300
try:
291301
response = httpx.get(article, timeout=3)
292302
if response.status_code == httpx.codes.OK: # pylint: disable=no-member
293303
article = response.text
294304
except (httpx.InvalidURL, httpx.RequestError):
295305
pass
306+
296307
return article
297308

298309

test/test_utils.py

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
is_in_or_equal,
2828
is_special_typed_parameter,
2929
kaggle_check,
30-
readme_to_html,
30+
download_if_url,
3131
sagemaker_check,
3232
sanitize_list_for_csv,
3333
sanitize_value_for_csv,
@@ -54,13 +54,34 @@ def test_ipython_check_no_ipython(self, mock_get_ipython):
5454
mock_get_ipython.return_value = None
5555
assert ipython_check() is False
5656

57-
@patch("httpx.get")
58-
def test_readme_to_html_doesnt_crash_on_connection_error(self, mock_get):
59-
mock_get.side_effect = httpx.ConnectError("Connection error")
60-
readme_to_html("placeholder")
61-
62-
def test_readme_to_html_correct_parse(self):
63-
readme_to_html("https://github.com/gradio-app/gradio/blob/master/README.md")
57+
def test_download_if_url_doesnt_crash_on_connection_error(self):
58+
in_article = "placeholder"
59+
out_article = download_if_url(in_article)
60+
assert out_article == in_article
61+
62+
# non-printable characters are not allowed in URL address
63+
in_article = "text\twith\rnon-printable\nASCII\x00characters"
64+
out_article = download_if_url(in_article)
65+
assert out_article == in_article
66+
67+
# only files with HTTP(S) URL can be downloaded
68+
in_article = "ftp://localhost/tmp/index.html"
69+
out_article = download_if_url(in_article)
70+
assert out_article == in_article
71+
72+
in_article = "file:///C:/tmp/index.html"
73+
out_article = download_if_url(in_article)
74+
assert out_article == in_article
75+
76+
# this address will raise ValueError during parsing
77+
in_article = "https://[unmatched_bracket#?:@/index.html"
78+
out_article = download_if_url(in_article)
79+
assert out_article == in_article
80+
81+
def test_download_if_url_correct_parse(self):
82+
in_article = "https://github.com/gradio-app/gradio/blob/master/README.md"
83+
out_article = download_if_url(in_article)
84+
assert out_article != in_article
6485

6586
def test_sagemaker_check_false(self):
6687
assert not sagemaker_check()

0 commit comments

Comments
 (0)