Switching tunneling functionality from ngrok to localhost.run

pull/44/head
Tom Chapin 11 months ago
parent 5f7d99071c
commit 21dc07026a

@ -16,16 +16,16 @@ TEACH_MODE=False
PIPER_VOICE_URL="https://huggingface.co/rhasspy/piper-voices/resolve/main/en/en_US/lessac/medium/" PIPER_VOICE_URL="https://huggingface.co/rhasspy/piper-voices/resolve/main/en/en_US/lessac/medium/"
PIPER_VOICE_NAME="en_US-lessac-medium.onnx" PIPER_VOICE_NAME="en_US-lessac-medium.onnx"
# Expose through Ngrok
# Uncomment following line with your Ngrok auth token (https://dashboard.ngrok.com/get-started/your-authtoken)
#NGROK_AUTHTOKEN="AUTH TOKEN"
# If SERVER_START, this is where we'll serve the server. # If SERVER_START, this is where we'll serve the server.
# If CLIENT_START, this is where the client expects the server to be. # If CLIENT_START, this is where the client expects the server to be.
SERVER_URL=ws://localhost:8000/ # SERVER_CONNECTION_URL=wss://localhost:8000/
SERVER_CONNECTION_URL=wss://localhost:8000/
SERVER_START=True SERVER_START=True
CLIENT_START=True CLIENT_START=True
# The port to start the local server on
SERVER_LOCAL_PORT=8000
# Explicitly set the client type (macos, rpi) # Explicitly set the client type (macos, rpi)
CLIENT_TYPE=auto CLIENT_TYPE=auto
@ -34,9 +34,6 @@ CODE_RUNNER=server
TTS_RUNNER=server # If client, audio will be sent over websocket. TTS_RUNNER=server # If client, audio will be sent over websocket.
STT_RUNNER=client # If server, audio will be sent over websocket. STT_RUNNER=client # If server, audio will be sent over websocket.
# Will expose the server publically and display that URL.
SERVER_EXPOSE_PUBLICALLY=False
# Image capture settings # Image capture settings
CAMERA_ENABLED=True CAMERA_ENABLED=True

@ -291,9 +291,9 @@ class Device:
async def start_async(self): async def start_async(self):
# Configuration for WebSocket # Configuration for WebSocket
WS_URL = os.getenv('SERVER_URL') WS_URL = os.getenv('SERVER_CONNECTION_URL')
if not WS_URL: if not WS_URL:
raise ValueError("The environment variable SERVER_URL is not set. Please set it to proceed.") raise ValueError("The environment variable SERVER_CONNECTION_URL is not set. Please set it to proceed.")
# Start the WebSocket communication # Start the WebSocket communication
asyncio.create_task(self.websocket_communication(WS_URL)) asyncio.create_task(self.websocket_communication(WS_URL))

@ -18,7 +18,6 @@ import urllib.parse
from .utils.kernel import put_kernel_messages_into_queue from .utils.kernel import put_kernel_messages_into_queue
from .i import configure_interpreter from .i import configure_interpreter
from interpreter import interpreter from interpreter import interpreter
import ngrok
from ..utils.accumulator import Accumulator from ..utils.accumulator import Accumulator
from .teach import teach from .teach import teach
from .utils.logs import setup_logging from .utils.logs import setup_logging
@ -31,6 +30,9 @@ app = FastAPI()
conversation_history_path = Path(__file__).parent / 'conversations' / 'user.json' conversation_history_path = Path(__file__).parent / 'conversations' / 'user.json'
SERVER_LOCAL_PORT = int(os.getenv('SERVER_LOCAL_PORT', 8000))
# This is so we only say() full sentences # This is so we only say() full sentences
def is_full_sentence(text): def is_full_sentence(text):
return text.endswith(('.', '!', '?')) return text.endswith(('.', '!', '?'))
@ -269,18 +271,6 @@ async def listener():
async def stream_tts_to_device(sentence): async def stream_tts_to_device(sentence):
for chunk in stream_tts(sentence): for chunk in stream_tts(sentence):
await to_device.put(chunk) await to_device.put(chunk)
async def setup_ngrok(ngrok_auth_token, parsed_url):
# Set up Ngrok
logger.info("Setting up Ngrok")
ngrok_listener = await ngrok.forward(f"{parsed_url.hostname}:{parsed_url.port}", authtoken=ngrok_auth_token)
ngrok_parsed_url = urllib.parse.urlparse(ngrok_listener.url())
# Setup SERVER_URL environment variable for device to use
connection_url = f"wss://{ngrok_parsed_url.hostname}/"
logger.info(f"Ngrok established at {ngrok_parsed_url.geturl()}")
logger.info(f"\033[1mSERVER_CONNECTION_URL should be set to \"{connection_url}\"\033[0m")
from uvicorn import Config, Server from uvicorn import Config, Server
@ -297,20 +287,11 @@ if __name__ == "__main__":
# Start watching the kernel if it's your job to do that # Start watching the kernel if it's your job to do that
if os.getenv('CODE_RUNNER') == "server": if os.getenv('CODE_RUNNER') == "server":
asyncio.create_task(put_kernel_messages_into_queue(from_computer)) asyncio.create_task(put_kernel_messages_into_queue(from_computer))
server_url = os.getenv('SERVER_URL')
if not server_url:
raise ValueError("The environment variable SERVER_URL is not set. Please set it to proceed.")
parsed_url = urllib.parse.urlparse(server_url)
# Set up Ngrok
ngrok_auth_token = os.getenv('NGROK_AUTHTOKEN')
if ngrok_auth_token is not None:
await setup_ngrok(ngrok_auth_token, parsed_url)
logger.info("Starting `server.py`...") # Start the server
logger.info("Starting `server.py`... on wss://localhost:" + str(SERVER_LOCAL_PORT))
config = Config(app, host=parsed_url.hostname, port=parsed_url.port, lifespan='on') config = Config(app, host="localhost", port=SERVER_LOCAL_PORT, lifespan='on')
server = Server(config) server = Server(config)
await server.serve() await server.serve()

