Merge pull request #44 from tomchapin/feature/replace-ngrok-with-open-source

Feature/replace ngrok with open source
pull/53/head
killian 11 months ago committed by GitHub
commit c599f585bf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,4 @@
_archive
__pycache__
.idea

@ -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_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 CLIENT_START, this is where the client expects the server to be.
# SERVER_URL=ws://localhost:8000/
SERVER_URL=ws://0.0.0.0:8000/
SERVER_START=True
CLIENT_START=True
# The port to start the local server on
SERVER_LOCAL_PORT=8000
# Explicitly set the client type (macos, rpi)
CLIENT_TYPE=auto
@ -34,9 +34,6 @@ CODE_RUNNER=server
TTS_RUNNER=server # If client, 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
CAMERA_ENABLED=False

@ -18,7 +18,6 @@ import urllib.parse
from .utils.kernel import put_kernel_messages_into_queue
from .i import configure_interpreter
from interpreter import interpreter
import ngrok
from ..utils.accumulator import Accumulator
from .teach import teach
from .utils.logs import setup_logging
@ -31,6 +30,9 @@ app = FastAPI()
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
def is_full_sentence(text):
return text.endswith(('.', '!', '?'))
@ -318,18 +320,6 @@ async def stream_tts_to_device(sentence):
return
for chunk in stream_tts(sentence):
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
@ -346,20 +336,11 @@ if __name__ == "__main__":
# Start watching the kernel if it's your job to do that
if os.getenv('CODE_RUNNER') == "server":
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 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)
await server.serve()

