# Copyright 2018 Michael Lin. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== """Contains code for adding common services to non-persistent `colaboratory` VM sessions When training on `colaboratory` VMs it it often useful to monitor the session via `tensorboard`. This script helps you launches tensorboard on the `colaboratory` VM and uses `ngrok` to create a secure introspective tunnel to access tensorboard via public URL. see: https://stackoverflow.com/questions/47818822/can-i-use-tensorboard-with-google-colab ************************************ * A simple working script * ************************************ ``` import os import colab_utils.tboard # set paths ROOT = %pwd LOG_DIR = os.path.join(ROOT, 'log') # will install `ngrok`, if necessary # will create `log_dir` if path does not exist tboard.launch_tensorboard( bin_dir=ROOT, log_dir=LOG_DIR ) ``` """ import os import requests import shutil import subprocess import tensorflow as tf __all__ = [ 'install_ngrok', 'launch_tensorboard', ] def __shell__(cmd, split=True): # get_ipython().system_raw(cmd) result = get_ipython().getoutput(cmd, split=split) if result and not split: result = result.strip('\n') return result # tested OK def install_ngrok(bin_dir="/tmp"): """ download and install ngrok on local vm instance Args: bin_dir: full path for the target directory for the `ngrok` binary """ TARGET_DIR = bin_dir CWD = os.getcwd() is_grok_avail = os.path.isfile(os.path.join(TARGET_DIR,'ngrok')) if is_grok_avail: print("ngrok installed") else: import platform plat = platform.platform() # 'Linux-4.4.64+-x86_64-with-Ubuntu-17.10-artful' if 'x86_64' in plat: os.chdir('/tmp') print("calling wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip ..." ) get_ipython().system_raw( "wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip" ) print("calling unzip ngrok-stable-linux-amd64.zip ...") get_ipython().system_raw( "unzip ngrok-stable-linux-amd64.zip" ) os.rename("ngrok", "{}/ngrok".format(TARGET_DIR)) os.remove("ngrok-stable-linux-amd64.zip") is_grok_avail = os.path.isfile(os.path.join(TARGET_DIR,'ngrok')) os.chdir(TARGET_DIR) if is_grok_avail: print("ngrok installed. path={}".format(os.path.join(TARGET_DIR,'ngrok'))) else: # ValueError: ERROR: ngrok not found, path= raise ValueError( "ERROR: ngrok not found, path=".format(TARGET_DIR) ) else: raise NotImplementedError( "ERROR, ngrok install not configured for this platform, platform={}".format(plat)) os.chdir(CWD) return # tested OK def launch_tensorboard(bin_dir="/tmp", log_dir="/tmp", retval=False): """returns a public tensorboard url based on the ngrok package checks if `ngrok` is available, and installs, if necessary, to `bin_dir` launches tensorboard, if necessary see: https://stackoverflow.com/questions/47818822/can-i-use-tensorboard-with-google-colab Args: bin_dir: full path for the target directory for the `ngrok` binary log_dir: full path for the tensorflow `log_dir` Return: public url for tensorboard if retval==True NOTE: the method will print a link to stdout (cell output) for the tensorflow URL. But the link printed from the return value has an extra "%27" in the URL which causes an error """ install_ngrok(bin_dir) if not os.path.isdir(log_dir): os.makedirs(log_dir) # check status of tensorboard and ngrok ps = __shell__("ps -ax") is_tensorboard_running = len([f for f in ps if "tensorboard" in f ]) > 0 is_ngrok_running = len([f for f in ps if "ngrok" in f ]) > 0 print("status: tensorboard={}, ngrok={}".format(is_tensorboard_running, is_ngrok_running)) if not is_tensorboard_running: get_ipython().system_raw( 'tensorboard --logdir {} --host 0.0.0.0 --port 6006 &' .format(log_dir) ) is_tensorboard_running = True if not is_ngrok_running: # grok should be installed in /tmp/ngrok get_ipython().system_raw('{}/ngrok http 6006 &'.format(bin_dir)) is_ngrok_running = True # get tensorboard url # BUG: getting connection refused for HTTPConnectionPool(host='localhost', port=4040) # on first run, retry works import time time.sleep(3) retval = requests.get('http://localhost:4040/api/tunnels') tensorboard_url = retval.json()['tunnels'][0]['public_url'].strip() print("tensorboard url=", tensorboard_url) if retval: return tensorboard_url