From 02eaf4cfcc03b4a0c27252c2b983bc1424794c7e Mon Sep 17 00:00:00 2001 From: Abubakar Abid Date: Tue, 8 Feb 2022 20:04:26 -0500 Subject: [PATCH 1/2] correctly handle no internet connection with share=True --- gradio/interface.py | 5 ++++- gradio/strings.py | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/gradio/interface.py b/gradio/interface.py index 61e98c8fd1..0560a14438 100644 --- a/gradio/interface.py +++ b/gradio/interface.py @@ -719,7 +719,6 @@ class Interface: if private_endpoint is not None: share = True - self.share = share if share: try: @@ -734,10 +733,14 @@ class Interface: if self.analytics_enabled: utils.error_analytics(self.ip_address, "Not able to set up tunnel") share_url = None + share = False + print(strings.en["COULD_NOT_GET_SHARE_LINK"]) else: print(strings.en["PUBLIC_SHARE_TRUE"]) share_url = None + self.share = share + if inbrowser: link = share_url if share else path_to_local_server webbrowser.open(link) diff --git a/gradio/strings.py b/gradio/strings.py index e0ca3d0912..09e2c10d3f 100644 --- a/gradio/strings.py +++ b/gradio/strings.py @@ -7,6 +7,7 @@ MESSAGING_API_ENDPOINT = "https://api.gradio.app/gradio-messaging/en" en = { "RUNNING_LOCALLY": "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.", "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)", @@ -18,7 +19,7 @@ en = { "COLAB_DEBUG_TRUE": "Colab notebook detected. This cell will run indefinitely so that you can see errors and logs. " "To turn off, set debug=False in launch().", "COLAB_DEBUG_FALSE": "Colab notebook detected. To show errors in colab notebook, set debug=True in launch()", - "SHARE_LINK_MESSAGE": "\nThis share link expires in 72 hours. For free permanent hosting, check out Spaces (https://huggingface.co/spaces)", + "SHARE_LINK_MESSAGE": "\nThis share link expires in 72 hours. For free permanent hosting, check out Spaces (https://www.huggingface.co/spaces)", "PRIVATE_LINK_MESSAGE": "Since this is a private endpoint, this share link will never expire.", "INLINE_DISPLAY_BELOW": "Interface loading below...", "MEDIA_PERMISSIONS_IN_COLAB": "Your interface requires microphone or webcam permissions - this may cause issues in Colab. Use the External URL in case of issues.", From 60728a4a201ad11e78eab42299bbd7cfbca39283 Mon Sep 17 00:00:00 2001 From: Abubakar Abid Date: Tue, 8 Feb 2022 23:45:18 -0500 Subject: [PATCH 2/2] enabled support for https --- gradio/interface.py | 10 +++++++--- gradio/networking.py | 18 +++++++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/gradio/interface.py b/gradio/interface.py index 0560a14438..eebfd08c14 100644 --- a/gradio/interface.py +++ b/gradio/interface.py @@ -628,6 +628,8 @@ class Interface: encrypt: bool = False, cache_examples: bool = False, favicon_path: Optional[str] = None, + ssl_keyfile: Optional[str] = None, + ssl_certfile: Optional[str] = None, ) -> Tuple[flask.Flask, str, str]: """ Launches the webserver that serves the UI for the interface. @@ -649,7 +651,9 @@ class Interface: height (int): The height in pixels of the iframe element containing the interface (used if inline=True) encrypt (bool): If True, flagged data will be encrypted by key provided by creator at launch cache_examples (bool): If True, examples outputs will be processed and cached in a folder, and will be used if a user uses an example input. - favicon_path (str): If a path to an file (.png, .gif, or .ico) is provided, it will be used as the favicon for the web page. + favicon_path (str): If a path to a file (.png, .gif, or .ico) is provided, it will be used as the favicon for the web page. + ssl_keyfile (str): If a path to a file is provided, will use this as the private key file to create a local server running on https. + ssl_certfile (str): If a path to a file is provided, will use this as the signed certificate for https. Needs to be provided if ssl_keyfile is provided. Returns: app (flask.Flask): Flask app object path_to_local_server (str): Locally accessible link @@ -691,9 +695,9 @@ class Interface: cache_interface_examples(self) server_port, path_to_local_server, app, server = networking.start_server( - self, server_name, server_port + self, server_name, server_port, ssl_keyfile, ssl_certfile ) - + self.local_url = path_to_local_server self.server_port = server_port self.status = "RUNNING" diff --git a/gradio/networking.py b/gradio/networking.py index 5991d275b5..7a8acb5dee 100644 --- a/gradio/networking.py +++ b/gradio/networking.py @@ -77,6 +77,8 @@ def start_server( interface: Interface, server_name: Optional[str] = None, server_port: Optional[int] = None, + ssl_keyfile: Optional[str] = None, + ssl_certfile: Optional[str] = None, ) -> Tuple[int, str, fastapi.FastAPI, threading.Thread, None]: """Launches a local server running the provided Interface Parameters: @@ -84,6 +86,8 @@ def start_server( server_name: to make app accessible on local network, set this to "0.0.0.0". Can be set by environment variable GRADIO_SERVER_NAME. server_port: will start gradio app on this port (if available). Can be set by environment variable GRADIO_SERVER_PORT. auth: If provided, username and password (or list of username-password tuples) required to access interface. Can also provide function that takes username and password and returns True if valid login. + ssl_keyfile: If a path to a file is provided, will use this as the private key file to create a local server running on https. + ssl_certfile: If a path to a file is provided, will use this as the signed certificate for https. Needs to be provided if ssl_keyfile is provided. """ server_name = server_name or LOCALHOST_NAME # if port is not specified, search for first available port @@ -105,7 +109,14 @@ def start_server( port = server_port url_host_name = "localhost" if server_name == "0.0.0.0" else server_name - path_to_local_server = "http://{}:{}/".format(url_host_name, port) + + if ssl_keyfile is not None: + if ssl_certfile is None: + raise ValueError("ssl_certfile must be provided if ssl_keyfile is provided.") + path_to_local_server = "https://{}:{}/".format(url_host_name, port) + else: + path_to_local_server = "http://{}:{}/".format(url_host_name, port) + auth = interface.auth if auth is not None: if not callable(auth): @@ -130,7 +141,8 @@ def start_server( if interface.save_to is not None: # Used for selenium tests interface.save_to["port"] = port - config = uvicorn.Config(app=app, port=port, host=server_name, log_level="warning") + config = uvicorn.Config(app=app, port=port, host=server_name, log_level="warning", + ssl_keyfile=ssl_keyfile, ssl_certfile=ssl_certfile) server = Server(config=config) server.run_in_thread() return port, path_to_local_server, app, server @@ -163,7 +175,7 @@ def url_ok(url: str) -> bool: try: for _ in range(5): time.sleep(0.500) - r = requests.head(url, timeout=3) + r = requests.head(url, timeout=3, verify=False) if r.status_code in (200, 401, 302): # 401 or 302 if auth is set return True except (ConnectionError, requests.exceptions.ConnectionError):