Allow sending a custom TLS certificate or no TLS certificate when connecting to custom share servers (#10728)

* changes

* changes

* add changeset

* changes

* add changeset

* fix

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
This commit is contained in:
Abubakar Abid 2025-03-04 15:11:31 -08:00 committed by GitHub
parent 17ffdd26c2
commit 9fce28b76b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 44 additions and 8 deletions

View File

@ -0,0 +1,5 @@
---
"gradio": patch
---
feat:Allow sending a custom TLS certificate or no TLS certificate when connecting to custom share servers

View File

@ -2394,6 +2394,7 @@ Received inputs:
state_session_capacity: int = 10000,
share_server_address: str | None = None,
share_server_protocol: Literal["http", "https"] | None = None,
share_server_tls_certificate: str | None = None,
auth_dependency: Callable[[fastapi.Request], str | None] | None = None,
max_file_size: str | int | None = None,
enable_monitoring: bool | None = None,
@ -2435,6 +2436,7 @@ Received inputs:
state_session_capacity: The maximum number of sessions whose information to store in memory. If the number of sessions exceeds this number, the oldest sessions will be removed. Reduce capacity to reduce memory usage when using gradio.State or returning updated components from functions. Defaults to 10000.
share_server_address: Use this to specify a custom FRP server and port for sharing Gradio apps (only applies if share=True). If not provided, will use the default FRP server at https://gradio.live. See https://github.com/huggingface/frp for more information.
share_server_protocol: Use this to specify the protocol to use for the share links. Defaults to "https", unless a custom share_server_address is provided, in which case it defaults to "http". If you are using a custom share_server_address and want to use https, you must set this to "https".
share_server_tls_certificate: The path to a TLS certificate file to use when connecting to a custom share server. This parameter is not used with the default FRP server at https://gradio.live. Otherwise, you must provide a valid TLS certificate file (e.g. a "cert.pem") relative to the current working directory, or the connection will not use TLS encryption, which is insecure.
auth_dependency: A function that takes a FastAPI request and returns a string user ID or None. If the function returns None for a specific request, that user is not authorized to access the app (they will see a 401 Unauthorized response). To be used with external authentication systems like OAuth. Cannot be used with `auth`.
max_file_size: The maximum file size in bytes that can be uploaded. Can be a string of the form "<value><unit>", where value is any positive integer and unit is one of "b", "kb", "mb", "gb", "tb". If None, no limit is set.
enable_monitoring: Enables traffic monitoring of the app through the /monitoring endpoint. By default is None, which enables this endpoint. If explicitly True, will also print the monitoring URL to the console. If False, will disable monitoring altogether.
@ -2624,6 +2626,7 @@ Received inputs:
self.share_server_protocol = share_server_protocol or (
"http" if share_server_address is not None else "https"
)
self.share_server_tls_certificate = share_server_tls_certificate
self.has_launched = True
self.protocol = (
@ -2740,6 +2743,7 @@ Received inputs:
local_port=self.server_port,
share_token=self.share_token,
share_server_address=self.share_server_address,
share_server_tls_certificate=self.share_server_tls_certificate,
)
parsed_url = urlparse(share_url)
self.share_url = urlunparse(

View File

@ -20,7 +20,11 @@ GRADIO_SHARE_SERVER_ADDRESS = os.getenv("GRADIO_SHARE_SERVER_ADDRESS")
def setup_tunnel(
local_host: str, local_port: int, share_token: str, share_server_address: str | None
local_host: str,
local_port: int,
share_token: str,
share_server_address: str | None,
share_server_tls_certificate: str | None,
) -> str:
share_server_address = (
GRADIO_SHARE_SERVER_ADDRESS
@ -36,6 +40,7 @@ def setup_tunnel(
Path(CERTIFICATE_PATH).parent.mkdir(parents=True, exist_ok=True)
with open(CERTIFICATE_PATH, "w") as f:
f.write(certificate)
share_server_tls_certificate = CERTIFICATE_PATH
except Exception as e:
raise RuntimeError(
"Could not get share link from Gradio API Server."
@ -43,7 +48,14 @@ def setup_tunnel(
else:
remote_host, remote_port = share_server_address.split(":")
remote_port = int(remote_port)
tunnel = Tunnel(remote_host, remote_port, local_host, local_port, share_token)
tunnel = Tunnel(
remote_host,
remote_port,
local_host,
local_port,
share_token,
share_server_tls_certificate,
)
address = tunnel.start_tunnel()
return address

View File

@ -60,7 +60,15 @@ CERTIFICATE_PATH = ".gradio/certificate.pem"
class Tunnel:
def __init__(self, remote_host, remote_port, local_host, local_port, share_token):
def __init__(
self,
remote_host: str,
remote_port: int,
local_host: str,
local_port: int,
share_token: str,
share_server_tls_certificate: str | None,
):
self.proc = None
self.url = None
self.remote_host = remote_host
@ -68,6 +76,7 @@ class Tunnel:
self.local_host = local_host
self.local_port = local_port
self.share_token = share_token
self.share_server_tls_certificate = share_server_tls_certificate
@staticmethod
def download_binary():
@ -127,10 +136,15 @@ class Tunnel:
"--server_addr",
f"{self.remote_host}:{self.remote_port}",
"--disable_log_color",
"--tls_enable",
"--tls_trusted_ca_file",
CERTIFICATE_PATH,
]
if self.share_server_tls_certificate is not None:
command.extend(
[
"--tls_enable",
"--tls_trusted_ca_file",
self.share_server_tls_certificate,
]
)
self.proc = subprocess.Popen(
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)

View File

@ -1696,6 +1696,7 @@ def test_mount_gradio_app_args_match_launch_args():
"share",
"share_server_address",
"share_server_protocol",
"share_server_tls_certificate",
"state_session_capacity",
"_frontend",
"self",

View File

@ -8,7 +8,7 @@ def test_setup_tunnel():
io = Interface(lambda x: x, "number", "number")
io.launch(show_error=True, prevent_thread_lock=True)
share_url = networking.setup_tunnel(
io.server_name, io.server_port, io.share_token, io.share_server_address
io.server_name, io.server_port, io.share_token, io.share_server_address, None
)
assert isinstance(share_url, str)
@ -22,6 +22,6 @@ def test_setup_custom_tunnel():
share_server_address="my-gpt-wrapper.com:7000",
)
share_url = networking.setup_tunnel(
io.server_name, io.server_port, io.share_token, io.share_server_address
io.server_name, io.server_port, io.share_token, io.share_server_address, None
)
assert isinstance(share_url, str)