Files
wehub-resource-sync 9a6da7d40d
Publish Docker image / Build and publish (push) Failing after 0s
CI / Python tests (push) Failing after 4s
chore: import upstream snapshot with attribution
2026-07-13 12:03:55 +08:00

188 lines
7.1 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Run MoneyPrinterTurbo on Google Colab\n",
"\n",
"This notebook installs [MoneyPrinterTurbo](https://github.com/harry0703/MoneyPrinterTurbo) in an isolated Python 3.11 environment and launches its WebUI. Colab runtimes are temporary, so generated files are removed when the runtime is reset."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Install MoneyPrinterTurbo\n",
"\n",
"The setup is safe to run again: it clones the repository on the first run and updates it on later runs. Dependencies are installed in the project's virtual environment to avoid conflicts with Colab's preinstalled packages."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "S8Eu-aQarY_B"
},
"outputs": [],
"source": [
"import os\n",
"import subprocess\n",
"from pathlib import Path\n",
"\n",
"REPO_DIR = Path(\"/content/MoneyPrinterTurbo\")\n",
"REPO_URL = \"https://github.com/harry0703/MoneyPrinterTurbo.git\"\n",
"\n",
"# Update an existing checkout so rerunning this cell does not fail during clone.\n",
"if (REPO_DIR / \".git\").is_dir():\n",
" subprocess.run(\n",
" [\"git\", \"-C\", str(REPO_DIR), \"pull\", \"--ff-only\"], check=True\n",
" )\n",
"elif REPO_DIR.exists():\n",
" raise RuntimeError(f\"{REPO_DIR} exists but is not a Git repository\")\n",
"else:\n",
" subprocess.run(\n",
" [\"git\", \"clone\", \"--depth\", \"1\", REPO_URL, str(REPO_DIR)], check=True\n",
" )\n",
"\n",
"os.chdir(REPO_DIR)\n",
"subprocess.run([\"python\", \"-m\", \"pip\", \"install\", \"-q\", \"uv\", \"pyngrok\"], check=True)\n",
"subprocess.run([\"uv\", \"python\", \"install\", \"3.11\"], check=True)\n",
"# Use the lockfile in an isolated environment without changing Colab's preinstalled packages.\n",
"subprocess.run([\"uv\", \"sync\", \"--frozen\", \"--python\", \"3.11\"], check=True)\n",
"print(f\"MoneyPrinterTurbo is ready in {REPO_DIR}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Configure the Colab tunnel\n",
"\n",
"MoneyPrinterTurbo itself does not require ngrok for normal local use. This notebook uses ngrok only because the Streamlit server runs inside a remote Colab runtime.\n",
"\n",
"Create an account and copy your authentication token from the [ngrok dashboard](https://dashboard.ngrok.com/get-started/your-authtoken). The next cell reads it without displaying or storing it in the notebook."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from getpass import getpass\n",
"\n",
"from pyngrok import ngrok\n",
"\n",
"# Close tunnels from earlier runs before configuring a new one.\n",
"ngrok.kill()\n",
"\n",
"ngrok_token = getpass(\"Enter your ngrok authentication token: \").strip()\n",
"if not ngrok_token:\n",
" raise ValueError(\"An ngrok authentication token is required\")\n",
"ngrok.set_auth_token(ngrok_token)\n",
"del ngrok_token\n",
"print(\"ngrok authentication configured\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Launch the WebUI\n",
"\n",
"The cell waits for Streamlit to become healthy before creating the public URL. If startup fails, it includes the recent server log in the error. After opening the URL, use **Settings** to configure the required model and media API keys."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"collapsed": true,
"id": "oahsIOXmwjl9",
"outputId": "ee23a96c-af21-4207-deb7-9fab69e0c05e"
},
"outputs": [],
"source": [
"import time\n",
"from urllib.error import URLError\n",
"from urllib.request import urlopen\n",
"\n",
"PORT = 8501\n",
"LOG_PATH = Path(\"/content/moneyprinterturbo-webui.log\")\n",
"\n",
"# Make this cell safe to rerun by closing the previous process, log handle, and tunnel.\n",
"if \"streamlit_proc\" in globals() and streamlit_proc.poll() is None:\n",
" streamlit_proc.terminate()\n",
" streamlit_proc.wait(timeout=10)\n",
"if \"streamlit_log\" in globals() and not streamlit_log.closed:\n",
" streamlit_log.close()\n",
"ngrok.kill()\n",
"\n",
"streamlit_log = LOG_PATH.open(\"w\", encoding=\"utf-8\")\n",
"streamlit_proc = subprocess.Popen(\n",
" [\n",
" \"uv\",\n",
" \"run\",\n",
" \"streamlit\",\n",
" \"run\",\n",
" \"webui/Main.py\",\n",
" f\"--server.port={PORT}\",\n",
" \"--server.address=0.0.0.0\",\n",
" \"--browser.gatherUsageStats=False\",\n",
" \"--client.toolbarMode=minimal\",\n",
" \"--server.showEmailPrompt=False\",\n",
" ],\n",
" cwd=REPO_DIR,\n",
" stdout=streamlit_log,\n",
" stderr=subprocess.STDOUT,\n",
" text=True,\n",
")\n",
"\n",
"# Poll the health endpoint because startup time varies across Colab runtimes.\n",
"deadline = time.time() + 90\n",
"server_ready = False\n",
"while time.time() < deadline:\n",
" if streamlit_proc.poll() is not None:\n",
" break\n",
" try:\n",
" with urlopen(f\"http://127.0.0.1:{PORT}/_stcore/health\", timeout=2) as response:\n",
" server_ready = response.status == 200\n",
" except (URLError, TimeoutError):\n",
" pass\n",
" if server_ready:\n",
" break\n",
" time.sleep(2)\n",
"\n",
"if not server_ready:\n",
" streamlit_log.flush()\n",
" recent_log = LOG_PATH.read_text(encoding=\"utf-8\", errors=\"replace\")[-4000:]\n",
" raise RuntimeError(f\"Streamlit failed to start. Recent log:\\n{recent_log}\")\n",
"\n",
"# Use an explicit IPv4 URL because pyngrok may otherwise route localhost through ::1.\n",
"public_tunnel = ngrok.connect(addr=f\"http://127.0.0.1:{PORT}\", proto=\"http\", bind_tls=True)\n",
"print(\"MoneyPrinterTurbo is ready:\")\n",
"print(public_tunnel.public_url)\n",
"print(f\"Server log: {LOG_PATH}\")"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}