From 0a14231e6dfa448f27acc7b3337eadd6b989a8b6 Mon Sep 17 00:00:00 2001 From: Ryan Casey Date: Sat, 17 May 2014 17:37:58 -0700 Subject: [PATCH 1/3] Play nice with Flask-HTTPAuth. --- flask_jsonrpc/site.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/flask_jsonrpc/site.py b/flask_jsonrpc/site.py index a968696..6d823e9 100644 --- a/flask_jsonrpc/site.py +++ b/flask_jsonrpc/site.py @@ -34,6 +34,7 @@ from werkzeug.exceptions import HTTPException from flask import json, jsonify, current_app, got_request_exception +from flask.wrappers import Response from flask_jsonrpc.types import Object, Array, Any from flask_jsonrpc.helpers import extract_raw_data_request, log_exception @@ -211,18 +212,21 @@ def response_dict(self, request, D, is_batch=False, version_hint='1.0'): return None, 204 encoder = current_app.json_encoder() + response['result'] = R + status = 200 # type of `R` should be one of these or... - if not sum([isinstance(R, e) for e in \ + if isinstance(R, Response): + status = R.status_code + response['result'] = R.status + + elif not sum([isinstance(R, e) for e in \ string_types + integer_types + (dict, list, set, NoneType, bool)]): try: rs = encoder.default(R) # ...or something this thing supports except TypeError as exc: raise TypeError("Return type not supported, for {0!r}".format(R)) - response['result'] = R - - status = 200 except Error as e: # exception missed by others From bb3bbe4b97e37835a2e59a885312d7402df1e6bc Mon Sep 17 00:00:00 2001 From: Ryan Casey Date: Mon, 19 May 2014 23:06:47 -0700 Subject: [PATCH 2/3] Allow method decorators to be passed in when creating the JSONRPC object. --- flask_jsonrpc/__init__.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/flask_jsonrpc/__init__.py b/flask_jsonrpc/__init__.py index 8152f17..763ddc3 100644 --- a/flask_jsonrpc/__init__.py +++ b/flask_jsonrpc/__init__.py @@ -156,26 +156,31 @@ def _inject_args(sig, types): sig = '{0}({1})'.format(sig, ', '.join(types)) return sig -def _site_api(site): +def _site_api(site, decorators=[]): def wrapper(method=''): response_dict, status_code = site.dispatch(request, method) if current_app.config['DEBUG']: logging.debug('request: %s', extract_raw_data_request(request)) logging.debug('response: %s, %s', status_code, response_dict) - return jsonify_status_code(status_code, response_dict), status_code + + response_func = jsonify_status_code + for decorator in decorators: + response_func = decorator(response_func) + + return response_func(status_code, response_dict), status_code return wrapper class JSONRPC(object): def __init__(self, app=None, service_url='/api', auth_backend=authenticate, site=default_site, - enable_web_browsable_api=False): + enable_web_browsable_api=False, decorators=[]): self.service_url = service_url self.browse_url = self._make_browse_url(service_url) self.enable_web_browsable_api = enable_web_browsable_api self.auth_backend = auth_backend self.site = site - self.site_api = _site_api(site) + self.site_api = _site_api(site, decorators=decorators) if app is not None: self.app = app self.init_app(self.app) From 6fbcf8e7e6d2456dcc20fb1ed8ac27c098c74cae Mon Sep 17 00:00:00 2001 From: Ryan Casey Date: Mon, 19 May 2014 23:07:06 -0700 Subject: [PATCH 3/3] Add OPTIONS HTTP method support. --- flask_jsonrpc/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flask_jsonrpc/__init__.py b/flask_jsonrpc/__init__.py index 763ddc3..956fd42 100644 --- a/flask_jsonrpc/__init__.py +++ b/flask_jsonrpc/__init__.py @@ -212,11 +212,11 @@ def _enable_web_browsable_api(self, app, url_prefix=None): jsonrpc_site_name=self._unique_name(), jsonrpc_site=self.site) def init_app(self, app): - app.add_url_rule(self.service_url, self._unique_name(), self.site_api, methods=['POST']) + app.add_url_rule(self.service_url, self._unique_name(), self.site_api, methods=['POST', 'OPTIONS']) app.add_url_rule(self.service_url + '/', self._unique_name('/'), self.site_api, methods=['GET']) def register_blueprint(self, blueprint): - blueprint.add_url_rule(self.service_url, '', self.site_api, methods=['POST']) + blueprint.add_url_rule(self.service_url, '', self.site_api, methods=['POST', 'OPTIONS']) blueprint.add_url_rule(self.service_url + '/', '', self.site_api, methods=['GET']) def method(self, name, authenticated=False, safe=False, validate=False, **options):