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 {}) }
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 []
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