def get(self, path):
        """
        Inject the user's KBase cookie before trying to look up a file.
        One of our big use cases bypasses the typical Jupyter login mechanism.
        """
        cookie_regex = re.compile('([^ =|]+)=([^\|]*)')

        client_ip = self.request.remote_ip
        http_headers = self.request.headers
        ua = http_headers.get('User-Agent', 'unknown')

        found_cookies = [self.cookies[c] for c in all_cookies if c in self.cookies]
        if found_cookies:
            cookie_val = urllib.unquote(found_cookies[0].value)
            cookie_obj = {
                k: v.replace('EQUALSSIGN', '=').replace('PIPESIGN', '|')
                for k, v in cookie_regex.findall(cookie_val) 
            }
        # if app_log.isEnabledFor(logging.DEBUG):
        #     app_log.debug("kbase cookie = {}".format(cookie_val))
        #     app_log.debug("KBaseLoginHandler.get: user_id={uid} token={tok}"
        #         .format(uid=sess.get('token', 'none'),
        #                 tok=sess.get('token', 'none')))

        biokbase.auth.set_environ_token(cookie_obj.get('token', None))
        kbase_env.session = cookie_obj.get('kbase_sessionid', '')
        kbase_env.client_ip = client_ip
        kbase_env.user = cookie_obj.get('user_id', '')
        log_event(g_log, 'session_start', {'user': kbase_env.user, 'user_agent': ua})



        """get renders the notebook template if a name is given, or 
        redirects to the '/files/' handler if the name is not given."""

        path = path.strip('/')
        cm = self.contents_manager

        # will raise 404 on not found
        try:
            model = cm.get(path, content=False)
        except web.HTTPError as e:
            raise
            # if e.status_code == 404 and 'files' in path.split('/'):
            #     # 404, but '/files/' in URL, let FilesRedirect take care of it
            #     return FilesRedirectHandler.redirect_to_files(self, path)
            # else:
            #     raise
        if model['type'] != 'notebook':
            # not a notebook, redirect to files
            return FilesRedirectHandler.redirect_to_files(self, path)
        name = url_escape(path.rsplit('/', 1)[-1])
        path = url_escape(path)
        self.write(self.render_template('notebook.html',
            notebook_path=path,
            notebook_name=path,
            kill_kernel=False,
            mathjax_url=self.mathjax_url,
            )
        )
Example #2
0
    def redirect_to_files(self, path):
        """make redirect logic a reusable static method
        
        so it can be called from other handlers.
        """
        cm = self.contents_manager
        if cm.dir_exists(path):
            # it's a *directory*, redirect to /tree
            url = url_path_join(self.base_url, 'tree', url_escape(path))
        else:
            orig_path = path
            # otherwise, redirect to /files
            parts = path.split('/')

            if not cm.file_exists(path=path) and 'files' in parts:
                # redirect without files/ iff it would 404
                # this preserves pre-2.0-style 'files/' links
                self.log.warning("Deprecated files/ URL: %s", orig_path)
                parts.remove('files')
                path = '/'.join(parts)

            if not cm.file_exists(path=path):
                raise web.HTTPError(404)

            url = url_path_join(self.base_url, 'files', url_escape(path))
        self.log.debug("Redirecting %s to %s", self.request.path, url)
        self.redirect(url)
Example #3
0
    def redirect_to_files(self, path):
        """make redirect logic a reusable static method
        
        so it can be called from other handlers.
        """
        cm = self.contents_manager
        if cm.dir_exists(path):
            # it's a *directory*, redirect to /tree
            url = url_path_join(self.base_url, 'tree', url_escape(path))
        else:
            orig_path = path
            # otherwise, redirect to /files
            parts = path.split('/')

            if not cm.file_exists(path=path) and 'files' in parts:
                # redirect without files/ iff it would 404
                # this preserves pre-2.0-style 'files/' links
                self.log.warning("Deprecated files/ URL: %s", orig_path)
                parts.remove('files')
                path = '/'.join(parts)

            if not cm.file_exists(path=path):
                raise web.HTTPError(404)

            url = url_path_join(self.base_url, 'files', url_escape(path))
        self.log.debug("Redirecting %s to %s", self.request.path, url)
        self.redirect(url)
Example #4
0
    def get(self, path):
        """
        Inject the user's KBase cookie before trying to look up a file.
        One of our big use cases bypasses the typical Jupyter login mechanism.
        """
        cookie_regex = re.compile('([^ =|]+)=([^\|]*)')

        client_ip = self.request.remote_ip
        http_headers = self.request.headers
        ua = http_headers.get('User-Agent', 'unknown')

        auth_cookie = self.cookies.get(auth_cookie_name, None)
        if auth_cookie:
            cookie_val = urllib.unquote(auth_cookie.value)
            cookie_obj = {
                k: v.replace('EQUALSSIGN', '=').replace('PIPESIGN', '|')
                for k, v in cookie_regex.findall(cookie_val)
            }
        else:
            raise web.HTTPError(status_code=401, log_message='No auth cookie, denying access', reason='Authorization required for Narrative access')

        biokbase.auth.set_environ_token(cookie_obj.get('token', None))
        kbase_env.session = cookie_obj.get('kbase_sessionid', '')
        kbase_env.client_ip = client_ip
        kbase_env.user = cookie_obj.get('user_id', '')
        log_event(g_log, 'session_start', {'user': kbase_env.user, 'user_agent': ua})



        """get renders the notebook template if a name is given, or
        redirects to the '/files/' handler if the name is not given."""

        path = path.strip('/')
        cm = self.contents_manager

        # will raise 404 on not found
        try:
            model = cm.get(path, content=False)
        except web.HTTPError as e:
            raise
            # if e.status_code == 404 and 'files' in path.split('/'):
            #     # 404, but '/files/' in URL, let FilesRedirect take care of it
            #     return FilesRedirectHandler.redirect_to_files(self, path)
            # else:
            #     raise
        if model['type'] != 'notebook':
            # not a notebook, redirect to files
            return FilesRedirectHandler.redirect_to_files(self, path)
        name = url_escape(path.rsplit('/', 1)[-1])
        path = url_escape(path)
        self.write(self.render_template('notebook.html',
            notebook_path=path,
            notebook_name=path,
            kill_kernel=False,
            mathjax_url=self.mathjax_url,
            )
        )
Example #5
0
 def post(self, path=''):
     """post creates a new checkpoint"""
     cm = self.contents_manager
     checkpoint = yield maybe_future(cm.create_checkpoint(path))
     data = json.dumps(checkpoint, default=date_default)
     location = url_path_join(self.base_url, 'api/contents',
         url_escape(path), 'checkpoints', url_escape(checkpoint['id']))
     self.set_header('Location', location)
     self.set_status(201)
     self.finish(data)
Example #6
0
 def post(self, path=''):
     """post creates a new checkpoint"""
     cm = self.contents_manager
     checkpoint = yield maybe_future(cm.create_checkpoint(path))
     data = json.dumps(checkpoint, default=date_default)
     location = url_path_join(self.base_url, 'api/contents',
         url_escape(path), 'checkpoints', url_escape(checkpoint['id']))
     self.set_header('Location', location)
     self.set_status(201)
     self.finish(data)
Example #7
0
    def get(self, path):
        """
        Inject the user's KBase cookie before trying to look up a file.
        One of our big use cases bypasses the typical Jupyter login mechanism.
        """
        client_ip = self.request.remote_ip
        http_headers = self.request.headers
        ua = http_headers.get('User-Agent', 'unknown')

        auth_cookie = self.cookies.get(auth_cookie_name, None)
        if auth_cookie:
            token = urllib.unquote(auth_cookie.value)
        else:
            raise web.HTTPError(
                status_code=401,
                log_message='No auth cookie, denying access',
                reason='Authorization required for Narrative access')

        if token != kbase_env.auth_token:
            init_session_env(get_user_info(token), client_ip)
            log_event(g_log, 'session_start', {
                'user': kbase_env.user,
                'user_agent': ua
            })
        """
        get renders the notebook template if a name is given, or
        redirects to the '/files/' handler if the name is not given.
        """

        path = path.strip('/')
        cm = self.contents_manager

        # will raise 404 on not found
        try:
            model = cm.get(path, content=False)
        except web.HTTPError as e:
            raise
            # if e.status_code == 404 and 'files' in path.split('/'):
            #     # 404, but '/files/' in URL, let FilesRedirect take care of it
            #     return FilesRedirectHandler.redirect_to_files(self, path)
            # else:
            #     raise
        if model['type'] != 'notebook':
            # not a notebook, redirect to files
            return FilesRedirectHandler.redirect_to_files(self, path)
        name = url_escape(path.rsplit('/', 1)[-1])
        path = url_escape(path)
        self.write(
            self.render_template('notebook.html',
                                 notebook_path=path,
                                 notebook_name=path,
                                 kill_kernel=False,
                                 mathjax_url=self.mathjax_url))
    def post(self, path=''):
        """post creates a new checkpoint"""
        # grab the commit message from the posted data
        commit_message = json.loads(self.request.body.decode('utf-8')).get('commit_message', None)

        # print("CREATING NEW CHECKPOINT WITH MESSAGE: " + str(commit_message))
        cm = self.contents_manager
        checkpoint = yield gen.maybe_future(cm.create_checkpoint(path, commit_message=commit_message))
        data = json.dumps(checkpoint, default=date_default)
        location = url_path_join(self.base_url, 'api/contents',
            url_escape(path), 'checkpoints', url_escape(checkpoint['id']))
        self.set_header('Location', location)
        self.set_status(201)
        self.finish(data)
Example #9
0
def test_url_escape():

    # changes path or notebook name with special characters to url encoding
    # these tests specifically encode paths with spaces
    path = url_escape('/this is a test/for spaces/')
    assert path == '/this%20is%20a%20test/for%20spaces/'

    path = url_escape('notebook with space.ipynb')
    assert path == 'notebook%20with%20space.ipynb'

    path = url_escape('/path with a/notebook and space.ipynb')
    assert path == '/path%20with%20a/notebook%20and%20space.ipynb'

    path = url_escape('/ !@$#%^&* / test %^ notebook @#$ name.ipynb')
    assert path == '/%20%21%40%24%23%25%5E%26%2A%20/%20test%20%25%5E%20notebook%20%40%23%24%20name.ipynb'
Example #10
0
def test_url_escape():

    # changes path or notebook name with special characters to url encoding
    # these tests specifically encode paths with spaces
    path = url_escape('/this is a test/for spaces/')
    nt.assert_equal(path, '/this%20is%20a%20test/for%20spaces/')

    path = url_escape('notebook with space.ipynb')
    nt.assert_equal(path, 'notebook%20with%20space.ipynb')

    path = url_escape('/path with a/notebook and space.ipynb')
    nt.assert_equal(path, '/path%20with%20a/notebook%20and%20space.ipynb')
    
    path = url_escape('/ !@$#%^&* / test %^ notebook @#$ name.ipynb')
    nt.assert_equal(path,
        '/%20%21%40%24%23%25%5E%26%2A%20/%20test%20%25%5E%20notebook%20%40%23%24%20name.ipynb')
    def post(self):
        """Most of this is taken from the super class MainKernelHandler but we hijack the name field to specify the notebook we want to run"""
        km = self.kernel_manager
        model = self.get_json_body()
        if model is None:
            msg = "Must supply a body with a name formated like {\"name\":\<path_to_notebook>}"
            raise web.HTTPError(400, msg, reason=msg)

        name = json.loads(model.get('name', ''))
        notebook = None
        if isinstance(name, dict):
            notebook = name.get('notebook', None)
        if notebook == None:
            msg = "Must supply a body with a name formated like {\"name\":\<path_to_notebook>}"
            raise web.HTTPError(400, msg, reason=msg)
        del model['name']

        model.setdefault('name', km.default_kernel_name)

        kernel_id = yield gen.maybe_future(
            km.start_kernel(kernel_name=model['name']))
        model = km.kernel_model(kernel_id)
        location = url_path_join(self.base_url, 'api', 'kernels',
                                 url_escape(kernel_id))

        kernel_reg.add(kernel_id, notebook)
        self.set_header('Location', location)
        self.set_status(201)
        self.finish(json.dumps(model, default=date_default))
Example #12
0
def nbopen(filename):
    filename = os.path.abspath(filename)
    home_dir = os.path.expanduser('~')
    server_inf = find_best_server(filename)
    if server_inf is not None:
        print("Using existing server at", server_inf['notebook_dir'])
        path = os.path.relpath(filename, start=server_inf['notebook_dir'])
        if os.sep != '/':
            path = path.replace(os.sep, '/')
        url = url_path_join(server_inf['url'], 'notebooks', url_escape(path))
        na = notebookapp.NotebookApp.instance()
        na.load_config_file()
        browser = webbrowser.get(na.browser or None)
        browser.open(url, new=2)
    else:
        if filename.startswith(home_dir):
            nbdir = home_dir
        else:
            nbdir = os.path.dirname(filename)

        print("Starting new server")
        notebookapp.launch_new_instance(file_to_run=os.path.abspath(filename),
                                        notebook_dir=nbdir,
                                        open_browser=True,
                                        argv=[],  # Avoid it seeing our own argv
                                        )
Example #13
0
def nbopen(filename):
    filename = os.path.abspath(filename)
    home_dir = os.path.expanduser('~')
    server_inf = find_best_server(filename)
    if server_inf is not None:
        print("Using existing server at", server_inf['notebook_dir'])
        path = os.path.relpath(filename, start=server_inf['notebook_dir'])
        if os.sep != '/':
            path = path.replace(os.sep, '/')
        url = url_path_join(server_inf['url'], 'notebooks', url_escape(path))
        na = notebookapp.NotebookApp.instance()
        na.load_config_file()
        browser = webbrowser.get(na.browser or None)
        browser.open(url, new=2)
    else:
        if filename.startswith(home_dir):
            nbdir = home_dir
        else:
            nbdir = os.path.dirname(filename)

        print("Starting new server")
        # Hack: we want to override these settings if they're in the config file.
        # The application class allows 'command line' config to override config
        # loaded afterwards from the config file. So by specifying config, we
        # can use this mechanism.
        cfg = Config()
        cfg.NotebookApp.file_to_run = os.path.abspath(filename)
        cfg.NotebookApp.notebook_dir = nbdir
        cfg.NotebookApp.open_browser = True
        notebookapp.launch_new_instance(
            config=cfg,
            argv=[],  # Avoid it seeing our own argv
        )
Example #14
0
    def post(self, path=''):
        """post creates a new checkpoint"""
        # grab the commit message from the posted data
        commit_message = json.loads(self.request.body.decode('utf-8')).get(
            'commit_message', None)

        # print("CREATING NEW CHECKPOINT WITH MESSAGE: " + str(commit_message))
        cm = self.contents_manager
        checkpoint = yield gen.maybe_future(
            cm.create_checkpoint(path, commit_message=commit_message))
        data = json.dumps(checkpoint, default=date_default)
        location = url_path_join(self.base_url, 'api/contents',
                                 url_escape(path), 'checkpoints',
                                 url_escape(checkpoint['id']))
        self.set_header('Location', location)
        self.set_status(201)
        self.finish(data)
Example #15
0
    def set_attachment_header(self, filename):
        """Set Content-Disposition: attachment header

        As a method to ensure handling of filename encoding
        """
        escaped_filename = url_escape(filename)
        self.set_header(
            'Content-Disposition', 'attachment;'
            " filename*=utf-8''{utf8}".format(utf8=escaped_filename, ))
    def get(self, path):
        """
        Proxy API requests to GitHub, adding authentication parameter(s) if
        they have been set.
        """

        # Get access to the notebook config object
        c = GitHubConfig(config=self.config)
        try:
            query = self.request.query_arguments
            params = {key: query[key][0].decode() for key in query}
            api_path = url_path_join(c.api_url, url_escape(path))
            params['per_page'] = 100

            access_token = params.pop('access_token', None)
            if access_token and c.allow_client_side_access_token == True:
                token = access_token
            elif access_token and c.allow_client_side_access_token == False:
                msg = ("Client side (JupyterLab) access tokens have been "
                       "disabled for security reasons.\nPlease remove your "
                       "access token from JupyterLab and instead add it to "
                       "your notebook configuration file:\n"
                       "c.GitHubConfig.access_token = '<TOKEN>'\n")
                raise HTTPError(403, msg)
            elif c.access_token != '':
                # Preferentially use the config access_token if set
                token = c.access_token

            api_path = url_concat(api_path, params)
            client = AsyncHTTPClient()
            request = HTTPRequest(
                api_path,
                validate_cert=c.validate_cert,
                user_agent='JupyterLab GitHub',
                headers={"Authorization": "token {}".format(token)})
            response = yield client.fetch(request)
            data = json.loads(response.body.decode('utf-8'))

            # Check if we need to paginate results.
            # If so, get pages until all the results
            # are loaded into the data buffer.
            next_page_path = self._maybe_get_next_page_path(response)
            while next_page_path:
                request = copy.copy(request)
                request.url = next_page_path
                response = yield client.fetch(request)
                next_page_path = self._maybe_get_next_page_path(response)
                data.extend(json.loads(response.body.decode('utf-8')))

            # Send the results back.
            self.finish(json.dumps(data))

        except HTTPError as err:
            self.set_status(err.code)
            message = err.response.body if err.response else str(err.code)
            self.finish(message)
Example #17
0
 def _check_created(self, resp, path, type='notebook'):
     self.assertEqual(resp.status_code, 201)
     location_header = py3compat.str_to_unicode(resp.headers['Location'])
     self.assertEqual(location_header, url_escape(url_path_join(u'/api/contents', path)))
     rjson = resp.json()
     self.assertEqual(rjson['name'], path.rsplit('/', 1)[-1])
     self.assertEqual(rjson['path'], path)
     self.assertEqual(rjson['type'], type)
     isright = self.isdir if type == 'directory' else self.isfile
     assert isright(path)
Example #18
0
    def location_url(self, path):
        """Return the full URL location of a file.

        Parameters
        ----------
        path : unicode
            The API path of the file, such as "foo/bar.txt".
        """
        return url_path_join(self.base_url, 'api', 'contents',
                             url_escape(path))
Example #19
0
 def generate_breadcrumbs(self, path):
     """ Generate array of breadcrumb to display in page """
     breadcrumbs = [(url_path_join(self.base_url, 'cernbox'), '')]
     parts = path.split('/')
     for i in range(len(parts)):
         if parts[i]:
             link = url_path_join(self.base_url, 'cernbox',
                                  url_escape(url_path_join(*parts[:i+1])),
                                  )
             breadcrumbs.append((link, parts[i]))
     return breadcrumbs
Example #20
0
 def _check_created(self, resp, path, type='notebook'):
     self.assertEqual(resp.status_code, 201)
     location_header = py3compat.str_to_unicode(resp.headers['Location'])
     self.assertEqual(location_header,
                      url_escape(url_path_join(u'/api/contents', path)))
     rjson = resp.json()
     self.assertEqual(rjson['name'], path.rsplit('/', 1)[-1])
     self.assertEqual(rjson['path'], path)
     self.assertEqual(rjson['type'], type)
     isright = self.isdir if type == 'directory' else self.isfile
     assert isright(path)
Example #21
0
    def location_url(self, path):
        """Return the full URL location of a file.

        Parameters
        ----------
        path : unicode
            The API path of the file, such as "foo/bar.txt".
        """
        return url_escape(url_path_join(
            self.base_url, 'api', 'contents', path
        ))
Example #22
0
    def set_attachment_header(self, filename):
        """Set Content-Disposition: attachment header

        As a method to ensure handling of filename encoding
        """
        escaped_filename = url_escape(filename)
        self.set_header('Content-Disposition',
            'attachment;'
            " filename*=utf-8''{utf8}"
            .format(
                utf8=escaped_filename,
            )
        )
Example #23
0
    def post(self):
        km = self.kernel_manager
        model = self.get_json_body()
        if model is None:
            model = {'name': km.default_kernel_name}
        else:
            model.setdefault('name', km.default_kernel_name)

        kernel_id = km.start_kernel(kernel_name=model['name'])
        model = km.kernel_model(kernel_id)
        location = url_path_join(self.base_url, 'api', 'kernels', kernel_id)
        self.set_header('Location', url_escape(location))
        self.set_status(201)
        self.finish(json.dumps(model))
Example #24
0
    def post(self):
        km = self.kernel_manager
        model = self.get_json_body()
        if model is None:
            model = {"name": km.default_kernel_name}
        else:
            model.setdefault("name", km.default_kernel_name)

        kernel_id = yield maybe_future(
            km.start_kernel(kernel_name=model["name"]))
        model = yield maybe_future(km.kernel_model(kernel_id))
        location = url_path_join(self.base_url, "api", "kernels",
                                 url_escape(kernel_id))
        self.set_header("Location", location)
        self.set_status(201)
        self.finish(json.dumps(model, default=date_default))
