Spaces:
Running
Running
Update Colab launcher to use the correct repository URL and streamline server startup process
Browse files- training/colab_launcher.ipynb +11 -69
training/colab_launcher.ipynb
CHANGED
|
@@ -44,7 +44,7 @@
|
|
| 44 |
"outputs": [],
|
| 45 |
"source": [
|
| 46 |
"import os\n",
|
| 47 |
-
"REPO_URL = 'https://github.com/
|
| 48 |
"WORKDIR = '/content/stocker'\n",
|
| 49 |
"if not os.path.isdir(WORKDIR):\n",
|
| 50 |
" assert '<your-username>' not in REPO_URL, 'Edit REPO_URL first.'\n",
|
|
@@ -97,71 +97,7 @@
|
|
| 97 |
"id": "launch",
|
| 98 |
"metadata": {},
|
| 99 |
"outputs": [],
|
| 100 |
-
"source": [
|
| 101 |
-
"import os, secrets, subprocess, time, re, pathlib, signal\n",
|
| 102 |
-
"\n",
|
| 103 |
-
"TOKEN = secrets.token_urlsafe(24)\n",
|
| 104 |
-
"PORT = 9988\n",
|
| 105 |
-
"LOG_J = pathlib.Path('/content/jupyter.log')\n",
|
| 106 |
-
"LOG_C = pathlib.Path('/content/cloudflared.log')\n",
|
| 107 |
-
"\n",
|
| 108 |
-
"# Kill any previous instances\n",
|
| 109 |
-
"for proc in ('jupyter-server', 'cloudflared'):\n",
|
| 110 |
-
" !pkill -f {proc} 2>/dev/null\n",
|
| 111 |
-
"time.sleep(1)\n",
|
| 112 |
-
"\n",
|
| 113 |
-
"# Start jupyter-server in the background, listening only on localhost.\n",
|
| 114 |
-
"# We run it from /content/stocker so the kernel's cwd matches the repo.\n",
|
| 115 |
-
"os.environ['PYTHONPATH'] = '/content/stocker'\n",
|
| 116 |
-
"j = subprocess.Popen(\n",
|
| 117 |
-
" [\n",
|
| 118 |
-
" 'jupyter', 'server',\n",
|
| 119 |
-
" f'--ServerApp.token={TOKEN}',\n",
|
| 120 |
-
" '--ServerApp.password=',\n",
|
| 121 |
-
" f'--ServerApp.port={PORT}',\n",
|
| 122 |
-
" '--ServerApp.ip=127.0.0.1',\n",
|
| 123 |
-
" '--ServerApp.allow_origin=*',\n",
|
| 124 |
-
" '--ServerApp.disable_check_xsrf=True',\n",
|
| 125 |
-
" '--ServerApp.allow_remote_access=True',\n",
|
| 126 |
-
" '--no-browser',\n",
|
| 127 |
-
" f'--ServerApp.root_dir=/content/stocker',\n",
|
| 128 |
-
" ],\n",
|
| 129 |
-
" stdout=open(LOG_J, 'w'),\n",
|
| 130 |
-
" stderr=subprocess.STDOUT,\n",
|
| 131 |
-
" cwd='/content/stocker',\n",
|
| 132 |
-
")\n",
|
| 133 |
-
"time.sleep(3)\n",
|
| 134 |
-
"assert j.poll() is None, f'jupyter-server died:\\n{LOG_J.read_text()[-2000:]}'\n",
|
| 135 |
-
"print('jupyter-server up on port', PORT)\n",
|
| 136 |
-
"\n",
|
| 137 |
-
"# Start the cloudflared quick tunnel.\n",
|
| 138 |
-
"c = subprocess.Popen(\n",
|
| 139 |
-
" ['cloudflared', 'tunnel', '--url', f'http://127.0.0.1:{PORT}', '--no-autoupdate'],\n",
|
| 140 |
-
" stdout=open(LOG_C, 'w'),\n",
|
| 141 |
-
" stderr=subprocess.STDOUT,\n",
|
| 142 |
-
")\n",
|
| 143 |
-
"\n",
|
| 144 |
-
"# Wait for the public URL to appear in the cloudflared log.\n",
|
| 145 |
-
"url = None\n",
|
| 146 |
-
"for _ in range(40):\n",
|
| 147 |
-
" time.sleep(1)\n",
|
| 148 |
-
" txt = LOG_C.read_text() if LOG_C.exists() else ''\n",
|
| 149 |
-
" m = re.search(r'https://[a-z0-9-]+\\.trycloudflare\\.com', txt)\n",
|
| 150 |
-
" if m:\n",
|
| 151 |
-
" url = m.group(0)\n",
|
| 152 |
-
" break\n",
|
| 153 |
-
"assert url, f'cloudflared did not produce a URL:\\n{LOG_C.read_text()[-2000:]}'\n",
|
| 154 |
-
"\n",
|
| 155 |
-
"FULL = f'{url}/?token={TOKEN}'\n",
|
| 156 |
-
"print('\\n' + '=' * 70)\n",
|
| 157 |
-
"print('Paste this into VSCode -> Jupyter: Specify Jupyter Server for Connections:')\n",
|
| 158 |
-
"print()\n",
|
| 159 |
-
"print(' ', FULL)\n",
|
| 160 |
-
"print()\n",
|
| 161 |
-
"print('Or use it from anywhere: curl -s', f'\"{FULL}/api/status\"')\n",
|
| 162 |
-
"print('=' * 70)\n",
|
| 163 |
-
"print('\\nKeep this Colab tab open. The tunnel dies when the runtime disconnects.')"
|
| 164 |
-
]
|
| 165 |
},
|
| 166 |
{
|
| 167 |
"cell_type": "markdown",
|
|
@@ -202,9 +138,15 @@
|
|
| 202 |
}
|
| 203 |
],
|
| 204 |
"metadata": {
|
| 205 |
-
"kernelspec": {
|
| 206 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
},
|
| 208 |
"nbformat": 4,
|
| 209 |
"nbformat_minor": 5
|
| 210 |
-
}
|
|
|
|
| 44 |
"outputs": [],
|
| 45 |
"source": [
|
| 46 |
"import os\n",
|
| 47 |
+
"REPO_URL = 'https://github.com/CRIMSONHydra/stocker.git' # <-- edit me\n",
|
| 48 |
"WORKDIR = '/content/stocker'\n",
|
| 49 |
"if not os.path.isdir(WORKDIR):\n",
|
| 50 |
" assert '<your-username>' not in REPO_URL, 'Edit REPO_URL first.'\n",
|
|
|
|
| 97 |
"id": "launch",
|
| 98 |
"metadata": {},
|
| 99 |
"outputs": [],
|
| 100 |
+
"source": "import os, re, secrets, signal, socket, subprocess, sys, time, pathlib\n\nTOKEN = secrets.token_urlsafe(24)\nPORT = 9988\nLOG_J = pathlib.Path('/content/jupyter.log')\nLOG_C = pathlib.Path('/content/cloudflared.log')\nWORKDIR = '/content/stocker'\n\n# We track the PIDs of OUR own children so re-running this cell can clean up\n# without `pkill -f jupyter-server` (which would also kill Colab's backend\n# and disconnect the runtime!).\nPID_DIR = pathlib.Path('/tmp/stocker_launcher_pids'); PID_DIR.mkdir(exist_ok=True)\n\ndef _kill_prev(name: str) -> None:\n pf = PID_DIR / f'{name}.pid'\n if not pf.exists():\n return\n try:\n pid = int(pf.read_text().strip())\n os.kill(pid, signal.SIGKILL)\n except (ProcessLookupError, ValueError):\n pass\n pf.unlink(missing_ok=True)\n\n_kill_prev('jupyter'); _kill_prev('cloudflared')\nLOG_J.write_text(''); LOG_C.write_text('')\n\ndef _port_free(p: int) -> bool:\n with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:\n return s.connect_ex(('127.0.0.1', p)) != 0\n\nif not _port_free(PORT):\n raise RuntimeError(\n f'Port {PORT} still in use. Re-run after a moment, or restart the '\n f'runtime (Runtime > Restart session) and re-run all cells.'\n )\n\n# --- jupyter-server -------------------------------------------------------\nos.environ['PYTHONPATH'] = WORKDIR\nj = subprocess.Popen(\n [\n sys.executable, '-m', 'jupyter', 'server',\n f'--ServerApp.token={TOKEN}',\n '--ServerApp.password=',\n f'--ServerApp.port={PORT}',\n '--ServerApp.ip=127.0.0.1',\n '--ServerApp.allow_origin=*',\n '--ServerApp.disable_check_xsrf=True',\n '--ServerApp.allow_remote_access=True',\n '--no-browser',\n f'--ServerApp.root_dir={WORKDIR}',\n ],\n stdout=open(LOG_J, 'w'),\n stderr=subprocess.STDOUT,\n cwd=WORKDIR,\n)\n(PID_DIR / 'jupyter.pid').write_text(str(j.pid))\ntime.sleep(3)\nif j.poll() is not None:\n raise RuntimeError(f'jupyter-server died:\\n{LOG_J.read_text()[-2000:]}')\nprint(f'jupyter-server up on 127.0.0.1:{PORT} (pid={j.pid})')\n\n# --- cloudflared (with --logfile, NOT shell redirection) ------------------\nc = subprocess.Popen(\n ['cloudflared', 'tunnel',\n '--url', f'http://127.0.0.1:{PORT}',\n '--no-autoupdate',\n '--loglevel', 'info',\n '--logfile', str(LOG_C)],\n stdout=subprocess.DEVNULL,\n stderr=subprocess.DEVNULL,\n)\n(PID_DIR / 'cloudflared.pid').write_text(str(c.pid))\n\nprint('cloudflared starting (typical: 5-30s) ', end='', flush=True)\nurl, deadline = None, time.time() + 120\nURL_RE = re.compile(r'https://[a-z0-9-]+\\.trycloudflare\\.com')\nwhile time.time() < deadline:\n if c.poll() is not None:\n print(f'\\ncloudflared exited unexpectedly:\\n{LOG_C.read_text()[-2000:]}', file=sys.stderr)\n break\n txt = LOG_C.read_text() if LOG_C.exists() else ''\n m = URL_RE.search(txt)\n if m:\n url = m.group(0)\n break\n print('.', end='', flush=True)\n time.sleep(2)\nprint()\n\nif not url:\n raise RuntimeError(\n 'cloudflared did not produce a URL within 120s.\\n'\n '----- last 2KB of cloudflared log -----\\n'\n + LOG_C.read_text()[-2000:]\n + '\\n----- last 1KB of jupyter log -----\\n'\n + LOG_J.read_text()[-1000:]\n )\n\nFULL = f'{url}/?token={TOKEN}'\nprint('=' * 70)\nprint('Paste this into VSCode -> Jupyter: Specify Jupyter Server for Connections')\nprint()\nprint(' ', FULL)\nprint()\nprint('Smoke-test from anywhere:')\nprint(f' curl -s \"{FULL}/api/status\" | head -c 200')\nprint('=' * 70)\nprint('\\nKeep this Colab tab open — the tunnel dies when the runtime disconnects.')"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
},
|
| 102 |
{
|
| 103 |
"cell_type": "markdown",
|
|
|
|
| 138 |
}
|
| 139 |
],
|
| 140 |
"metadata": {
|
| 141 |
+
"kernelspec": {
|
| 142 |
+
"display_name": "Python 3",
|
| 143 |
+
"language": "python",
|
| 144 |
+
"name": "python3"
|
| 145 |
+
},
|
| 146 |
+
"language_info": {
|
| 147 |
+
"name": "python"
|
| 148 |
+
}
|
| 149 |
},
|
| 150 |
"nbformat": 4,
|
| 151 |
"nbformat_minor": 5
|
| 152 |
+
}
|