Merge pull request #44 from tomchapin/feature/replace-ngrok-with-open-source
Feature/replace ngrok with open source
This commit is contained in:
commit
c599f585bf
|
@ -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
|
39
README.md
39
README.md
|
@ -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…
Reference in New Issue