Example #25
0
    def post(self):
        km = self.kernel_manager
        model = self.get_json_body()
        if model is None:
            model = {
                'name': km.default_kernel_name
            }
        else:
            model.setdefault('name', km.default_kernel_name)

        kernel_id = km.start_kernel(kernel_name=model['name'])
        model = km.kernel_model(kernel_id)
        location = url_path_join(self.base_url, 'api', 'kernels', kernel_id)
        self.set_header('Location', url_escape(location))
        self.set_status(201)
        self.finish(json.dumps(model))
Example #26
0
    def get(self, path=''):
        """
        Proxy API requests to GitHub, adding authentication parameter(s) if
        they have been set.
        """

        # Get access to the notebook config object
        c = GitHubConfig(config=self.config)
        try:
            api_path = url_path_join(c.api_url, url_escape(path))
            query = self.request.query_arguments
            params = {key: query[key][0].decode() for key in query}
            params['per_page'] = 100
            if c.access_token != '':
                # Preferentially use the access_token if set
                params['access_token'] = c.access_token
            elif c.client_id != '' and c.client_secret != '':
                # Otherwise use client_id and client_secret if set
                params['client_id'] = c.client_id
                params['client_secret'] = c.client_secret

            api_path = url_concat(api_path, params)
            client = AsyncHTTPClient()
            request = HTTPRequest(api_path,
                                  validate_cert=c.validate_cert,
                                  user_agent='JupyterLab GitHub')
            response = yield client.fetch(request)
            data = json.loads(response.body.decode('utf-8'))

            # Check if we need to paginate results.
            # If so, get pages until all the results
            # are loaded into the data buffer.
            next_page_path = self._maybe_get_next_page_path(response)
            while next_page_path:
                request = copy.copy(request)
                request.url = next_page_path
                response = yield client.fetch(request)
                next_page_path = self._maybe_get_next_page_path(response)
                data.extend(json.loads(response.body.decode('utf-8')))

            # Send the results back.
            self.finish(json.dumps(data))

        except HTTPError as err:
            self.set_status(err.code)
            message = err.response.body if err.response else str(err.code)
            self.finish(message)
Example #27
0
    def post(self):
        km = self.kernel_manager
        model = self.get_json_body()
        if model is None:
            model = {'name': km.default_kernel_name}
        else:
            model.setdefault('name', km.default_kernel_name)

        kernel_id = yield tornado.gen.maybe_future(
            km.start_kernel(
                kernel_name=model['name'],
                extra_arguments=[self.module_name, self.object_name]))
        model = km.kernel_model(kernel_id)
        location = url_path_join(self.base_url, 'api', 'kernels',
                                 url_escape(kernel_id))
        self.set_header('Location', location)
        self.set_status(201)
        self.finish(json.dumps(model, default=date_default))
Example #28
0
    def get(self, path=''):
        """ Get handler to cope with Projects as root folder """
        path = path.strip('/')
        cm = self.contents_manager

        swan_path = url_path_join('SWAN_projects', path)

        if cm.dir_exists(path=swan_path):
            if cm.is_hidden(swan_path):
                self.log.info(
                    "Refusing to serve hidden directory, via 404 Error")
                raise web.HTTPError(404)

            if path != '':
                parent_project = cm._get_project_path(swan_path)
                if not parent_project or parent_project == 'invalid':
                    self.log.info("Trying to see a folder inside Projects")
                    raise web.HTTPError(404)
            breadcrumbs = self.generate_breadcrumbs(path)
            page_title = self.generate_page_title(path)
            self.write(
                self.render_template(
                    'tree.html',
                    page_title=page_title,
                    notebook_path=swan_path,
                    breadcrumbs=breadcrumbs,
                    terminals_available=self.settings['terminals_available'],
                    server_root=self.settings['server_root_dir'],
                    projects_page=True,
                ))
        elif cm.file_exists(swan_path):
            # it's not a directory, we have redirecting to do
            model = cm.get(swan_path, content=False)
            # redirect to /api/notebooks if it's a notebook, otherwise /api/files
            service = 'notebooks' if model['type'] == 'notebook' else 'files'
            url = url_path_join(
                self.base_url,
                service,
                url_escape(swan_path),
            )
            self.log.debug("Redirecting %s to %s", self.request.swan_path, url)
            self.redirect(url)
        else:
            raise web.HTTPError(404)
Example #29
0
    def get(self, path):
        _init_session(self.request, self.cookies)
        """
        get renders the notebook template if a name is given, or
        redirects to the '/files/' handler if the name is not given.
        """

        path = path.strip("/")
        cm = self.contents_manager

        # will raise 404 on not found
        try:
            model = cm.get(path, content=False)
        except web.HTTPError as e:
            log_event(g_log, "loading_error", {"error": str(e)})
            if e.status_code == 403:
                self.write(self.render_template("403.html", status_code=403))
                return
            else:
                self.write(
                    self.render_template(
                        "generic_error.html",
                        message=e.log_message,
                        status_code=e.status_code,
                    ))
                return
        if model.get("type") != "notebook":
            # not a notebook, redirect to files
            return FilesRedirectHandler.redirect_to_files(self, path)
        path = url_escape(path)
        self.write(
            self.render_template(
                "notebook.html",
                notebook_path=path,
                notebook_name=path,
                kill_kernel=False,
                mathjax_url=self.mathjax_url,
                google_analytics_id=URLS.google_analytics_id,
                userName=kbase_env.user,
                google_ad_id=URLS.google_ad_id,
                google_ad_conversion=URLS.google_ad_conversion,
            ))
Example #30
0
    def register(self, server_info):
        """Register attributes that can be computed with the server info."""
        # Path relative to the server directory
        self.path = os.path.relpath(self.filename,
                                    start=server_info['notebook_dir'])

        # Replace backslashes on Windows
        if os.name == 'nt':
            self.path = self.path.replace('\\', '/')

        # Server url to send requests to
        self.server_url = server_info['url']

        # Server token
        self.token = server_info['token']

        url = url_path_join(self.server_url, 'notebook', url_escape(self.path))

        # Set file url to load this notebook
        self.file_url = self.add_token(url)