@ -1,33 +0,0 @@
The open-source language model computer.
```bash
pip install 01OS
```
```bash
01 # This will run a server + attempt to determine and run a client.
# (Behavior can be modified by changing the contents of `.env`)
```
**Expose an 01 server publically:**
```bash
01 --server --expose # This will print a URL that a client can point to.
```
**Run a specific client:**
```bash
01 --client macos # Options: macos, rpi
```
**Run locally:**
The current default uses OpenAI's services.
The `--local` flag will install and run the [whisper.cpp](https://github.com/ggerganov/whisper.cpp) STT and [Piper](https://github.com/rhasspy/piper) TTS models.
```bash
01 --local # Local client and server
01 --local --server --expose # Expose a local server
```

@ -56,8 +56,22 @@ fi
# Check if "--expose" is passed as an argument
if [[ "$@" == *"--expose"* ]]; then
# If "--expose" is passed, set SERVER_EXPOSE_PUBLICALLY to True
export SERVER_EXPOSE_PUBLICALLY="True"
if [[ "$SERVER_START" != "True" ]]; then
echo "Error: Start script must be started with --serve for tunneling to work."
exit 1
else
export TUNNEL_START="True"
if [[ "$@" == *"--expose-with-bore"* ]]; then
export TUNNEL_METHOD="bore"
elif [[ "$@" == *"--expose-with-localtunnel"* ]]; then
export TUNNEL_METHOD="localtunnel"
elif [[ "$@" == *"--expose-with-ngrok"* ]]; then
export TUNNEL_METHOD="ngrok"
fi
echo "exposing server"
fi
fi
# Check if "--clear-local" is passed as an argument
@ -177,6 +191,14 @@ start_server() {
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() {
if [[ -n $CLIENT_PID ]]; then
echo "Stopping client..."
@ -186,6 +208,10 @@ stop_processes() {
echo "Stopping server..."
kill $SERVER_PID
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
@ -203,9 +229,16 @@ if [[ "$CLIENT_START" == "True" ]]; then
start_client
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 $CLIENT_PID
wait $SERVER_PID
wait $TUNNEL_PID
# TTS, STT

@ -0,0 +1,65 @@
#!/usr/bin/env bash
# Get tunnel method from TUNNEL_METHOD environment variable, but default to bore
# Possible options;
# - bore
# - localtunnel
# - ngrok
TUNNEL_METHOD=${TUNNEL_METHOD:-bore}
# Get the SERVER_PORT environment variable, but default to 8000
SERVER_LOCAL_PORT=${SERVER_LOCAL_PORT:-8000}
echo "Using $TUNNEL_METHOD to expose port $SERVER_LOCAL_PORT on localhost..."
# If the TUNNEL_METHOD is bore, then we need to check if the bore-cli is installed
if [[ "$TUNNEL_METHOD" == "bore" ]]; then
if ! command -v bore &> /dev/null; then
echo "The bore-cli command is not available. Please run 'cargo install bore-cli'."
echo "For more information, see https://github.com/ekzhang/bore"
exit 1
else
bore local $SERVER_LOCAL_PORT --to bore.pub | while IFS= read -r line; do
if [[ "$line" == *"listening at bore.pub:"* ]]; then
remote_port=$(echo "$line" | grep -o 'bore.pub:[0-9]*' | cut -d':' -f2)
echo "Please set your client env variable for SERVER_URL=ws://bore.pub:$remote_port"
break
fi
done
fi
elif [[ "$TUNNEL_METHOD" == "localtunnel" ]]; then
if ! command -v lt &> /dev/null; then
echo "The 'lt' command is not available."
echo "Please ensure you have Node.js installed, then run 'npm install -g localtunnel'."
echo "For more information, see https://github.com/localtunnel/localtunnel"
exit 1
else
npx localtunnel --port $SERVER_LOCAL_PORT | while IFS= read -r line; do
if [[ "$line" == *"your url is: https://"* ]]; then
remote_url=$(echo "$line" | grep -o 'https://[a-zA-Z0-9.-]*' | sed 's|https://||')
echo "Please set your client env variable for SERVER_URL=wss://$remote_url"
break
fi
done
fi
elif [[ "$TUNNEL_METHOD" == "ngrok" ]]; then
if ! command -v ngrok &> /dev/null; then
echo "The ngrok command is not available."
echo "Please install ngrok using the instructions at https://ngrok.com/docs/getting-started/"
exit 1
else
ngrok http $SERVER_LOCAL_PORT --log stdout | while IFS= read -r line; do
if [[ "$line" == *"started tunnel"* ]]; then
remote_url=$(echo "$line" | grep -o 'https://[a-zA-Z0-9.-]*' | sed 's|https://||')
echo "Please set your client env variable for SERVER_URL=wss://$remote_url"
break
fi
done
fi
fi

@ -35,11 +35,40 @@ pip install 01OS
# (Behavior can be modified by changing the contents of `.env`)
```
**Expose an 01 server publically:**
**Expose an 01 Server Publicly**
We currently support exposing the 01 server publicly via a couple of different tunnel services:
- **bore.pub** ([GitHub](https://github.com/ekzhang/bore))
- **Requirements:** Ensure that Rust is installed ([Rust Installation](https://www.rust-lang.org/tools/install)), then run:
```
cargo install bore-cli
```
- **To Expose:**
```bash
01 --server --expose-with-bore
```
- **localtunnel** ([GitHub](https://github.com/localtunnel/localtunnel))
- **Requirements:** Ensure that Node.js is installed ([Node.js Download](https://nodejs.org/en/download)), then run:
```
npm install -g localtunnel
```
- **To Expose:**
```bash
01 --server --expose-with-localtunnel
```
- **ngrok** ([Website](https://ngrok.com/))
- **Requirements:** Install ngrok ([Getting Started with ngrok](https://ngrok.com/docs/getting-started/)), and set up an ngrok account. Get your auth key from [ngrok dashboard](https://dashboard.ngrok.com/get-started/your-authtoken), then set it in your local configuration by running:
```
ngrok config add-authtoken your_auth_token_here
```
- **To Expose:**
```bash
01 --server --expose-with-ngrok
```
```bash
01 --server --expose # This will print a URL that a client can point to.
```
**Run a specific client:**
@ -55,7 +84,7 @@ The `--local` flag will install and run the [whisper.cpp](https://github.com/gge
```bash
01 --local # Local client and server
01 --local --server --expose # Expose a local server
01 --local --server --expose-with-bore # Expose the local server with a public tunnel
```
**Teach Mode (experimental)**

Loading…
Cancel
Save