Skip to content

Commit

Permalink
Fix HTTPX package crash for some values of "article" parameter in the…
Browse files Browse the repository at this point in the history
… interface (#7389)
  • Loading branch information
YuryYakhno authored Feb 12, 2024
1 parent 1095110 commit b5c74ff
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 11 deletions.
5 changes: 5 additions & 0 deletions .changeset/eight-candies-stick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"gradio": patch
---

fix:Fix HTTPX package crash for some values of "article" parameter in the interface
4 changes: 2 additions & 2 deletions gradio/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def __init__(
live: Whether the interface should automatically rerun if any of the inputs change.
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.
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.
article: An expanded article explaining the interface; if provided, appears below the input and output components in regular font. Accepts Markdown and HTML content.
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.
thumbnail: String path or url to image to use as display image when the web demo is shared on social media.
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.
css: Custom css as a string or path to a css file. This css will be included in the demo webpage.
Expand Down Expand Up @@ -295,7 +295,7 @@ def __init__(
self.simple_description = utils.remove_html_tags(description)
self.description = description
if article is not None:
article = utils.readme_to_html(article)
article = utils.download_if_url(article)
self.article = article

self.thumbnail = thumbnail
Expand Down
13 changes: 12 additions & 1 deletion gradio/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,13 +286,24 @@ def is_zero_gpu_space() -> bool:
return os.getenv("SPACES_ZERO_GPU") == "true"


def readme_to_html(article: str) -> str:
def download_if_url(article: str) -> str:
try:
result = urllib.parse.urlparse(article)
is_url = all([result.scheme, result.netloc, result.path])
is_url = is_url and result.scheme in ["http", "https"]
except ValueError:
is_url = False

if not is_url:
return article

try:
response = httpx.get(article, timeout=3)
if response.status_code == httpx.codes.OK: # pylint: disable=no-member
article = response.text
except (httpx.InvalidURL, httpx.RequestError):
pass

return article


Expand Down
37 changes: 29 additions & 8 deletions test/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
is_in_or_equal,
is_special_typed_parameter,
kaggle_check,
readme_to_html,
download_if_url,
sagemaker_check,
sanitize_list_for_csv,
sanitize_value_for_csv,
Expand All @@ -54,13 +54,34 @@ def test_ipython_check_no_ipython(self, mock_get_ipython):
mock_get_ipython.return_value = None
assert ipython_check() is False

@patch("httpx.get")
def test_readme_to_html_doesnt_crash_on_connection_error(self, mock_get):
mock_get.side_effect = httpx.ConnectError("Connection error")
readme_to_html("placeholder")

def test_readme_to_html_correct_parse(self):
readme_to_html("https://github.com/gradio-app/gradio/blob/master/README.md")
def test_download_if_url_doesnt_crash_on_connection_error(self):
in_article = "placeholder"
out_article = download_if_url(in_article)
assert out_article == in_article

# non-printable characters are not allowed in URL address
in_article = "text\twith\rnon-printable\nASCII\x00characters"
out_article = download_if_url(in_article)
assert out_article == in_article

# only files with HTTP(S) URL can be downloaded
in_article = "ftp://localhost/tmp/index.html"
out_article = download_if_url(in_article)
assert out_article == in_article

in_article = "file:///C:/tmp/index.html"
out_article = download_if_url(in_article)
assert out_article == in_article

# this address will raise ValueError during parsing
in_article = "https://[unmatched_bracket#?:@/index.html"
out_article = download_if_url(in_article)
assert out_article == in_article

def test_download_if_url_correct_parse(self):
in_article = "https://github.com/gradio-app/gradio/blob/master/README.md"
out_article = download_if_url(in_article)
assert out_article != in_article

def test_sagemaker_check_false(self):
assert not sagemaker_check()
Expand Down

0 comments on commit b5c74ff

Please sign in to comment.