makes sure the response' document has all leaf-fields converted to string

def safe_json_response(method):
    """ makes sure the response' document has all leaf-fields converted to string """

    def _safe_document(document):
        """ function modifies the document in place
            it iterates over the json document and stringify all non-string types
            :return: modified document """
        assert isinstance(document, dict), 'Error: provided document is not of DICT type: {0}' \
            .format(document.__class__.__name__)

        for key, value in document.items():
            if isinstance(value, dict):
                document[key] = {k: str(v) for k, v in value.items()}
            elif isinstance(value, list):
                document[key] = [str(v) for v in value]
            else:
                document[key] = str(document[key])
        return document

    @functools.wraps(method)
    def _wrapper(self, *args, **kwargs):
        try:
            document = method(self, *args, **kwargs)
            return _safe_document(document)
        except Exception as e:
            return self.reply_server_error(e)

    return _wrapper