21
01OS/poetry.lock generated

@ -1766,25 +1766,6 @@ files = [
{file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"},
] ]
[[package]]
name = "ngrok"
version = "1.0.0"
description = "The ngrok Agent SDK for Python"
optional = false
python-versions = ">=3.7"
files = [
{file = "ngrok-1.0.0-cp37-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0c01e3ae6d37b7faa6a23968a6caf12c50b5d1d2ffda2932fa904de4a418a50f"},
{file = "ngrok-1.0.0-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:5a46dc024b23da2f3a424e3d877d3e8bb44937aa4304f3ebfb681644fb785575"},
{file = "ngrok-1.0.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:c650c2c5c9adc81be824479a9dfdedefb21f3e9b2d9ca454728a0c76e47a7f63"},
{file = "ngrok-1.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d2a2176547919d2431023b9e2abed873db2d0a7f2a116585438a2ba33778455"},
{file = "ngrok-1.0.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0a61acdbc378b82992e75abb9787437379a430c3ff44c38fb7c3dc498920ef86"},
{file = "ngrok-1.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aed49b00dc75ec8c6ca9ff0c88bad450df33c8d8972650848e5a3fd648b091a0"},
{file = "ngrok-1.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b3cdcf75435c0f23695161c5892580a7b0e64d6d26ccdc9764878bfebfc93b7b"},
{file = "ngrok-1.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:45d2652872fd33c6388dfe5fe02ca4eb70d2fef2199c25d476e90b818f725c45"},
{file = "ngrok-1.0.0-cp37-abi3-win32.whl", hash = "sha256:92b253ec235321abc7d6d5fae08fbda3b854099ccc02c748402b517c53a4b39a"},
{file = "ngrok-1.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:8a256b16be77bba45543e60dd1b4515a11fd1f43cde2a221ba0b360a51bfa980"},
]
[[package]] [[package]]
name = "numpy" name = "numpy"
version = "1.26.4" version = "1.26.4"
@ -3539,4 +3520,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = ">=3.9,<3.12" python-versions = ">=3.9,<3.12"
content-hash = "5c8d587b405e97c0dca454078950157106f9aea687cbecce5b7ae7effd2aeece" content-hash = "f69adbb8a50c2b9efa5162a5c289ff3e887ce58c656338eb5ca52274c7d3b5a4"

@ -22,7 +22,6 @@ python-dotenv = "^1.0.1"
ffmpeg-python = "^0.2.0" ffmpeg-python = "^0.2.0"
textual = "^0.50.1" textual = "^0.50.1"
pydub = "^0.25.1" pydub = "^0.25.1"
ngrok = "^1.0.0"
open-interpreter = "^0.2.0" open-interpreter = "^0.2.0"
simpleaudio = "^1.0.4" simpleaudio = "^1.0.4"
opencv-python = "^4.9.0.80" opencv-python = "^4.9.0.80"

@ -56,8 +56,7 @@ fi
# Check if "--expose" is passed as an argument # Check if "--expose" is passed as an argument
if [[ "$@" == *"--expose"* ]]; then if [[ "$@" == *"--expose"* ]]; then
# If "--expose" is passed, set SERVER_EXPOSE_PUBLICALLY to True export TUNNEL_START="True"
export SERVER_EXPOSE_PUBLICALLY="True"
fi fi
# Check if "--clear-local" is passed as an argument # Check if "--clear-local" is passed as an argument
@ -173,6 +172,14 @@ start_server() {
echo "Server started as process $SERVER_PID" echo "Server started as process $SERVER_PID"
} }
# Function to start tunnel service
start_tunnel() {
echo "Starting tunnel..."
./tunnel.sh &
TUNNEL_PID=$!
echo "Tunnel started as process $TUNNEL_PID"
}
stop_processes() { stop_processes() {
if [[ -n $CLIENT_PID ]]; then if [[ -n $CLIENT_PID ]]; then
echo "Stopping client..." echo "Stopping client..."
@ -182,6 +189,10 @@ stop_processes() {
echo "Stopping server..." echo "Stopping server..."
kill $SERVER_PID kill $SERVER_PID
fi fi
if [[ -n $TUNNEL_PID ]]; then
echo "Stopping tunnel..."
kill $TUNNEL_PID
fi
} }
# Trap SIGINT and SIGTERM to stop processes when the script is terminated # Trap SIGINT and SIGTERM to stop processes when the script is terminated
@ -199,9 +210,16 @@ if [[ "$CLIENT_START" == "True" ]]; then
start_client start_client
fi fi
# TUNNEL
# Start tunnel if TUNNEL_START is True
if [[ "$TUNNEL_START" == "True" ]]; then
start_tunnel
fi
# Wait for client and server processes to exit # Wait for client and server processes to exit
wait $CLIENT_PID wait $CLIENT_PID
wait $SERVER_PID wait $SERVER_PID
wait $TUNNEL_PID
# TTS, STT # TTS, STT

@ -0,0 +1,8 @@
#!/usr/bin/env bash
echo "Starting up localhost.run tunnel..."
ssh -o StrictHostKeyChecking=no -R 80:localhost:8000 nokey@localhost.run 2>&1 | while IFS= read -r line; do
if [[ "$line" =~ https://([a-zA-Z0-9]+\.lhr\.life) ]]; then
echo "Your free localhost.run tunnel is now active. Please set your client SERVER_CONNECTION_URL env var to: \"wss://${BASH_REMATCH[1]}\""
fi
done
Loading…
Cancel
Save