Provide ready binary for Mac and Linux to do sharing tunneling (#49)

This commit is contained in:
Nguyen Trung Duc (john) 2023-10-17 17:19:29 +07:00 committed by GitHub
parent 2b779926c6
commit aab982ddc4
4 changed files with 124 additions and 38 deletions

View File

@ -67,7 +67,7 @@ def export(export_path, output):
@click.option(
"--appname",
required=False,
default="The share app subdomain. Requires --share and --username",
help="The share app subdomain. Requires --share and --username",
)
@click.option(
"--port",
@ -121,39 +121,13 @@ def run(run_path, share, username, password, appname, port):
"Username must be provided to enable authentication for sharing"
)
if appname:
command = [
"frpc",
"http",
"-l",
str(port),
"-i",
"127.0.0.1",
"--uc",
"--sd",
str(appname),
"-n",
str(appname + username),
"--server_addr",
"35.92.162.75:7000",
"--token",
"Wz807/DyC;#t;#/",
"--disable_log_color",
]
import atexit
import subprocess
from kotaemon.contribs.promptui.tunnel import Tunnel
proc = subprocess.Popen(
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE
tunnel = Tunnel(
appname=str(appname), username=str(username), local_port=port
)
def kill_proc():
if proc is not None:
print(f"Killing tunnel: https://{appname}.promptui.dm.cinnamon.is")
proc.terminate()
atexit.register(kill_proc)
print(f"App is shared at https://{appname}.promptui.dm.cinnamon.is")
url = tunnel.run()
print(f"App is shared at {url}")
else:
params["share"] = True
print("App is shared at Gradio")

View File

@ -0,0 +1 @@
/frpc_*

View File

@ -0,0 +1,107 @@
import atexit
import logging
import os
import platform
import stat
import subprocess
from pathlib import Path
import requests
VERSION = "1.0"
machine = platform.machine()
if machine == "x86_64":
machine = "amd64"
BINARY_REMOTE_NAME = f"frpc_{platform.system().lower()}_{machine.lower()}"
EXTENSION = ".exe" if os.name == "nt" else ""
BINARY_URL = (
"some-endpoint.com"
f"/kotaemon/tunneling/{VERSION}/{BINARY_REMOTE_NAME}{EXTENSION}"
)
BINARY_FILENAME = f"{BINARY_REMOTE_NAME}_v{VERSION}"
BINARY_FOLDER = Path(__file__).parent
BINARY_PATH = f"{BINARY_FOLDER / BINARY_FILENAME}"
logger = logging.getLogger(__name__)
class Tunnel:
def __init__(self, appname, username, local_port):
self.proc = None
self.url = None
self.appname = appname
self.username = username
self.local_port = local_port
@staticmethod
def download_binary():
if not Path(BINARY_PATH).exists():
print("First time setting tunneling...")
resp = requests.get(BINARY_URL)
if resp.status_code == 404:
raise OSError(
f"Cannot set up a share link as this platform is incompatible. "
"Please create a GitHub issue with information about your "
f"platform: {platform.uname()}"
)
if resp.status_code == 403:
raise OSError(
"You do not have permission to setup the tunneling. Please "
"make sure that you are within Cinnamon VPN or within other "
"approved IPs. If this is new server, please contact @channel "
"at #llm-productization to add your IP address"
)
resp.raise_for_status()
# Save file data to local copy
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)
def run(self) -> str:
"""Setting up tunneling"""
if platform.system().lower() == "windows":
logger.warning("Tunneling is not fully supported on Windows.")
self.download_binary()
self.url = self._start_tunnel(BINARY_PATH)
return self.url
def kill(self):
if self.proc is not None:
print(f"Killing tunnel 127.0.0.1:{self.local_port} <> {self.url}")
self.proc.terminate()
self.proc = None
def _start_tunnel(self, binary: str) -> str:
command = [
binary,
"http",
"-l",
str(self.local_port),
"-i",
"127.0.0.1",
"--uc",
"--sd",
str(self.appname),
"-n",
str(self.appname + self.username),
"--server_addr",
"44.229.38.9:7000",
"--token",
"Wz807/DyC;#t;#/",
"--disable_log_color",
]
self.proc = subprocess.Popen(
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
atexit.register(self.kill)
return f"https://{self.appname}.promptui.dm.cinnamon.is"

View File

@ -106,12 +106,16 @@ def construct_pipeline_ui(
export_btn.click(func_export, inputs=None, outputs=exported_file)
with gr.Row():
with gr.Column():
with temp("Params"):
for component in params:
component.render()
with temp("Inputs"):
for component in inputs:
component.render()
if params:
with temp("Params"):
for component in params:
component.render()
if inputs:
with temp("Inputs"):
for component in inputs:
component.render()
if not params and not inputs:
gr.Text("No params or inputs")
with gr.Column():
with temp("Outputs"):
for component in outputs: