Skip to content

Commit

Permalink
Merge pull request #4453 from minrk/maybe-future
Browse files Browse the repository at this point in the history
- Finish transition to our own maybe_future
- Bump minimum Python version to 3.5
  • Loading branch information
willingc committed Mar 7, 2019
2 parents 43622e7 + 3d94b51 commit d17caf9
Show file tree
Hide file tree
Showing 14 changed files with 112 additions and 150 deletions.
7 changes: 0 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,20 +93,13 @@ matrix:
- MOZ_HEADLESS=1
addons:
firefox: 57.0

- python: 3.4
env: GROUP=python
- python: 3.5
env: GROUP=python
- python: 3.7
dist: xenial
env: GROUP=python
- python: 3.6
env: GROUP=docs
- python: 3.6
env:
- GROUP=python
- EXTRA_PIP="tornado<5"

after_success:
- codecov
28 changes: 12 additions & 16 deletions notebook/base/zmqhandlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,10 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

import os
import json
import struct
import warnings
import sys

try:
from urllib.parse import urlparse # Py 3
except ImportError:
from urlparse import urlparse # Py 2
from urllib.parse import urlparse

import tornado
from tornado import gen, ioloop, web
Expand All @@ -23,8 +17,10 @@
from jupyter_client.jsonutil import date_default, extract_dates
from ipython_genutils.py3compat import cast_unicode

from notebook.utils import maybe_future
from .handlers import IPythonHandler


