class ResourceRepositoryViewSet:
    repository = repositories.ResourceRepository()
    schema = descriptors.NotImplementedProperty('schema')
    filter_schema = filters_schema.FilterSchema()
    detail_view_cls = ResourceRepositoryDetailView
    list_view_cls = ResourceRepositoryListView
    view_decorators = ()
    view_kwargs = None

    def __init__(self,
                 *,
                 repository=None,
                 schema=None,
                 filter_schema=None,
                 detail_view_cls=None,
                 list_view_cls=None,
                 view_decorators=None,
                 view_kwargs=None):
        if repository:
            self.repository = repository
        if schema:
            self.schema = schema
        if filter_schema:
            self.filter_schema = filter_schema
        if detail_view_cls:
            self.detail_view_cls = detail_view_cls
        if list_view_cls:
            self.list_view_cls = list_view_cls
        if view_decorators:
            self.view_decorators = view_decorators
        if view_kwargs:
            self.view_kwargs = view_kwargs

    def as_detail_view(self, view_name):
        return self.decorate(
            self.detail_view_cls.as_view(view_name, **self.get_views_kwargs()))

    def as_list_view(self, view_name):
        return self.decorate(
            self.list_view_cls.as_view(view_name,
                                       filter_schema=self.filter_schema,
                                       **self.get_views_kwargs()))

    def decorate(self, view):
        for decorator in self.view_decorators:
            view = decorator(view)
        return view

    def get_views_kwargs(self):
        return {
            'schema': self.schema,
            'repository': self.repository,
            **(self.view_kwargs or {})
        }
Example #2
0
class ResourceList(ResourceBase):
    methods = ['GET', 'POST']
    filter_schema = filters_schema.FilterSchema({})

    def __init__(self, *, filter_schema=None, **kwargs):
        super().__init__(**kwargs)
        if filter_schema:
            self.filter_schema = filter_schema

    def get(self, *args, **kwargs):
        objects_list = self.read_many(filters=self.filter_schema.parse())
        include_fields = self._check_include_fields()
        try:
            objects, errors = self.schema(
                many=True, include_data=include_fields).dump(objects_list)
        except marshmallow.ValidationError as e:
            return response.JsonApiErrorResponse.from_marshmallow_errors(
                e.messages)
        else:
            if errors:
                return response.JsonApiErrorResponse.from_marshmallow_errors(
                    errors)
            else:
                return response.JsonApiListResponse(response_data=objects, )

    def post(self, *args, **kwargs):
        try:
            data, errors = self.schema().load(request.get_json())
        except marshmallow_jsonapi_exceptions.IncorrectTypeError as e:
            return response.JsonApiErrorResponse.from_marshmallow_errors(
                e.messages)
        except marshmallow.ValidationError as e:
            return response.JsonApiErrorResponse.from_marshmallow_errors(
                e.messages)
        else:
            if errors:
                response.JsonApiErrorResponse.from_marshmallow_errors(errors)
            else:
                return self.prepare_response(data)

    def prepare_response(self, data):
        object = self.create(data=data)
        return response.JsonApiResponse(
            self.schema().dump(object).data,
            status=http.HTTPStatus.CREATED,
        )

    def read_many(self, filters):
        raise NotImplementedError

    def create(self, data, **kwargs):
        raise NotImplementedError
    class ExampleListView(resources.ResourceList):
        schema = example_schema
        filter_schema = filters_schema.FilterSchema({
            'basic':
            filters_schema.FilterField(),
            'listed':
            filters_schema.ListFilterField(),
            'renamed':
            filters_schema.FilterField(field_name='dumb-name'),
            'integer':
            filters_schema.FilterField(parse_value=int),
            'skipped_filter':
            filters_schema.FilterField(),
        })

        applied_filters = []

        def read_many(self, filters):
            self.applied_filters.append(filters)
            return []
Example #4
0
class ResourceList(ResourceBase):
    methods = ['GET', 'POST']
    filter_schema = filters_schema.FilterSchema()
    pagination = query_string.SizeNumberPagination()

    def __init__(self, *, filter_schema=None, **kwargs):
        super().__init__(**kwargs)
        if filter_schema:
            self.filter_schema = filter_schema

    def get(self, *args, **kwargs):
        parsed_filters = self.filter_schema.parse()
        parsed_pagination = self.pagination.parse()
        objects_list = self.read_many(filters=parsed_filters,
                                      pagination=parsed_pagination)
        include_fields = self.include_parser.parse()
        sparse_fields = self.sparse_fields_parser.parse()
        try:
            objects, errors = self.schema(
                many=True, include_data=include_fields,
                only=sparse_fields).dump(objects_list)
        except marshmallow.ValidationError as e:
            return response.JsonApiErrorResponse.from_marshmallow_errors(
                e.messages)
        except (AttributeError, KeyError, ValueError) as e:
            logger.error('Error Processing Request',
                         extra={
                             'status_code': http.HTTPStatus.BAD_REQUEST,
                             'request': request,
                             'exception': e
                         })
            return helpers.make_response('Error Processing Request',
                                         http.HTTPStatus.BAD_REQUEST)
        else:
            if errors:
                return response.JsonApiErrorResponse.from_marshmallow_errors(
                    errors)
            else:
                pagination_links = self.get_pagination_links(
                    parsed_pagination, parsed_filters)
                return response.JsonApiListResponse(
                    response_data=objects,
                    links=pagination_links,
                )

    def get_pagination_links(self, parsed_pagination, parsed_filters):
        if parsed_pagination:
            page_size = parsed_pagination['size']
            current_page = parsed_pagination['number']
            total_count = self.get_count(filters=parsed_filters)
            pagination_links = self.pagination.get_links(
                page_size, current_page, total_count)
        else:
            pagination_links = {}
        return pagination_links

    def post(self, *args, **kwargs):
        try:
            data, errors = self.schema().load(request.get_json())
        except marshmallow_jsonapi_exceptions.IncorrectTypeError as e:
            return response.JsonApiErrorResponse.from_marshmallow_errors(
                e.messages)
        except marshmallow.ValidationError as e:
            return response.JsonApiErrorResponse.from_marshmallow_errors(
                e.messages)
        else:
            if errors:
                response.JsonApiErrorResponse.from_marshmallow_errors(errors)
            else:
                return self.prepare_response(data)

    def prepare_response(self, data):
        object = self.create(data=data)
        return response.JsonApiResponse(
            self.schema().dump(object).data,
            status=http.HTTPStatus.CREATED,
        )

    def read_many(self, filters, pagination):
        raise NotImplementedError

    def get_count(self, filters):
        raise NotImplementedError

    def create(self, data, **kwargs):
        raise NotImplementedError