Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update settings handler to parse complex URL paths. #19

Merged
merged 4 commits into from
Sep 29, 2017
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions jupyterlab_launcher/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,11 @@ def add_handlers(web_app, config):
config.version = (config.version or data['jupyterlab']['version'] or
data['version'])
config.name = config.name or data['jupyterlab']['name']
# Handle the settings.

# Handle the settings.
if config.schemas_dir and not config.settings_url:
config.settings_url = ujoin(base_url, default_settings_path)
settings_path = config.settings_url + '(?P<section_name>[\w.-]+)'
settings_path = config.settings_url + '(?P<section_name>.+)'
handlers.append((settings_path, SettingsHandler, {
'schemas_dir': config.schemas_dir,
'settings_dir': config.user_settings_dir
Expand Down
76 changes: 46 additions & 30 deletions jupyterlab_launcher/settings_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import json
import os
from tornado import web
import pdb

from notebook.base.handlers import APIHandler, json_errors

Expand All @@ -24,22 +25,12 @@ def initialize(self, schemas_dir, settings_dir):
@json_errors
@web.authenticated
def get(self, section_name):
self.set_header('Content-Type', "application/json")
path = os.path.join(self.schemas_dir, section_name + ".json")
self.set_header("Content-Type", "application/json")

if not os.path.exists(path):
raise web.HTTPError(404, "Schema not found: %r" % section_name)
with open(path) as fid:
# Attempt to load the schema file.
try:
schema = json.load(fid)
except Exception as e:
name = section_name
message = "Failed parsing schema ({}): {}".format(name, str(e))
raise web.HTTPError(500, message)

path = os.path.join(self.settings_dir, section_name + '.json')
schema = _get_schema(self.schemas_dir, section_name)
path = _path(self.settings_dir, section_name)
settings = dict()

if os.path.exists(path):
with open(path) as fid:
# Attempt to load the settings file.
Expand All @@ -66,30 +57,55 @@ def patch(self, section_name):
if not self.settings_dir:
raise web.HTTPError(404, "No current settings directory")

path = os.path.join(self.schemas_dir, section_name + '.json')

if not os.path.exists(path):
raise web.HTTPError(404, "Schema not found for: %r" % section_name)

data = self.get_json_body() # Will raise 400 if content is not valid JSON
# Will raise 400 if content is not valid JSON.
data = self.get_json_body()

# Validate the data against the schema.
if Validator is not None:
with open(path) as fid:
schema = json.load(fid)
validator = Validator(schema)
validator = Validator(_get_schema(self.schemas_dir, section_name))
try:
validator.validate(data)
except ValidationError as e:
raise web.HTTPError(400, str(e))

# Create the settings dir as needed.
if not os.path.exists(self.settings_dir):
os.makedirs(self.settings_dir)

path = os.path.join(self.settings_dir, section_name + '.json')

with open(path, 'w') as fid:
with open(_path(self.settings_dir, section_name, True), "w") as fid:
json.dump(data, fid)

self.set_status(204)


def _path(root_dir, section_name, make_dirs = False):
"""Parse the URL section name and find the local file system path."""

# Attempt to parse path, e.g. @jupyterlab/apputils-extension:themes.
try:
package_dir, plugin = section_name.split(":")
parent_dir = os.path.join(root_dir, package_dir)
path = os.path.join(parent_dir, plugin + ".json")
# This is deprecated and exists to support the older URL scheme.
except Exception as e:
path = os.path.join(root_dir, section_name + ".json")

if make_dirs and parent_dir and not os.path.exists(parent_dir):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parent_dir would only be defined if there was a : in the section name (need to pre-define it outside of the try block).

os.makedirs(parent_dir)

return path

def _get_schema(schemas_dir, section_name):
"""Retrieve and parse a JSON schema."""

path = _path(schemas_dir, section_name)

if not os.path.exists(path):
raise web.HTTPError(404, "Schema not found: %r" % path)

with open(path) as fid:
# Attempt to load the schema file.
try:
schema = json.load(fid)
except Exception as e:
name = section_name
message = "Failed parsing schema ({}): {}".format(name, str(e))
raise web.HTTPError(500, message)

return schema