Source code for authomatic.adapters
# -*- coding: utf-8 -*-
"""
Framework Adapters
------------------
The :func:`authomatic.login` function needs access to functionality like
getting the url of the handler where it is called, getting the request params, headers and cookies and
writing the body, headers and status to the response.
Since implementation of these features varies across Python web frameworks,
the Authomatic library uses **adapters** to unify these differences into a single interface.
Implementing an adapter for a Python web framework is pretty easy.
You do it by subclassing the :class:`.BaseAdapter` abstract class.
There are only **seven** members that you need to implement.
Moreover if your framework is based on the |webob|_ library
you can subclass the :class:`.WebObBaseAdapter` and you only need to
override the constructor.
.. autoclass:: BaseAdapter
:members:
.. autoclass:: WebObBaseAdapter
:members:
.. autoclass:: Webapp2Adapter
:members:
"""
import abc
[docs]class BaseAdapter(object):
"""
Base class for platform adapters
Defines common interface for WSGI framework specific functionality.
"""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
[docs] def write(self, value):
"""
Must write specified value to response.
:param str value:
String to be written to response.
:returns:
:class:`dict`
"""
@abc.abstractproperty
[docs] def params(self):
"""
Must return a dictionary of all request parameters of any HTTP method.
:returns:
:class:`dict`
"""
@abc.abstractproperty
[docs] def url(self):
"""
Must return the url of the actual request including path but without query and fragment
:returns:
:class:`str`
"""
@abc.abstractmethod
@abc.abstractproperty
@abc.abstractproperty
[docs] def cookies(self):
"""
We need it to retrieve the session cookie.
"""
@abc.abstractmethod
[docs] def set_status(self):
"""
To set the staus in JSON endpoint.
"""
[docs]class WebObBaseAdapter(BaseAdapter):
"""
Abstract base class for adapters for |webob|_ based frameworks.
If you use this base class you only need to implement these three :class:`.BaseAdapter` members:
* :meth:`.BaseAdapter.fetch_async`
* :meth:`.BaseAdapter.response_parser`
* :attr:`.BaseAdapter.openid_store`
"""
@abc.abstractproperty
[docs] def request(self):
"""
Must be a |webob|_ :class:`Request`.
"""
@abc.abstractproperty
[docs] def response(self):
"""
Must be a |webob|_ :class:`Response`.
"""
#===========================================================================
# Request
#===========================================================================
@property
def url(self):
return self.request.path_url
@property
def params(self):
return dict(self.request.params)
@property
def headers(self):
return dict(self.request.headers)
@property
def cookies(self):
return dict(self.request.cookies)
#===========================================================================
# Response
#===========================================================================
def write(self, value):
self.response.write(value)
def set_header(self, key, value):
self.response.headers[key] = str(value)
def set_status(self, status):
self.response.status = status
[docs]class Webapp2Adapter(WebObBaseAdapter):
"""
Adapter for the |webapp2|_ framework.
"""
request = None
response = None
def __init__(self, handler):
"""
:param handler:
A |webapp2|_ :class:`RequestHandler` instance.
"""
self.request = handler.request
self.response = handler.response