Load trace_processor binary if the path to it is defined

Change-Id: If2249dcf965e8a590cd22071be138bdfe26be791
diff --git a/src/trace_processor/python/example.py b/src/trace_processor/python/example.py
index fd27903..9f6c784 100644
--- a/src/trace_processor/python/example.py
+++ b/src/trace_processor/python/example.py
@@ -26,18 +26,24 @@
       "--address",
       help="Address at which trace_processor is being run, e.g. localhost:9001",
       type=str)
+  parser.add_argument(
+      "-b",
+      "--binary",
+      help="Absolute path to a trace processor binary",
+      type=str)
   parser.add_argument("-f", "--file", help="Absolute path to trace", type=str)
   args = parser.parse_args()
 
   # Pass arguments into api to construct the trace processor and load the trace
-  if args.address == None and args.file == None:
+  if args.address is None and args.file is None:
     raise Exception("You must specify an address or a file path to trace")
-  elif args.address == None:
-    tp = TraceProcessor(file_path=args.file)
-  elif args.file == None:
-    tp = TraceProcessor(uri=args.address)
+  elif args.address is None:
+    tp = TraceProcessor(file_path=args.file, bin_path=args.binary)
+  elif args.file is None:
+    tp = TraceProcessor(addr=args.address)
   else:
-    tp = TraceProcessor(uri=args.address, file_path=args.file)
+    tp = TraceProcessor(
+        addr=args.address, file_path=args.file, bin_path=args.binary)
 
   # Call functions on the loaded trace
   res_it = tp.query('select * from slice limit 10')
diff --git a/src/trace_processor/python/trace_processor/api.py b/src/trace_processor/python/trace_processor/api.py
index bd5175d..9529fa3 100644
--- a/src/trace_processor/python/trace_processor/api.py
+++ b/src/trace_processor/python/trace_processor/api.py
@@ -77,13 +77,13 @@
       self.__next_index = self.__next_index + len(self.__column_names)
       return row
 
-  def __init__(self, uri=None, file_path=None):
+  def __init__(self, addr=None, file_path=None, bin_path=None):
     # Load trace_processor_shell or access via given address
-    if uri:
-      p = urlparse(uri)
+    if addr:
+      p = urlparse(addr)
       tp = TraceProcessorHttp(p.netloc if p.netloc else p.path)
     else:
-      url, self.subprocess = load_shell()
+      url, self.subprocess = load_shell(bin_path=bin_path)
       tp = TraceProcessorHttp(url)
     self.http = tp
 
diff --git a/src/trace_processor/python/trace_processor/shell.py b/src/trace_processor/python/trace_processor/shell.py
index c77a95d..dd68a50 100644
--- a/src/trace_processor/python/trace_processor/shell.py
+++ b/src/trace_processor/python/trace_processor/shell.py
@@ -14,6 +14,7 @@
 # limitations under the License.
 
 from urllib import request, error
+import os
 import subprocess
 import tempfile
 import time
@@ -22,19 +23,24 @@
 SHELL_URL = 'http://get.perfetto.dev/trace_processor'
 
 
-def load_shell():
+def load_shell(bin_path=None):
   try:
     from .shell_vendor import load_shell_vendor
     shell_path = load_shell_vendor()
   except ModuleNotFoundError:
-    # TODO(@aninditaghosh): Try to use preexisting binary before
-    # attempting to download trace_processor
-    with tempfile.NamedTemporaryFile(delete=False) as file:
-      req = request.Request(SHELL_URL)
-      with request.urlopen(req) as req:
-        file.write(req.read())
-    shell_path = file.name
-    subprocess.check_output(['chmod', '+x', shell_path])
+    # Try to use preexisting binary before attempting to download
+    # trace_processor
+    if bin_path is None:
+      with tempfile.NamedTemporaryFile(delete=False) as file:
+        req = request.Request(SHELL_URL)
+        with request.urlopen(req) as req:
+          file.write(req.read())
+      shell_path = file.name
+      subprocess.check_output(['chmod', '+x', shell_path])
+    else:
+      if not os.path.isfile(bin_path):
+        raise Exception('Path to binary is not valid')
+      shell_path = bin_path
 
   p = subprocess.Popen([shell_path, '-D'], stdout=subprocess.DEVNULL)