def serialize_binary_message(msg):
"""serialize a message as a binary blob
Expand Down Expand Up @@ -251,39 +247,39 @@ def _on_zmq_reply(self, stream, msg_list):


class AuthenticatedZMQStreamHandler(ZMQStreamHandler, IPythonHandler):

def set_default_headers(self):
"""Undo the set_default_headers in IPythonHandler
which doesn't make sense for websockets
"""
pass

def pre_get(self):
"""Run before finishing the GET request
Extend this method to add logic that should fire before
the websocket finishes completing.
"""
# authenticate the request before opening the websocket
if self.get_current_user() is None:
self.log.warning("Couldn't authenticate WebSocket connection")
raise web.HTTPError(403)

if self.get_argument('session_id', False):
self.session.session = cast_unicode(self.get_argument('session_id'))
else:
self.log.warning("No session ID specified")

@gen.coroutine
def get(self, *args, **kwargs):
# pre_get can be a coroutine in subclasses
# assign and yield in two step to avoid tornado 3 issues
res = self.pre_get()
yield gen.maybe_future(res)
yield maybe_future(res)
res = super(AuthenticatedZMQStreamHandler, self).get(*args, **kwargs)
yield gen.maybe_future(res)
yield maybe_future(res)

def initialize(self):
self.log.debug("Initializing websocket connection %s", self.request.path)
self.session = Session(config=self.config)
Expand Down
13 changes: 8 additions & 5 deletions notebook/bundler/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
from . import tools
from notebook.utils import url2path
from notebook.base.handlers import IPythonHandler
from notebook.services.config import ConfigManager

from ipython_genutils.importstring import import_item
from tornado import web, gen

from notebook.utils import maybe_future, url2path
from notebook.base.handlers import IPythonHandler
from notebook.services.config import ConfigManager

from . import tools


class BundlerHandler(IPythonHandler):
def initialize(self):
Expand Down Expand Up @@ -74,7 +77,7 @@ def get(self, path):

# Let the bundler respond in any way it sees fit and assume it will
# finish the request
yield gen.maybe_future(bundler_mod.bundle(self, model))
yield maybe_future(bundler_mod.bundle(self, model))

_bundler_id_regex = r'(?P<bundler_id>[A-Za-z0-9_]+)'

Expand Down
12 changes: 4 additions & 8 deletions notebook/files/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,12 @@

import mimetypes
import json
from base64 import decodebytes

try: #PY3
from base64 import decodebytes
except ImportError: #PY2
from base64 import decodestring as decodebytes


from tornado import gen, web
from tornado import web

from notebook.base.handlers import IPythonHandler
from notebook.utils import maybe_future


class FilesHandler(IPythonHandler):
Expand Down Expand Up @@ -51,7 +47,7 @@ def get(self, path, include_body=True):
else:
name = path

model = yield gen.maybe_future(cm.get(path, type='file', content=include_body))
model = yield maybe_future(cm.get(path, type='file', content=include_body))

if self.get_argument("download", False):
self.set_attachment_header(name)
Expand Down
10 changes: 6 additions & 4 deletions notebook/services/api/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

from itertools import chain
import json
import os

from tornado import gen, web

from ...base.handlers import IPythonHandler, APIHandler
from notebook._tz import utcfromtimestamp, isoformat
from notebook.utils import maybe_future

import os

class APISpecHandler(web.StaticFileHandler, IPythonHandler):

Expand All @@ -22,10 +22,11 @@ def initialize(self):
def get(self):
self.log.warning("Serving api spec (experimental, incomplete)")
return web.StaticFileHandler.get(self, 'api.yaml')

def get_content_type(self):
return 'text/x-yaml'


class APIStatusHandler(APIHandler):

_track_activity = False
Expand All @@ -37,7 +38,7 @@ def get(self):
started = self.settings.get('started', utcfromtimestamp(0))
started = isoformat(started)

kernels = yield gen.maybe_future(self.kernel_manager.list_kernels())
kernels = yield maybe_future(self.kernel_manager.list_kernels())
total_connections = sum(k['connections'] for k in kernels)
last_activity = isoformat(self.application.last_activity())
model = {
Expand All @@ -48,6 +49,7 @@ def get(self):
}
self.finish(json.dumps(model, sort_keys=True))


default_handlers = [
(r"/api/spec.yaml", APISpecHandler),
(r"/api/status", APIStatusHandler),
Expand Down
38 changes: 19 additions & 19 deletions notebook/services/contents/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from tornado import gen, web

from notebook.utils import url_path_join, url_escape
from notebook.utils import maybe_future, url_path_join, url_escape
from jupyter_client.jsonutil import date_default

from notebook.base.handlers import (
Expand Down Expand Up @@ -108,7 +108,7 @@ def get(self, path=''):
raise web.HTTPError(400, u'Content %r is invalid' % content)
content = int(content)

model = yield gen.maybe_future(self.contents_manager.get(
model = yield maybe_future(self.contents_manager.get(
path=path, type=type, format=format, content=content,
))
validate_model(model, expect_content=content)
Expand All @@ -122,7 +122,7 @@ def patch(self, path=''):
model = self.get_json_body()
if model is None:
raise web.HTTPError(400, u'JSON body missing')
model = yield gen.maybe_future(cm.update(model, path))
model = yield maybe_future(cm.update(model, path))
validate_model(model, expect_content=False)
self._finish_model(model)

Expand All @@ -133,7 +133,7 @@ def _copy(self, copy_from, copy_to=None):
copy_from=copy_from,
copy_to=copy_to or '',
))
model = yield gen.maybe_future(self.contents_manager.copy(copy_from, copy_to))
model = yield maybe_future(self.contents_manager.copy(copy_from, copy_to))
self.set_status(201)
validate_model(model, expect_content=False)
self._finish_model(model)
Expand All @@ -142,7 +142,7 @@ def _copy(self, copy_from, copy_to=None):
def _upload(self, model, path):
"""Handle upload of a new file to path"""
self.log.info(u"Uploading file to %s", path)
model = yield gen.maybe_future(self.contents_manager.new(model, path))
model = yield maybe_future(self.contents_manager.new(model, path))
self.set_status(201)
validate_model(model, expect_content=False)
self._finish_model(model)
Expand All @@ -151,7 +151,7 @@ def _upload(self, model, path):
def _new_untitled(self, path, type='', ext=''):
"""Create a new, empty untitled entity"""
self.log.info(u"Creating new %s in %s", type or 'file', path)
model = yield gen.maybe_future(self.contents_manager.new_untitled(path=path, type=type, ext=ext))
model = yield maybe_future(self.contents_manager.new_untitled(path=path, type=type, ext=ext))
self.set_status(201)
validate_model(model, expect_content=False)
self._finish_model(model)
Expand All @@ -162,7 +162,7 @@ def _save(self, model, path):
chunk = model.get("chunk", None)
if not chunk or chunk == -1: # Avoid tedious log information
self.log.info(u"Saving file at %s", path)
model = yield gen.maybe_future(self.contents_manager.save(model, path))
model = yield maybe_future(self.contents_manager.save(model, path))
validate_model(model, expect_content=False)
self._finish_model(model)

Expand All @@ -182,11 +182,11 @@ def post(self, path=''):

cm = self.contents_manager

file_exists = yield gen.maybe_future(cm.file_exists(path))
file_exists = yield maybe_future(cm.file_exists(path))
if file_exists:
raise web.HTTPError(400, "Cannot POST to files, use PUT instead.")

dir_exists = yield gen.maybe_future(cm.dir_exists(path))
dir_exists = yield maybe_future(cm.dir_exists(path))
if not dir_exists:
raise web.HTTPError(404, "No such directory: %s" % path)

Expand Down Expand Up @@ -220,21 +220,21 @@ def put(self, path=''):
if model:
if model.get('copy_from'):
raise web.HTTPError(400, "Cannot copy with PUT, only POST")
exists = yield gen.maybe_future(self.contents_manager.file_exists(path))
exists = yield maybe_future(self.contents_manager.file_exists(path))
if exists:
yield gen.maybe_future(self._save(model, path))
yield maybe_future(self._save(model, path))
else:
yield gen.maybe_future(self._upload(model, path))
yield maybe_future(self._upload(model, path))
else:
yield gen.maybe_future(self._new_untitled(path))
yield maybe_future(self._new_untitled(path))

@web.authenticated
@gen.coroutine
def delete(self, path=''):
"""delete a file in the given path"""
cm = self.contents_manager
self.log.warning('delete %s', path)
yield gen.maybe_future(cm.delete(path))
yield maybe_future(cm.delete(path))
self.set_status(204)
self.finish()

Expand All @@ -246,7 +246,7 @@ class CheckpointsHandler(APIHandler):
def get(self, path=''):
"""get lists checkpoints for a file"""
cm = self.contents_manager
checkpoints = yield gen.maybe_future(cm.list_checkpoints(path))
checkpoints = yield maybe_future(cm.list_checkpoints(path))
data = json.dumps(checkpoints, default=date_default)
self.finish(data)

Expand All @@ -255,7 +255,7 @@ def get(self, path=''):
def post(self, path=''):
"""post creates a new checkpoint"""
cm = self.contents_manager
checkpoint = yield gen.maybe_future(cm.create_checkpoint(path))
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']))
Expand All @@ -271,7 +271,7 @@ class ModifyCheckpointsHandler(APIHandler):
def post(self, path, checkpoint_id):
"""post restores a file from a checkpoint"""
cm = self.contents_manager
yield gen.maybe_future(cm.restore_checkpoint(checkpoint_id, path))
yield maybe_future(cm.restore_checkpoint(checkpoint_id, path))
self.set_status(204)
self.finish()

Expand All @@ -280,7 +280,7 @@ def post(self, path, checkpoint_id):
def delete(self, path, checkpoint_id):
"""delete clears a checkpoint for a given file"""
cm = self.contents_manager
yield gen.maybe_future(cm.delete_checkpoint(checkpoint_id, path))
yield maybe_future(cm.delete_checkpoint(checkpoint_id, path))
self.set_status(204)
self.finish()

Expand All @@ -307,7 +307,7 @@ class TrustNotebooksHandler(IPythonHandler):
@gen.coroutine
def post(self,path=''):
cm = self.contents_manager
yield gen.maybe_future(cm.trust_notebook(path))
yield maybe_future(cm.trust_notebook(path))
self.set_status(201)
self.finish()
#-----------------------------------------------------------------------------
Expand Down
Loading

0 comments on commit d17caf9

Please sign in to comment.