Added mini-framework for PATCH handlers per node type.

This commit is contained in:
Sybren A. Stüvel 2016-07-27 16:58:24 +02:00
parent 14ec0feec4
commit 63a78440a1
4 changed files with 76 additions and 1 deletions

View File

@ -393,6 +393,10 @@ def after_deleting_node(item):
def setup_app(app, url_prefix): def setup_app(app, url_prefix):
from . import patch
patch.setup_app(app, url_prefix=url_prefix)
app.on_fetched_item_nodes += before_returning_node app.on_fetched_item_nodes += before_returning_node
app.on_fetched_resource_nodes += before_returning_nodes app.on_fetched_resource_nodes += before_returning_nodes

View File

@ -0,0 +1,20 @@
import logging
log = logging.getLogger(__name__)
patch_handlers = {} # mapping from node type to callable.
def register_patch_handler(node_type):
"""Decorator, registers the decorated function as patch handler for the given node type."""
def wrapper(func):
if node_type in patch_handlers:
raise ValueError('Node type %r already handled by %r' %
(node_type, patch_handlers[node_type]))
log.debug('Registering %s as PATCH handler for node type %r',
func, node_type)
patch_handlers[node_type] = func
return func
return wrapper

View File

@ -0,0 +1,51 @@
"""Generic node patching support.
Depends on node_type-specific patch handlers in submodules.
"""
import logging
from flask import Blueprint, request
import werkzeug.exceptions as wz_exceptions
from application.utils import str2id
from application.utils import authorization, mongo, authentication
from . import custom
log = logging.getLogger(__name__)
blueprint = Blueprint('nodes.patch', __name__)
@blueprint.route('/<node_id>', methods=['PATCH'])
@authorization.require_login()
def patch_node(node_id):
# Parse the request
node_id = str2id(node_id)
patch = request.get_json()
# Find the node type.
node = mongo.find_one_or_404('nodes', node_id,
projection={'node_type': 1})
try:
node_type = node['node_type']
except KeyError:
msg = 'Node %s has no node_type property' % node_id
log.warning(msg)
raise wz_exceptions.InternalServerError(msg)
log.debug('User %s wants to PATCH %s node %s',
authentication.current_user_id(), node_type, node_id)
# Find the PATCH handler for the node type.
try:
patch_handler = custom.patch_handlers[node_type]
except KeyError:
log.info('No patch handler for node type %r', node_type)
raise wz_exceptions.MethodNotAllowed('PATCH on node type %r not allowed' % node_type)
# Let the PATCH handler do its thing.
return patch_handler(node_id, patch)
def setup_app(app, url_prefix):
app.register_blueprint(blueprint, url_prefix=url_prefix)

View File

@ -7,7 +7,7 @@ RESOURCE_METHODS = ['GET', 'POST', 'DELETE']
# Enable reads (GET), edits (PATCH), replacements (PUT) and deletes of # Enable reads (GET), edits (PATCH), replacements (PUT) and deletes of
# individual items (defaults to read-only item access). # individual items (defaults to read-only item access).
ITEM_METHODS = ['GET', 'PUT', 'DELETE', 'PATCH'] ITEM_METHODS = ['GET', 'PUT', 'DELETE']
PAGINATION_LIMIT = 250 PAGINATION_LIMIT = 250
PAGINATION_DEFAULT = 250 PAGINATION_DEFAULT = 250