'Converts a *request handler* to a JSON backend which you can use with
:ref:`authomatic.js <js>`.
Just call it inside a *request handler* like this:
class JSONHandler(webapp2.RequestHandler):
def get(self):
authomatic.backend(Webapp2Adapter(self))
:param adapter:
The only argument is an :doc:`adapter <adapters>`.
The *request handler* will now accept these request parameters:
:param str type:
Type of the request. Either ``auto``, ``fetch`` or ``elements``.
Default is ``auto``.
:param str credentials:
Serialized :class:`.Credentials`.
:param str url:
URL of the **protected resource** request.
:param str method:
HTTP method of the **protected resource** request.
:param str body:
HTTP body of the **protected resource** request.
:param JSON params:
HTTP params of the **protected resource** request as a JSON object.
:param JSON headers:
HTTP headers of the **protected resource** request as a
JSON object.
:param JSON json:
You can pass all of the aforementioned params except ``type``
in a JSON object.
.. code-block:: javascript
"credentials": "######",
"url": "https://example.com",
"method": "POST",
"params": {"foo": "bar"},
"headers": {"baz": "bing"},
"body": "the body of the request"
Depending on the ``type`` param, the handler will either write
a JSON object with *request elements* to the response,
and add an ``Authomatic-Response-To: elements`` response header, ...
.. code-block:: javascript
"url": "https://example.com/api",
"method": "POST",
"params": {
"access_token": "###",
"foo": "bar"
"headers": {
"baz": "bing",
"Authorization": "Bearer ###"
... or make a fetch to the **protected resource** and forward
it\'s response content, status and headers with an additional
``Authomatic-Response-To: fetch`` header to the response.
.. warning::
The backend will not work if you write anything to the
response in the handler!'

def backend(self, adapter):

    AUTHOMATIC_HEADER = 'Authomatic-Response-To'
    request_type = adapter.params.get('type', 'auto')
    json_input = adapter.params.get('json')
    credentials = adapter.params.get('credentials')
    url = adapter.params.get('url')
    method = adapter.params.get('method', 'GET')
    body = adapter.params.get('body', '')
    params = adapter.params.get('params')
    params = (json.loads(params) if params else {})
    headers = adapter.params.get('headers')
    headers = (json.loads(headers) if headers else {})
    ProviderClass = Credentials.deserialize(self.config, credentials).provider_class
    if (request_type == 'auto'):
        jsonp = params.get('callback')
        if (ProviderClass.supports_jsonp and (method is 'GET')):
            request_type = 'elements'
        else:
            if jsonp:
                params.pop('callback')
            request_type = 'fetch'
    if (request_type == 'fetch'):
        response = self.access(credentials, url, params, method, headers, body)
        result = response.content
        adapter.status = ((str(response.status) + '    ') + str(response.reason))
        for (k, v) in response.getheaders():
            logging.info('                {0}:    {1}'.format(k, v))
            adapter.set_header(k, v)
    elif (request_type == 'elements'):
        if json_input:
            result = self.request_elements(json_input=json_input, return_json=True)
        else:
            result = self.request_elements(credentials=credentials, url=url, method=method, params=params, headers=headers, body=body, return_json=True)
        adapter.set_header('Content-Type', 'application/json')
    else:
        result = '{"error":    "Bad    Request!"}'
    adapter.set_header(AUTHOMATIC_HEADER, request_type)
    adapter.write(result)
