From ed7fcfdf693d1e10b4831490f129464891228543 Mon Sep 17 00:00:00 2001 From: Tim Head Date: Tue, 20 Aug 2019 07:47:47 +0200 Subject: [PATCH] Check if nbviewer URL would show an error If the nbviewer widget would show a 404 or other error we don't want to display it. We check the status before rendering the template by making a HEAD request to nbviewer, if the status code is >=400 we don't show the preview. --- binderhub/main.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/binderhub/main.py b/binderhub/main.py index 33331086a2..e9f04d1b0b 100644 --- a/binderhub/main.py +++ b/binderhub/main.py @@ -1,6 +1,7 @@ """ Main handler classes for requests """ +from tornado.httpclient import AsyncHTTPClient from tornado.web import HTTPError, authenticated from tornado.httputil import url_concat from tornado.log import app_log @@ -15,6 +16,7 @@ "zenodo": "Zenodo" } + class MainHandler(BaseHandler): """Main handler for requests""" @@ -35,7 +37,7 @@ class ParameterizedMainHandler(BaseHandler): """Main handler that allows different parameter settings""" @authenticated - def get(self, provider_prefix, _unescaped_spec): + async def get(self, provider_prefix, _unescaped_spec): prefix = '/v2/' + provider_prefix spec = self.get_spec_from_request(prefix) spec = spec.rstrip("/") @@ -61,14 +63,25 @@ def get(self, provider_prefix, _unescaped_spec): org, repo_name, ref = spec.split('/', 2) # NOTE: tornado unquotes query arguments too -> notebooks%2Findex.ipynb becomes notebooks/index.ipynb filepath = self.get_argument('filepath', '').lstrip('/') - + # Check if we have a JupyterLab + file path, if so then use it for the filepath urlpath = self.get_argument('urlpath', '').lstrip('/') if urlpath.startswith("lab") and "/tree/" in urlpath: filepath = urlpath.split('tree/', 1)[-1] - + blob_or_tree = 'blob' if filepath else 'tree' nbviewer_url = f'{nbviewer_url}/{org}/{repo_name}/{blob_or_tree}/{ref}/{filepath}' + + # Check if the nbviewer URL is valid and would display something + # useful to the reader, if not we don't show it + client = AsyncHTTPClient() + response = await client.fetch(nbviewer_url, + method="HEAD", + user_agent="BinderHub", + raise_error=False) + if response.code >= 400: + nbviewer_url = None + self.render_template( "loading.html", base_url=self.settings['base_url'],