Repository: gradio-app/gradio
Pull request: Update message when share link binary is blocked
Aggressive antivirus software sometimes blocks the share link binary file. Here, we make the error message more explicit so that users can find the binary file themselves and whitelist it from their antivirus software settings.

Closes: #4347 

Problem statement:
Share= True fails to generate public share link
### Describe the bug

Attempting to run the "Hello, World!" example given in the gradio docs, with share=True set, on a linux machine (Ubuntu 22.04, gradio version =3.32.0) simply results in a localhost link. No public sharing link is generated despite waiting for 4+ minutes.
I have looked at the previous issues involving failures in the link creation, but those explicitly return an error message.
The localhost link generated works fine.

Downgrading to gradio version = 3.13.0 successfully creates a public share link. Versions 3.15,3.16 and so on up to 3.21 do not generate links. I have not verified for versions from 3.21 to 3.32.
### Is there an existing issue for this?

- [X] I have searched the existing issues

### Reproduction

```
import gradio as gr

def greet(name):
    return "Hello " + name + "!"

demo = gr.Interface(fn=greet, inputs="text", outputs="text")

demo.launch(share=True) 
```

### Screenshot

_No response_

### Logs

```shell
No errors are shown, and the localhost link works just fine.
```


### System Info

```shell
Gradio version:3.32.0, OS: Ubuntu:22.04, Browser: Firefox
```


### Severity

serious, but I can work around it

Hints from issue discussion:
Hi @Gothos I think I know what the issue is. Basically your antivirus software is blocking the download of the binary file that creates the share link. Will make this more explicit and suggest a workaround.

Commit message: update share link message

Patch to review:
diff --git a/gradio/blocks.py b/gradio/blocks.py
index 275061c2ac..49d80ba345 100644
--- a/gradio/blocks.py
+++ b/gradio/blocks.py
@@ -40,7 +40,7 @@
 from gradio.helpers import EventData, create_tracker, skip, special_args
 from gradio.themes import Default as DefaultTheme
 from gradio.themes import ThemeClass as Theme
-from gradio.tunneling import CURRENT_TUNNELS
+from gradio.tunneling import CURRENT_TUNNELS, BINARY_FILENAME
 from gradio.utils import (
     GRADIO_VERSION,
     TupleNoPrint,
@@ -1845,7 +1845,7 @@ def reverse(text):
                     analytics.error_analytics("Not able to set up tunnel")
                 self.share_url = None
                 self.share = False
-                print(strings.en["COULD_NOT_GET_SHARE_LINK"])
+                print(strings.en["COULD_NOT_GET_SHARE_LINK"].format(BINARY_FILENAME))
         else:
             if not (quiet):
                 print(strings.en["PUBLIC_SHARE_TRUE"])
diff --git a/gradio/strings.py b/gradio/strings.py
index 1f1cfa230a..f5b6103975 100644
--- a/gradio/strings.py
+++ b/gradio/strings.py
@@ -10,7 +10,7 @@
     "RUNNING_LOCALLY": "Running on local URL:  {}",
     "RUNNING_LOCALLY_SEPARATED": "Running on local URL:  {}://{}:{}",
     "SHARE_LINK_DISPLAY": "Running on public URL: {}",
-    "COULD_NOT_GET_SHARE_LINK": "\nCould not create share link. Please check your internet connection or our status page: https://status.gradio.app",
+    "COULD_NOT_GET_SHARE_LINK": "\nCould not create share link. Please check your internet connection or our status page: https://status.gradio.app. Also please ensure that your antivirus or firewall is not blocking the {} binary file.",
     "COLAB_NO_LOCAL": "Cannot display local interface on google colab, public link created.",
     "PUBLIC_SHARE_TRUE": "\nTo create a public link, set `share=True` in `launch()`.",
     "MODEL_PUBLICLY_AVAILABLE_URL": "Model available publicly at: {} (may take up to a minute for link to be usable)",
diff --git a/gradio/tunneling.py b/gradio/tunneling.py
index b73eb07501..831f109e84 100644
--- a/gradio/tunneling.py
+++ b/gradio/tunneling.py
@@ -2,6 +2,8 @@
 import os
 import platform
 import re
+import requests
+import stat
 import subprocess
 from pathlib import Path
 from typing import List
@@ -9,6 +11,16 @@
 VERSION = "0.2"
 CURRENT_TUNNELS: List["Tunnel"] = []
 
+machine = platform.machine()
+if machine == "x86_64":
+    machine = "amd64"
+
+# Check if the file exist
+BINARY_NAME = f"frpc_{platform.system().lower()}_{machine.lower()}"
+BINARY_FILENAME = f"{BINARY_NAME}_v{VERSION}"
+BINARY_PATH = f"{Path(__file__).parent / BINARY_FILENAME}"
+EXTENSION = ".exe" if os.name == "nt" else ""
+
 
 class Tunnel:
     def __init__(self, remote_host, remote_port, local_host, local_port, share_token):
@@ -22,22 +34,8 @@ def __init__(self, remote_host, remote_port, local_host, local_port, share_token
 
     @staticmethod
     def download_binary():
-        machine = platform.machine()
-        if machine == "x86_64":
-            machine = "amd64"
-
-        # Check if the file exist
-        binary_name = f"frpc_{platform.system().lower()}_{machine.lower()}"
-        binary_path = f"{Path(__file__).parent / binary_name}_v{VERSION}"
-
-        extension = ".exe" if os.name == "nt" else ""
-
-        if not Path(binary_path).exists():
-            import stat
-
-            import requests
-
-            binary_url = f"https://cdn-media.huggingface.co/frpc-gradio-{VERSION}/{binary_name}{extension}"
+        if not Path(BINARY_PATH).exists():
+            binary_url = f"https://cdn-media.huggingface.co/frpc-gradio-{VERSION}/{BINARY_NAME}{EXTENSION}"
             resp = requests.get(binary_url)
 
             if resp.status_code == 403:
@@ -49,16 +47,14 @@ def download_binary():
             resp.raise_for_status()
 
             # Save file data to local copy
-            with open(binary_path, "wb") as file:
+            with open(BINARY_PATH, "wb") as file:
                 file.write(resp.content)
-            st = os.stat(binary_path)
-            os.chmod(binary_path, st.st_mode | stat.S_IEXEC)
-
-        return binary_path
+            st = os.stat(BINARY_PATH)
+            os.chmod(BINARY_PATH, st.st_mode | stat.S_IEXEC)
 
     def start_tunnel(self) -> str:
-        binary_path = self.download_binary()
-        self.url = self._start_tunnel(binary_path)
+        self.download_binary()
+        self.url = self._start_tunnel(BINARY_PATH)
         return self.url
 
     def kill(self):


Code review comments:
diff_hunk: @@ -1845,7 +1845,7 @@ def reverse(text):
                     analytics.error_analytics("Not able to set up tunnel")
                 self.share_url = None
                 self.share = False
-                print(strings.en["COULD_NOT_GET_SHARE_LINK"])
+                print(strings.en["COULD_NOT_GET_SHARE_LINK"].format(BINARY_FILENAME))
path: gradio/blocks.py
text: @user1:
I think it would be better if we displayed BINARY_PATH so that users don't have to search for the full path themselves. They may not know where the site-packages directory is on their machine.

@author:
Makes sense, thanks for the suggestion @user1