Skip to content

Instantly share code, notes, and snippets.

@froseph
Forked from mitechie/jsonresponse.py
Created February 15, 2013 00:27
Show Gist options
  • Save froseph/4957674 to your computer and use it in GitHub Desktop.
Save froseph/4957674 to your computer and use it in GitHub Desktop.

Revisions

  1. @mitechie mitechie created this gist Apr 6, 2010.
    150 changes: 150 additions & 0 deletions jsonresponse.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,150 @@
    import logging

    try:
    import json
    except ImportError:
    import simplejson as json


    log = logging.getLogger(__name__)


    class JSONResponse(object):
    """JSONResponse provides a standard method of responding to all JSON ajax
    requests.
    So that we can determine success/failure, related messages, and any html
    data payload we wish to send back to the client
    """
    success = False
    message = ""
    payload = {}

    def __init__(self, success=False, message=None, payload=None):
    """Create JSONResponse
    Check for success, message, payload and make sure payload is a dict
    object
    """

    if success:
    self.success = True

    if message is not None:
    self.message = str(message)
    else:
    self.message = ""

    if payload is not None and isinstance(payload, dict):
    self.payload = payload
    else:
    self.payload = {}

    def jsonify(self):
    """Return a json string of the response """
    return json.dumps(self.dict_response())

    def json_response(self, response):
    """Return a json response with headers set manually
    If we want to combine a single json/html response in one controller
    we can't use the jsonify decorator. We need to do the work that the
    jsonify decorator does in here
    """
    response.headers['Content-Type'] = 'application/json'
    return self.jsonify()

    def dict_response(self):
    """Build a dictionary of the response object """
    return {"success": self.success,
    "message": self.message,
    "payload": self.payload}

    from decorator import decorator
    def mijson():
    """Action decorator that formats output for JSON
    Given a function that will return content, this decorator will turn
    the result into JSON, with a content-type of 'application/json' and
    output it.
    adds a method to the controller
    self.accepts_json()
    It checks if the request comes in accepting json and returns a JSONResponse
    object pulling from:
    self.json.success
    self.json.message
    self.json.payload
    returned html content is placed into json.payload.html
    Otherwise it just returns the html output returned.
    A template variable is set so that the template can conditionaly inherit
    or not
    c.request_ajax = Bool
    Sample Controller:
    @myjson()
    def pause(self, id):
    result = SomeObj.pause()
    if result:
    self.json.success = True
    self.json.message = 'Paused'
    else:
    self.json.success = False
    self.json.message = 'Failed'
    self.json.payload['job_id'] = id
    return '<h1>Result was: %s</h1>' % message
    Response:
    {'success': true,
    'message': 'Paused',
    'payload': {'html': '<h1>Result was: Paused</h1>'}}
    """
    def wrapper(func, self, *args, **kwargs):
    request = self._py_object.request
    response = self._py_object.response

    def controller_accepts_json():
    return 'application/json' in request.headers.get('accept', '')


    is_json = False
    self._py_object.c.request_ajax = False
    self.accepts_json = controller_accepts_json

    # go ahead and put this on the controller
    # but we'll only use it if this is a json request
    self.json = JSONResponse()
    self.json.success = False
    self.json.message = ""
    self.json.payload = {}

    if self.accepts_json():
    is_json = True

    # let the template know it's an ajax request
    self._py_object.c.request_ajax = True

    html = func(self, *args, **kwargs)

    if is_json:
    response.headers['Content-Type'] = 'application/json'

    # grab the returned html content and place it in the payload under the
    # key html
    self.json.payload['html'] = html

    log.debug("Returning JSON wrapped action output")
    return self.json.jsonify()
    else:
    return html
    return func(self, *args, **kwargs)
    return decorator(wrapper)