summaryrefslogtreecommitdiff
path: root/ironic/api/method.py
diff options
context:
space:
mode:
authorSteve Baker <sbaker@redhat.com>2020-07-29 10:41:11 +1200
committerSteve Baker <sbaker@redhat.com>2020-11-16 10:39:40 +1300
commit3846965e9c7407c6b92dcf12dec586ce478c6e60 (patch)
tree3f4b0a6158ef1f09f7e123888a08f503daa1832b /ironic/api/method.py
parent6ea0e8eaf65330e47e9be231fd7871474ad16f76 (diff)
downloadironic-3846965e9c7407c6b92dcf12dec586ce478c6e60.tar.gz
Add expose body decorator, status_code argument
@method.body populates a method argument with the contents of the request JSON. When the request body JSON is a dict, pecan populates the keyword arguments of the method with the values of the dict. This is not desirable for our typical usage so the body decorator also strips these keyword arguments. A status_code argument is also added to @method.expose to set custom responses. Empty response status codes are given special handling. This change also adds unit tests for the @method.expose decorator. Change-Id: I82d75345e4512c79ad7d211e81ca474f1b45a7ca Story: 1651346 Task: 10551
Diffstat (limited to 'ironic/api/method.py')
-rw-r--r--ironic/api/method.py41
1 files changed, 40 insertions, 1 deletions
diff --git a/ironic/api/method.py b/ironic/api/method.py
index 50f672a29..48bd8caa0 100644
--- a/ironic/api/method.py
+++ b/ironic/api/method.py
@@ -32,7 +32,7 @@ pecan_json_decorate = pecan.expose(
generic=False)
-def expose():
+def expose(status_code=None):
def decorate(f):
@@ -40,6 +40,8 @@ def expose():
def callfunction(self, *args, **kwargs):
try:
result = f(self, *args, **kwargs)
+ if status_code:
+ pecan.response.status = status_code
except Exception:
try:
@@ -58,6 +60,18 @@ def expose():
else:
pecan.response.status = 500
+ def _empty():
+ pecan.request.pecan['content_type'] = None
+ pecan.response.content_type = None
+
+ # never return content for NO_CONTENT
+ if pecan.response.status_code == 204:
+ return _empty()
+
+ # don't encode None for ACCEPTED responses
+ if result is None and pecan.response.status_code == 202:
+ return _empty()
+
return json.dumps(result)
pecan_json_decorate(callfunction)
@@ -66,6 +80,31 @@ def expose():
return decorate
+def body(body_arg):
+ """Decorator which places HTTP request body JSON into a method argument
+
+ :param body_arg: Name of argument to populate with body JSON
+ """
+
+ def inner_function(function):
+
+ @functools.wraps(function)
+ def inner_body(*args, **kwargs):
+
+ data = pecan.request.json
+ if isinstance(data, dict):
+ # remove any keyword arguments which pecan has
+ # extracted from the body
+ for field in data.keys():
+ kwargs.pop(field, None)
+
+ kwargs[body_arg] = data
+
+ return function(*args, **kwargs)
+ return inner_body
+ return inner_function
+
+
def format_exception(excinfo, debug=False):
"""Extract informations that can be sent to the client."""
error = excinfo[1]