Example #31
0
    def post(self):
        # Creates a new session
        # (unless a session already exists for the named nb)
        sm = self.session_manager
        cm = self.contents_manager
        km = self.kernel_manager

        model = self.get_json_body()
        if model is None:
            raise web.HTTPError(400, "No JSON data provided")
        try:
            path = model["notebook"]["path"]
        except KeyError:
            raise web.HTTPError(400, "Missing field in JSON data: notebook.path")
        try:
            kernel_name = model["kernel"]["name"]
        except KeyError:
            self.log.debug("No kernel name specified, using default kernel")
            kernel_name = None

        # Check to see if session exists
        if sm.session_exists(path=path):
            model = sm.get_session(path=path)
        else:
            try:
                model = sm.create_session(path=path, kernel_name=kernel_name)
            except NoSuchKernel:
                msg = (
                    "The '%s' kernel is not available. Please pick another "
                    "suitable kernel instead, or install that kernel." % kernel_name
                )
                status_msg = "%s not found" % kernel_name
                self.log.warn("Kernel not found: %s" % kernel_name)
                self.set_status(501)
                self.finish(json.dumps(dict(message=msg, short_message=status_msg)))
                return

        location = url_path_join(self.base_url, "api", "sessions", model["id"])
        self.set_header("Location", url_escape(location))
        self.set_status(201)
        self.finish(json.dumps(model, default=date_default))
Example #32
0
def nbopen(filename, profile='default'):
    filename = os.path.abspath(filename)
    home_dir = os.path.expanduser('~')
    server_inf = find_best_server(filename, profile)
    if server_inf is not None:
        print("Using existing server at", server_inf['notebook_dir'])
        path = os.path.relpath(filename, start=server_inf['notebook_dir'])
        url = url_path_join(server_inf['url'], 'notebooks', url_escape(path))
        webbrowser.open(url, new=2)
    else:
        if filename.startswith(home_dir):
            nbdir = home_dir
        else:
            nbdir = os.path.dirname(filename)

        print("Starting new server")
        notebookapp.launch_new_instance(file_to_run=os.path.abspath(filename),
                                        notebook_dir=nbdir,
                                        open_browser=True,
                                        argv=[],  # Avoid it seeing our own argv
                                       )
Example #33
0
def open_notebook(notebook_file):
    """Open the given IPython Notebook file in an existing or a new Jupyter Notebook server"""
    server = find_running_server(notebook_file)
    if server:
        logging.info(
            f"Using existing Jupyter server at {server['url']} (serving from {server['notebook_dir']})"
        )
        rel_path = Path(notebook_file).resolve(strict=True).relative_to(
            Path(server['notebook_dir']))
        url = url_path_join(server['url'], 'notebooks',
                            url_escape(rel_path.as_posix()))

        nbapp = notebookapp.NotebookApp.instance()
        nbapp.load_config_file()
        browser = webbrowser.get(nbapp.browser or None)
        browser.open_new_tab(url)
    else:
        logging.info("Starting new Jupyter server to serve notebook file")
        launch_detached_process(sys.executable, '-m', 'notebook',
                                '--NotebookApp.open_browser=True',
                                notebook_file)
Example #34
0
    def get(self, path):
        _init_session(self.request, self.cookies)
        """
        get renders the notebook template if a name is given, or
        redirects to the '/files/' handler if the name is not given.
        """

        path = path.strip('/')
        cm = self.contents_manager

        # will raise 404 on not found
        try:
            model = cm.get(path, content=False)
        except web.HTTPError as e:
            log_event(g_log, 'loading_error', {'error': str(e)})
            if e.status_code == 403:
                self.write(self.render_template('403.html', status_code=403))
                return
            else:
                self.write(self.render_template(
                    'generic_error.html', message=e.log_message, status_code=e.status_code
                ))
                return
        if model.get('type') != 'notebook':
            # not a notebook, redirect to files
            return FilesRedirectHandler.redirect_to_files(self, path)
        path = url_escape(path)
        self.write(
            self.render_template(
                'notebook.html',
                notebook_path=path,
                notebook_name=path,
                kill_kernel=False,
                mathjax_url=self.mathjax_url,
                google_analytics_id=URLS.google_analytics_id,
                userName=kbase_env.user,
                google_ad_id=URLS.google_ad_id,
                google_ad_conversion=URLS.google_ad_conversion,
            )
        )
Example #35
0
    def get(self, path=''):
        """
        Proxy API requests to GitHub, adding 'client_id' and 'client_secret'
        if they have been set.
        """

        # Get access to the notebook config object
        c = GitHubConfig(config=self.config)
        try:
            api_path = url_path_join(GITHUB_API, url_escape(path))
            # If the config has client_id and client_secret set,
            # apply them to the request.
            if c.client_id != '' and c.client_secret != '':
                api_path = url_concat(api_path,
                    {'client_id': c.client_id,\
                     'client_secret': c.client_secret,\
                     'per_page': 100})
            client = AsyncHTTPClient()
            request = HTTPRequest(api_path, user_agent='JupyterLab GitHub')
            response = yield client.fetch(request)
            data = json.loads(response.body.decode('utf-8'))

            # Check if we need to paginate results.
            # If so, get pages until all the results
            # are loaded into the data buffer.
            next_page_path = self._maybe_get_next_page_path(response)
            while next_page_path:
                request = HTTPRequest(next_page_path,
                                      user_agent='JupyterLab GitHub')
                response = yield client.fetch(request)
                next_page_path = self._maybe_get_next_page_path(response)
                data.extend(json.loads(response.body.decode('utf-8')))

            # Send the results back.
            self.finish(json.dumps(data))

        except HTTPError as err:
            self.set_status(err.code)
            self.finish(err.response.body)
Example #36
0
    def post(self):
        # Creates a new session
        #(unless a session already exists for the named nb)
        sm = self.session_manager
        cm = self.contents_manager
        km = self.kernel_manager

        model = self.get_json_body()
        if model is None:
            raise web.HTTPError(400, "No JSON data provided")
        try:
            path = model['notebook']['path']
        except KeyError:
            raise web.HTTPError(400, "Missing field in JSON data: notebook.path")
        try:
            kernel_name = model['kernel']['name']
        except KeyError:
            self.log.debug("No kernel name specified, using default kernel")
            kernel_name = None

        # Check to see if session exists
        if sm.session_exists(path=path):
            model = sm.get_session(path=path)
        else:
            try:
                model = sm.create_session(path=path, kernel_name=kernel_name)
            except NoSuchKernel:
                msg = ("The '%s' kernel is not available. Please pick another "
                       "suitable kernel instead, or install that kernel." % kernel_name)
                status_msg = '%s not found' % kernel_name
                self.log.warn('Kernel not found: %s' % kernel_name)
                self.set_status(501)
                self.finish(json.dumps(dict(message=msg, short_message=status_msg)))
                return

        location = url_path_join(self.base_url, 'api', 'sessions', model['id'])
        self.set_header('Location', url_escape(location))
        self.set_status(201)
        self.finish(json.dumps(model, default=date_default))
    def get(self, path):
        _init_session(self.request, self.cookies)
        """
        get renders the notebook template if a name is given, or
        redirects to the '/files/' handler if the name is not given.
        """

        path = path.strip('/')
        cm = self.contents_manager

        # will raise 404 on not found
        try:
            model = cm.get(path, content=False)
        except web.HTTPError as e:
            log_event(g_log, 'loading_error', {'error': str(e)})
            if e.status_code == 403:
                self.write(self.render_template('403.html', status_code=403))
                return
            else:
                self.write(
                    self.render_template('generic_error.html',
                                         message=e.log_message,
                                         status_code=e.status_code))
                return
        if model.get('type') != 'notebook':
            # not a notebook, redirect to files
            return FilesRedirectHandler.redirect_to_files(self, path)
        path = url_escape(path)
        self.write(
            self.render_template(
                'notebook.html',
                notebook_path=path,
                notebook_name=path,
                kill_kernel=False,
                mathjax_url=self.mathjax_url,
                google_analytics_id=URLS.google_analytics_id,
            ))
