We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Use Binder Build API for Builds in PRs
# Description

After a discussion with @minrk and @betatim on the jupyterhub/binder Gitter, it was made clear that the use of Selenium in [`binder/trigger_binder.py`](https://github.com/diana-hep/pyhf/blob/c81f6007309f4c13241f9efac187594337d0bd08/binder/trigger_binder.py) (and the script itself) is unnecessary. Instead a simple API call can be made just using Python's `webbrowser` with an [endpoint of the form `https://mybinder.org/build/gh/owner/repo/ref`](https://gitter.im/jupyterhub/binder?at=5c2f87038dafa715c73ff54f) as can be [seen in the Binder Hub demo](https://github.com/jupyterhub/binderhub/blob/9ca8fa68bb8b69c6a2736f2275279583073f314f/examples/binder-api.py#L28) (thanks Tim for the link).

So, for example

```
python -m webbrowser "https://mybinder.org/build/gh/diana-hep/pyhf/master"
```

So asking [WWKHTD](https://github.com/kelseyhightower/nocode), this means that `binder/trigger_binder.py` is unnecessary and should be removed and `.travis.yml` should be updated to use the API calls.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `binder/trigger_binder.py`
Content:
```
1 #!/usr/bin/env python
2 
3 import argparse
4 from contextlib import contextmanager
5 from selenium import webdriver
6 from selenium.webdriver.chrome.options import Options
7 from selenium.webdriver.support.ui import WebDriverWait
8 from selenium.webdriver.support.expected_conditions import staleness_of
9 
10 
11 class SeleniumSession:
12     def __init__(self, args):
13         self.options = Options()
14         self.options.set_headless()
15         self.options.add_argument('--no-sandbox')
16         if args.chromedriver_path is not None:
17             self.browser = webdriver.Chrome(
18                 args.chromedriver_path, chrome_options=self.options
19             )
20         else:
21             self.browser = webdriver.Chrome(chrome_options=self.options)
22 
23     @contextmanager
24     def wait_for_page_load(self, timeout=20):
25         old_page = self.browser.find_element_by_tag_name('html')
26         yield
27         WebDriverWait(self.browser, timeout).until(staleness_of(old_page))
28 
29     def trigger_binder(self, url):
30         with self.wait_for_page_load():
31             self.browser.get(url)
32 
33 
34 def main(args):
35     driver = SeleniumSession(args)
36     if args.is_verbose:
37         print('Chrome Headless Browser Invoked')
38     driver.trigger_binder(args.url)
39 
40 
41 if __name__ == '__main__':
42     parser = argparse.ArgumentParser()
43     parser.add_argument(
44         '-v',
45         '--verbose',
46         dest='is_verbose',
47         action='store_true',
48         help='Print out more information',
49     )
50     parser.add_argument(
51         '--chromedriver-path',
52         dest='chromedriver_path',
53         type=str,
54         default=None,
55         help='System path to ChromeDriver',
56     )
57     parser.add_argument(
58         '--url', dest='url', type=str, default=None, help='URL for Selinium to open'
59     )
60     args = parser.parse_args()
61 
62     main(args)
63
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/binder/trigger_binder.py b/binder/trigger_binder.py
deleted file mode 100644
--- a/binder/trigger_binder.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env python
-
-import argparse
-from contextlib import contextmanager
-from selenium import webdriver
-from selenium.webdriver.chrome.options import Options
-from selenium.webdriver.support.ui import WebDriverWait
-from selenium.webdriver.support.expected_conditions import staleness_of
-
-
-class SeleniumSession:
-    def __init__(self, args):
-        self.options = Options()
-        self.options.set_headless()
-        self.options.add_argument('--no-sandbox')
-        if args.chromedriver_path is not None:
-            self.browser = webdriver.Chrome(
-                args.chromedriver_path, chrome_options=self.options
-            )
-        else:
-            self.browser = webdriver.Chrome(chrome_options=self.options)
-
-    @contextmanager
-    def wait_for_page_load(self, timeout=20):
-        old_page = self.browser.find_element_by_tag_name('html')
-        yield
-        WebDriverWait(self.browser, timeout).until(staleness_of(old_page))
-
-    def trigger_binder(self, url):
-        with self.wait_for_page_load():
-            self.browser.get(url)
-
-
-def main(args):
-    driver = SeleniumSession(args)
-    if args.is_verbose:
-        print('Chrome Headless Browser Invoked')
-    driver.trigger_binder(args.url)
-
-
-if __name__ == '__main__':
-    parser = argparse.ArgumentParser()
-    parser.add_argument(
-        '-v',
-        '--verbose',
-        dest='is_verbose',
-        action='store_true',
-        help='Print out more information',
-    )
-    parser.add_argument(
-        '--chromedriver-path',
-        dest='chromedriver_path',
-        type=str,
-        default=None,
-        help='System path to ChromeDriver',
-    )
-    parser.add_argument(
-        '--url', dest='url', type=str, default=None, help='URL for Selinium to open'
-    )
-    args = parser.parse_args()
-
-    main(args)

{"golden_diff": "diff --git a/binder/trigger_binder.py b/binder/trigger_binder.py\ndeleted file mode 100644\n--- a/binder/trigger_binder.py\n+++ /dev/null\n@@ -1,62 +0,0 @@\n-#!/usr/bin/env python\n-\n-import argparse\n-from contextlib import contextmanager\n-from selenium import webdriver\n-from selenium.webdriver.chrome.options import Options\n-from selenium.webdriver.support.ui import WebDriverWait\n-from selenium.webdriver.support.expected_conditions import staleness_of\n-\n-\n-class SeleniumSession:\n-    def __init__(self, args):\n-        self.options = Options()\n-        self.options.set_headless()\n-        self.options.add_argument('--no-sandbox')\n-        if args.chromedriver_path is not None:\n-            self.browser = webdriver.Chrome(\n-                args.chromedriver_path, chrome_options=self.options\n-            )\n-        else:\n-            self.browser = webdriver.Chrome(chrome_options=self.options)\n-\n-    @contextmanager\n-    def wait_for_page_load(self, timeout=20):\n-        old_page = self.browser.find_element_by_tag_name('html')\n-        yield\n-        WebDriverWait(self.browser, timeout).until(staleness_of(old_page))\n-\n-    def trigger_binder(self, url):\n-        with self.wait_for_page_load():\n-            self.browser.get(url)\n-\n-\n-def main(args):\n-    driver = SeleniumSession(args)\n-    if args.is_verbose:\n-        print('Chrome Headless Browser Invoked')\n-    driver.trigger_binder(args.url)\n-\n-\n-if __name__ == '__main__':\n-    parser = argparse.ArgumentParser()\n-    parser.add_argument(\n-        '-v',\n-        '--verbose',\n-        dest='is_verbose',\n-        action='store_true',\n-        help='Print out more information',\n-    )\n-    parser.add_argument(\n-        '--chromedriver-path',\n-        dest='chromedriver_path',\n-        type=str,\n-        default=None,\n-        help='System path to ChromeDriver',\n-    )\n-    parser.add_argument(\n-        '--url', dest='url', type=str, default=None, help='URL for Selinium to open'\n-    )\n-    args = parser.parse_args()\n-\n-    main(args)\n", "issue": "Use Binder Build API for Builds in PRs\n# Description\r\n\r\nAfter a discussion with @minrk and @betatim on the jupyterhub/binder Gitter, it was made clear that the use of Selenium in [`binder/trigger_binder.py`](https://github.com/diana-hep/pyhf/blob/c81f6007309f4c13241f9efac187594337d0bd08/binder/trigger_binder.py) (and the script itself) is unnecessary. Instead a simple API call can be made just using Python's `webbrowser` with an [endpoint of the form `https://mybinder.org/build/gh/owner/repo/ref`](https://gitter.im/jupyterhub/binder?at=5c2f87038dafa715c73ff54f) as can be [seen in the Binder Hub demo](https://github.com/jupyterhub/binderhub/blob/9ca8fa68bb8b69c6a2736f2275279583073f314f/examples/binder-api.py#L28) (thanks Tim for the link).\r\n\r\nSo, for example\r\n\r\n```\r\npython -m webbrowser \"https://mybinder.org/build/gh/diana-hep/pyhf/master\"\r\n```\r\n\r\nSo asking [WWKHTD](https://github.com/kelseyhightower/nocode), this means that `binder/trigger_binder.py` is unnecessary and should be removed and `.travis.yml` should be updated to use the API calls.\n", "before_files": [{"content": "#!/usr/bin/env python\n\nimport argparse\nfrom contextlib import contextmanager\nfrom selenium import webdriver\nfrom selenium.webdriver.chrome.options import Options\nfrom selenium.webdriver.support.ui import WebDriverWait\nfrom selenium.webdriver.support.expected_conditions import staleness_of\n\n\nclass SeleniumSession:\n    def __init__(self, args):\n        self.options = Options()\n        self.options.set_headless()\n        self.options.add_argument('--no-sandbox')\n        if args.chromedriver_path is not None:\n            self.browser = webdriver.Chrome(\n                args.chromedriver_path, chrome_options=self.options\n            )\n        else:\n            self.browser = webdriver.Chrome(chrome_options=self.options)\n\n    @contextmanager\n    def wait_for_page_load(self, timeout=20):\n        old_page = self.browser.find_element_by_tag_name('html')\n        yield\n        WebDriverWait(self.browser, timeout).until(staleness_of(old_page))\n\n    def trigger_binder(self, url):\n        with self.wait_for_page_load():\n            self.browser.get(url)\n\n\ndef main(args):\n    driver = SeleniumSession(args)\n    if args.is_verbose:\n        print('Chrome Headless Browser Invoked')\n    driver.trigger_binder(args.url)\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\n        '-v',\n        '--verbose',\n        dest='is_verbose',\n        action='store_true',\n        help='Print out more information',\n    )\n    parser.add_argument(\n        '--chromedriver-path',\n        dest='chromedriver_path',\n        type=str,\n        default=None,\n        help='System path to ChromeDriver',\n    )\n    parser.add_argument(\n        '--url', dest='url', type=str, default=None, help='URL for Selinium to open'\n    )\n    args = parser.parse_args()\n\n    main(args)\n", "path": "binder/trigger_binder.py"}], "after_files": [{"content": null, "path": "binder/trigger_binder.py"}]}