예제 #1
0
    def __init__(self, model, renderer_proxy=None):
        """
        A object which represents an restful service. It offers all the necessary methods and is able to consume a
        renderer proxy. This way we assure a plug able system to use custom renderers. If some custom behaviour is
        wanted at all, you can achieve this by subclassing this class and adding some post or pre processing to the
        desired method.

        :param model: The model for which the service will be created for.
        :type model: sqlalchemy.ext.declarative.DeclarativeMeta
        :param renderer_proxy: A renderer proxy may be passed to achieve custom rendering
        :type renderer_proxy: RenderProxy or None
        """
        self.orm_model = model
        self.model_description = ModelDescription(self.orm_model)
        self.primary_key_names = self.model_description.primary_key_column_names
        self.name = self.name_from_definition(self.model_description.schema_name, self.model_description.table_name)
        if renderer_proxy is None:
            self.renderer_proxy = RenderProxy()
        else:
            self.renderer_proxy = renderer_proxy
예제 #2
0
class Service(object):

    def __init__(self, model, renderer_proxy=None):
        """
        A object which represents an restful service. It offers all the necessary methods and is able to consume a
        renderer proxy. This way we assure a plug able system to use custom renderers. If some custom behaviour is
        wanted at all, you can achieve this by subclassing this class and adding some post or pre processing to the
        desired method.

        :param model: The model for which the service will be created for.
        :type model: sqlalchemy.ext.declarative.DeclarativeMeta
        :param renderer_proxy: A renderer proxy may be passed to achieve custom rendering
        :type renderer_proxy: RenderProxy or None
        """
        self.orm_model = model
        self.model_description = ModelDescription(self.orm_model)
        self.primary_key_names = self.model_description.primary_key_column_names
        self.name = self.name_from_definition(self.model_description.schema_name, self.model_description.table_name)
        if renderer_proxy is None:
            self.renderer_proxy = RenderProxy()
        else:
            self.renderer_proxy = renderer_proxy

    @staticmethod
    def name_from_definition(schema_name, table_name):
        """
        Little helper method to get a comma separated string of schema and table name.

        :param schema_name: The schema name
        :type schema_name: str
        :param table_name: The table name
        :type table_name: str
        :return: schema name and table name concatenated in one string separated by comma.
        :rtype: str
        """
        return '{0},{1}'.format(
            schema_name,
            table_name
        )

    def read(self, request, session):
        """
        The method which is used by the api to read a bunch of records from the database.

        :param request: The request which comes all the way through the application from the client
        :type request: pyramid.request.Request
        :param session: The session which is uesed to emit the query.
        :type session: sqlalchemy.orm.Session
        :return: An pyramid response object
        :rtype: pyramid.response.Response
        """
        query = session.query(self.orm_model)
        if request.method == RestProxy.read_filter_method:
            rest_filter = Filter(self.model_description, **request.json_body.get('filter'))
            query = rest_filter.filter(query)
        results = query.all()
        return self.renderer_proxy.render(request, results, self.model_description)

    def show(self, request, session):
        """
        The method which is used by the api to read exact one record from the database.

        :param request: The request which comes all the way through the application from the client
        :type request: pyramid.request.Request
        :param session: The session which is uesed to emit the query.
        :type session: sqlalchemy.orm.Session
        :return: An pyramid response object
        :rtype: pyramid.response.Response
        :raises: HTTPBadRequest
        """
        requested_primary_keys = request.matchdict['primary_keys']
        model_description = ModelDescription(self.orm_model)
        model_primary_keys = model_description.primary_key_columns.items()
        if len(requested_primary_keys) != len(model_primary_keys):
            text = "The number of passed primary keys mismatch the model given. Can't complete the request. Sorry..."
            log.error(text)
            raise HTTPBadRequest(
                detail=text
            )
        query = session.query(self.orm_model)
        for index, requested_primary_key in enumerate(requested_primary_keys):
            query = query.filter(model_primary_keys[index][1] == requested_primary_key)
        try:
            result = query.one()
            return self.renderer_proxy.render(request, [result], self.model_description)
        except MultipleResultsFound, e:
            text = "Strange thing happened... Found more than one record for the primary key(s) you passed."
            log.error('{text}, Original error was: {error}'.format(text=text, error=e))
            raise HTTPBadRequest(
                detail=text
            )