Example #38
0
def test_url_escape_12():
    #test for ?
    path = url_escape('hostname/?something/')
    assert path == 'hostname/%3Fsomething/'
Example #39
0
def load_jupyter_server_extension(nbapp):
    """Load the JupyterLab server extension.
    """
    # Delay imports to speed up jlpmapp
    from json import dumps
    from jupyterlab_server import add_handlers
    from notebook.utils import url_path_join as ujoin, url_escape
    from notebook._version import version_info
    from tornado.ioloop import IOLoop
    from markupsafe import Markup
    from .handlers.build_handler import build_path, Builder, BuildHandler
    from .handlers.extension_manager_handler import (
        extensions_handler_path, ExtensionManager, ExtensionHandler
    )
    from .handlers.error_handler import ErrorHandler
    from .commands import (
        DEV_DIR, HERE, ensure_app, ensure_core, ensure_dev, watch,
        watch_dev, get_app_dir
    )

    web_app = nbapp.web_app
    logger = nbapp.log
    base_url = nbapp.base_url

    # Handle the app_dir
    app_dir = getattr(nbapp, 'app_dir', get_app_dir())

    # Check for core mode.
    core_mode = False
    if getattr(nbapp, 'core_mode', False) or app_dir.startswith(HERE):
        app_dir = HERE
        core_mode = True
        logger.info('Running JupyterLab in core mode')

    # Check for dev mode.
    dev_mode = False
    if getattr(nbapp, 'dev_mode', False) or app_dir.startswith(DEV_DIR):
        app_dir = DEV_DIR
        dev_mode = True
        logger.info('Running JupyterLab in dev mode')

    # Set the value on nbapp so it will get picked up in load_config
    nbapp.app_dir = app_dir

    config = load_config(nbapp)
    config.app_name = 'JupyterLab'
    config.app_namespace = 'jupyterlab'

    config.app_url = '/lab'

    config.cache_files = True

    # Check for watch.
    watch_mode = getattr(nbapp, 'watch', False)

    if watch_mode and core_mode:
        logger.warn('Cannot watch in core mode, did you mean --dev-mode?')
        watch_mode = False

    if core_mode and dev_mode:
        logger.warn('Conflicting modes, choosing dev_mode over core_mode')
        core_mode = False

    page_config = web_app.settings.setdefault('page_config_data', dict())
    page_config['buildAvailable'] = not core_mode and not dev_mode
    page_config['buildCheck'] = not core_mode and not dev_mode
    page_config['devMode'] = dev_mode
    page_config['token'] = nbapp.token

    # Export the version info tuple to a JSON array. This gets printed
    # inside double quote marks, so we render it to a JSON string of the
    # JSON data (so that we can call JSON.parse on the frontend on it).
    # We also have to wrap it in `Markup` so that it isn't escaped
    # by Jinja. Otherwise, if the version has string parts these will be
    # escaped and then will have to be unescaped on the frontend.
    page_config['notebookVersion'] = Markup(dumps(dumps(version_info))[1:-1])

    if nbapp.file_to_run and type(nbapp).__name__ == "LabApp":
        relpath = os.path.relpath(nbapp.file_to_run, nbapp.notebook_dir)
        uri = url_escape(ujoin('/lab/tree', *relpath.split(os.sep)))
        nbapp.default_url = uri
        nbapp.file_to_run = ''

    # Print messages.
    logger.info('JupyterLab extension loaded from %s' % HERE)
    logger.info('JupyterLab application directory is %s' % app_dir)

    build_url = ujoin(base_url, build_path)
    builder = Builder(logger, core_mode, app_dir)
    build_handler = (build_url, BuildHandler, {'builder': builder})
    handlers = [build_handler]

    errored = False

    if core_mode:
        logger.info(CORE_NOTE.strip())
        ensure_core(logger)

    elif dev_mode:
        if not watch_mode:
            ensure_dev(logger)
            logger.info(DEV_NOTE)

    # Make sure the app dir exists.
    else:
        msgs = ensure_app(app_dir)
        if msgs:
            [logger.error(msg) for msg in msgs]
            handler = (ujoin(base_url, '/lab'), ErrorHandler, { 'messages': msgs })
            handlers.append(handler)
            errored = True

    if watch_mode:
        logger.info('Starting JupyterLab watch mode...')

        # Set the ioloop in case the watch fails.
        nbapp.ioloop = IOLoop.current()
        if dev_mode:
            watch_dev(logger)
        else:
            watch(app_dir, logger)
            page_config['buildAvailable'] = False

        config.cache_files = False

    if not core_mode and not errored:
        ext_url = ujoin(base_url, extensions_handler_path)
        ext_manager = ExtensionManager(logger, app_dir)
        ext_handler = (ext_url, ExtensionHandler, {'manager': ext_manager})
        handlers.append(ext_handler)

    # Must add before the root server handlers to avoid shadowing.
    web_app.add_handlers('.*$', handlers)

    # If running under JupyterHub, add more metadata.
    if hasattr(nbapp, 'hub_prefix'):
        page_config['hubPrefix'] = nbapp.hub_prefix
        page_config['hubHost'] = nbapp.hub_host
        page_config['hubUser'] = nbapp.user
        api_token = os.getenv('JUPYTERHUB_API_TOKEN', '')
        page_config['token'] = api_token

    # Add the root handlers if we have not errored.
    if not errored:
        add_handlers(web_app, config)
Example #40
0
def load_jupyter_server_extension(nbapp):
    """Load the JupyterLab server extension.
    """
    # Delay imports to speed up jlpmapp
    from json import dumps
    from jupyterlab_launcher import add_handlers, LabConfig
    from notebook.utils import url_path_join as ujoin, url_escape
    from notebook._version import version_info
    from tornado.ioloop import IOLoop
    from markupsafe import Markup
    from .build_handler import build_path, Builder, BuildHandler
    from .commands import (
        get_app_dir, get_user_settings_dir, watch, ensure_dev, watch_dev,
        pjoin, DEV_DIR, HERE, get_app_info, ensure_core, get_workspaces_dir
    )

    web_app = nbapp.web_app
    logger = nbapp.log
    config = LabConfig()
    app_dir = getattr(nbapp, 'app_dir', get_app_dir())
    user_settings_dir = getattr(
        nbapp, 'user_settings_dir', get_user_settings_dir()
    )
    workspaces_dir = getattr(
        nbapp, 'workspaces_dir', get_workspaces_dir()
    )

    # Print messages.
    logger.info('JupyterLab beta preview extension loaded from %s' % HERE)
    logger.info('JupyterLab application directory is %s' % app_dir)

    config.app_name = 'JupyterLab Beta'
    config.app_namespace = 'jupyterlab'
    config.page_url = '/lab'
    config.cache_files = True

    # Check for core mode.
    core_mode = False
    if getattr(nbapp, 'core_mode', False) or app_dir.startswith(HERE):
        core_mode = True
        logger.info('Running JupyterLab in core mode')

    # Check for dev mode.
    dev_mode = False
    if getattr(nbapp, 'dev_mode', False) or app_dir.startswith(DEV_DIR):
        dev_mode = True
        logger.info('Running JupyterLab in dev mode')

    # Check for watch.
    watch_mode = getattr(nbapp, 'watch', False)

    if watch_mode and core_mode:
        logger.warn('Cannot watch in core mode, did you mean --dev-mode?')
        watch_mode = False

    if core_mode and dev_mode:
        logger.warn('Conflicting modes, choosing dev_mode over core_mode')
        core_mode = False

    page_config = web_app.settings.setdefault('page_config_data', dict())
    page_config['buildAvailable'] = not core_mode and not dev_mode
    page_config['buildCheck'] = not core_mode and not dev_mode
    page_config['token'] = nbapp.token
    page_config['devMode'] = dev_mode
    # Export the version info tuple to a JSON array. This get's printed
    # inside double quote marks, so we render it to a JSON string of the
    # JSON data (so that we can call JSON.parse on the frontend on it).
    # We also have to wrap it in `Markup` so that it isn't escaped
    # by Jinja. Otherwise, if the version has string parts these will be
    # escaped and then will have to be unescaped on the frontend.
    page_config['notebookVersion'] = Markup(dumps(dumps(version_info))[1:-1])

    if nbapp.file_to_run and type(nbapp).__name__ == "LabApp":
        relpath = os.path.relpath(nbapp.file_to_run, nbapp.notebook_dir)
        uri = url_escape(ujoin('/lab/tree', *relpath.split(os.sep)))
        nbapp.default_url = uri
        nbapp.file_to_run = ''

    if core_mode:
        app_dir = HERE
        logger.info(CORE_NOTE.strip())
        ensure_core(logger)

    elif dev_mode:
        app_dir = DEV_DIR
        ensure_dev(logger)
        if not watch_mode:
            logger.info(DEV_NOTE)

    config.app_settings_dir = pjoin(app_dir, 'settings')
    config.schemas_dir = pjoin(app_dir, 'schemas')
    config.themes_dir = pjoin(app_dir, 'themes')
    config.workspaces_dir = workspaces_dir
    info = get_app_info(app_dir)
    config.app_version = info['version']
    public_url = info['publicUrl']
    if public_url:
        config.public_url = public_url
    else:
        config.static_dir = pjoin(app_dir, 'static')

    config.user_settings_dir = user_settings_dir

    # The templates end up in the built static directory.
    config.templates_dir = pjoin(app_dir, 'static')

    if watch_mode:
        logger.info('Starting JupyterLab watch mode...')

        # Set the ioloop in case the watch fails.
        nbapp.ioloop = IOLoop.current()
        if dev_mode:
            watch_dev(logger)
        else:
            watch(app_dir, logger)
            page_config['buildAvailable'] = False

        config.cache_files = False

    base_url = web_app.settings['base_url']
    build_url = ujoin(base_url, build_path)
    builder = Builder(logger, core_mode, app_dir)
    build_handler = (build_url, BuildHandler, {'builder': builder})

    # Must add before the launcher handlers to avoid shadowing.
    web_app.add_handlers('.*$', [build_handler])

    add_handlers(web_app, config)
Example #41
0
def load_jupyter_server_extension(nbapp):
    """Load the JupyterLab server extension.
    """
    # Delay imports to speed up jlpmapp
    from json import dumps
    from jupyterlab_server import add_handlers
    from notebook.utils import url_path_join as ujoin, url_escape
    from notebook._version import version_info
    from tornado.ioloop import IOLoop
    from markupsafe import Markup
    from .build_handler import build_path, Builder, BuildHandler
    from .extension_manager_handler import (
        extensions_handler_path, ExtensionManager, ExtensionHandler
    )
    from .commands import (
        DEV_DIR, HERE, ensure_core, ensure_dev, watch, watch_dev, get_app_dir
    )

    web_app = nbapp.web_app
    logger = nbapp.log

    # Handle the app_dir
    app_dir = getattr(nbapp, 'app_dir', get_app_dir())

    # Check for core mode.
    core_mode = False
    if getattr(nbapp, 'core_mode', False) or app_dir.startswith(HERE):
        app_dir = HERE
        core_mode = True
        logger.info('Running JupyterLab in core mode')

    # Check for dev mode.
    dev_mode = False
    if getattr(nbapp, 'dev_mode', False) or app_dir.startswith(DEV_DIR):
        app_dir = DEV_DIR
        dev_mode = True
        logger.info('Running JupyterLab in dev mode')

    # Set the value on nbapp so it will get picked up in load_config
    nbapp.app_dir = app_dir

    config = load_config(nbapp)
    config.app_name = 'JupyterLab'
    config.app_namespace = 'jupyterlab'
    config.page_url = '/lab'
    config.cache_files = True

    # Check for watch.
    watch_mode = getattr(nbapp, 'watch', False)

    if watch_mode and core_mode:
        logger.warn('Cannot watch in core mode, did you mean --dev-mode?')
        watch_mode = False

    if core_mode and dev_mode:
        logger.warn('Conflicting modes, choosing dev_mode over core_mode')
        core_mode = False

    page_config = web_app.settings.setdefault('page_config_data', dict())
    page_config['buildAvailable'] = not core_mode and not dev_mode
    page_config['buildCheck'] = not core_mode and not dev_mode
    page_config['token'] = nbapp.token
    page_config['devMode'] = dev_mode

    # Handle bundle url
    bundle_url = config.public_url
    if bundle_url.startswith(config.page_url):
        bundle_url = ujoin(nbapp.base_url, bundle_url)
    page_config['bundleUrl'] = bundle_url

    # Export the version info tuple to a JSON array. This gets printed
    # inside double quote marks, so we render it to a JSON string of the
    # JSON data (so that we can call JSON.parse on the frontend on it).
    # We also have to wrap it in `Markup` so that it isn't escaped
    # by Jinja. Otherwise, if the version has string parts these will be
    # escaped and then will have to be unescaped on the frontend.
    page_config['notebookVersion'] = Markup(dumps(dumps(version_info))[1:-1])

    if nbapp.file_to_run and type(nbapp).__name__ == "LabApp":
        relpath = os.path.relpath(nbapp.file_to_run, nbapp.notebook_dir)
        uri = url_escape(ujoin('/lab/tree', *relpath.split(os.sep)))
        nbapp.default_url = uri
        nbapp.file_to_run = ''

    if core_mode:
        logger.info(CORE_NOTE.strip())
        ensure_core(logger)

    elif dev_mode:
        ensure_dev(logger)
        if not watch_mode:
            logger.info(DEV_NOTE)

    # Print messages.
    logger.info('JupyterLab extension loaded from %s' % HERE)
    logger.info('JupyterLab application directory is %s' % app_dir)

    if watch_mode:
        logger.info('Starting JupyterLab watch mode...')

        # Set the ioloop in case the watch fails.
        nbapp.ioloop = IOLoop.current()
        if dev_mode:
            watch_dev(logger)
        else:
            watch(app_dir, logger)
            page_config['buildAvailable'] = False

        config.cache_files = False

    base_url = web_app.settings['base_url']
    build_url = ujoin(base_url, build_path)
    builder = Builder(logger, core_mode, app_dir)
    build_handler = (build_url, BuildHandler, {'builder': builder})
    handlers = [build_handler]

    if not core_mode:
        ext_url = ujoin(base_url, extensions_handler_path)
        ext_manager = ExtensionManager(logger, app_dir)
        ext_handler = (ext_url, ExtensionHandler, {'manager': ext_manager})
        handlers.append(ext_handler)

    # Must add before the launcher handlers to avoid shadowing.
    web_app.add_handlers('.*$', handlers)

    add_handlers(web_app, config)
Example #42
0
def test_url_escape_14():
    #test for +
    path = url_escape('hostname/+something/')
    assert path == 'hostname/%2Bsomething/'
Example #43
0
def load_jupyter_server_extension(nbapp):
    """Load the JupyterLab server extension.
    """
    # Delay imports to speed up jlpmapp
    from json import dumps
    from jupyterlab_server import add_handlers
    from notebook.utils import url_path_join as ujoin, url_escape
    from notebook._version import version_info
    from tornado.ioloop import IOLoop
    from markupsafe import Markup
    from .handlers.build_handler import build_path, Builder, BuildHandler
    from .handlers.extension_manager_handler import (extensions_handler_path,
                                                     ExtensionManager,
                                                     ExtensionHandler)
    from .handlers.error_handler import ErrorHandler
    from .commands import (DEV_DIR, HERE, ensure_app, ensure_core, ensure_dev,
                           watch, watch_dev, get_app_dir, AppOptions)

    web_app = nbapp.web_app
    logger = nbapp.log
    base_url = nbapp.base_url

    # Handle the app_dir
    app_dir = getattr(nbapp, 'app_dir', get_app_dir())

    build_handler_options = AppOptions(logger=logger, app_dir=app_dir)

    # Check for core mode.
    core_mode = False
    if getattr(nbapp, 'core_mode', False) or app_dir.startswith(HERE):
        app_dir = HERE
        core_mode = True
        logger.info('Running JupyterLab in core mode')

    # Check for dev mode.
    dev_mode = False
    if getattr(nbapp, 'dev_mode', False) or app_dir.startswith(DEV_DIR):
        app_dir = DEV_DIR
        dev_mode = True
        logger.info('Running JupyterLab in dev mode')

    # Set the value on nbapp so it will get picked up in load_config
    nbapp.app_dir = app_dir

    config = load_config(nbapp)
    config.app_name = 'JupyterLab'
    config.app_namespace = 'jupyterlab'

    config.app_url = '/lab'

    config.cache_files = True

    # Check for watch.
    watch_mode = getattr(nbapp, 'watch', False)

    if watch_mode and core_mode:
        logger.warn('Cannot watch in core mode, did you mean --dev-mode?')
        watch_mode = False

    if core_mode and dev_mode:
        logger.warn('Conflicting modes, choosing dev_mode over core_mode')
        core_mode = False

    page_config = web_app.settings.setdefault('page_config_data', dict())
    page_config['buildAvailable'] = not core_mode and not dev_mode
    page_config['buildCheck'] = not core_mode and not dev_mode
    page_config['devMode'] = dev_mode
    page_config['token'] = nbapp.token

    # Handle quit button with support for Notebook < 5.6
    page_config['quitButton'] = getattr(nbapp, 'quit_button', False)

    # Client-side code assumes notebookVersion is a JSON-encoded string
    # TODO: fix this when we can make such a change
    page_config['notebookVersion'] = dumps(version_info)
    page_config['exposeAppInBrowser'] = getattr(nbapp, 'expose_app_in_browser',
                                                False)

    if nbapp.file_to_run and type(nbapp).__name__ == "LabApp":
        relpath = os.path.relpath(nbapp.file_to_run, nbapp.notebook_dir)
        uri = url_escape(ujoin('/lab/tree', *relpath.split(os.sep)))
        nbapp.default_url = uri
        nbapp.file_to_run = ''

    # Print messages.
    logger.info('JupyterLab extension loaded from %s' % HERE)
    logger.info('JupyterLab application directory is %s' % app_dir)

    build_url = ujoin(base_url, build_path)
    builder = Builder(None, core_mode, None, app_options=build_handler_options)
    build_handler = (build_url, BuildHandler, {'builder': builder})
    handlers = [build_handler]

    errored = False

    if core_mode:
        logger.info(CORE_NOTE.strip())
        ensure_core(logger)

    elif dev_mode:
        if not watch_mode:
            ensure_dev(logger)
            logger.info(DEV_NOTE)

    # Make sure the app dir exists.
    elif not watch_mode:
        msgs = ensure_app(app_dir)
        if msgs:
            [logger.error(msg) for msg in msgs]
            handler = (ujoin(base_url, '/lab'), ErrorHandler, {
                'messages': msgs
            })
            handlers.append(handler)
            errored = True

    if watch_mode:
        logger.info('Starting JupyterLab watch mode...')

        # Set the ioloop in case the watch fails.
        nbapp.ioloop = IOLoop.current()
        if dev_mode:
            watch_dev(logger)
        else:
            watch(app_options=build_handler_options)
            page_config['buildAvailable'] = False

        config.cache_files = False

    if not core_mode and not errored:
        ext_url = ujoin(base_url, extensions_handler_path)
        ext_manager = ExtensionManager(app_options=build_handler_options)
        ext_handler = (ext_url, ExtensionHandler, {'manager': ext_manager})
        handlers.append(ext_handler)

    # Must add before the root server handlers to avoid shadowing.
    web_app.add_handlers('.*$', handlers)

    # If running under JupyterHub, add more metadata.
    if hasattr(nbapp, 'hub_prefix'):
        page_config['hubPrefix'] = nbapp.hub_prefix
        page_config['hubHost'] = nbapp.hub_host
        page_config['hubUser'] = nbapp.user
        # Assume the server_name property indicates running JupyterHub 1.0.
        if hasattr(nbapp, 'server_name'):
            page_config['hubServerName'] = nbapp.server_name
        api_token = os.getenv('JUPYTERHUB_API_TOKEN', '')
        page_config['token'] = api_token

    # Add the root handlers if we have not errored.
    if not errored:
        add_handlers(web_app, config)
Example #44
0
def test_url_escape_13():
    #test for :
    path = url_escape('hostname/:something/')
    assert path == 'hostname/%3Asomething/'