def test_limit(db_session): """Make sure providing a limit query_param works.""" query_params = {"limit": "1"} parser = ModelQueryParamParser(query_params) album_resource = AlbumResource(session=db_session) offset_limit_info = parser.parse_offset_limit(page_max_size=30) offset = offset_limit_info.offset limit = offset_limit_info.limit result = album_resource.get_collection(filters=parser.parse_filters( album_resource.model), sorts=parser.parse_sorts(), limit=limit, offset=offset) assert len(result) == 1
def test_get_second_page(db_session): """Test that we can get the second page of a set of objects.""" query_params = {"sort": "album_id", "page": "2"} parser = ModelQueryParamParser(query_params) album_resource = AlbumResource(session=db_session) offset_limit_info = parser.parse_offset_limit(page_max_size=30) offset = offset_limit_info.offset limit = offset_limit_info.limit result = album_resource.get_collection(filters=parser.parse_filters( album_resource.model), sorts=parser.parse_sorts(), limit=limit, offset=offset) assert len(result) == 30 assert result[0]["album_id"] == 31
def get(self, path, query_params=None, strict=True, head=False): """Generic API router for GET requests. :param str path: The resource path specified. This should not include the root ``/api`` or any versioning info. :param query_params: Dictionary of query parameters, likely provided as part of a request. Defaults to an empty dict. :type query_params: dict or None :param bool strict: If ``True``, bad query params will raise non fatal errors rather than ignoring them. :param bool head: ``True`` if this was a HEAD request. :return: If this is a single entity query, an individual resource or ``None``. If this is a collection query, a list of resources. If it's an instance field query, the raw field value. :raise ResourceNotFoundError: If no resource can be found at the provided path. :raise BadRequestError: Invalid filters, sorts, fields, embeds, offset, or limit as defined in the provided query params will result in a raised exception if strict is set to ``True``. """ if self.resource is None: self._deduce_resource(path) path_objs = self._get_path_objects(path) resource = path_objs.get("resource", None) path_part = path_objs.get("path_part", None) query_session = path_objs.get("query_session", None) ident = path_objs.get("ident", None) parser = ModelQueryParamParser(query_params, context=self.context) fields = parser.parse_fields() embeds = parser.parse_embeds() try: subfilters = parser.parse_subfilters(strict=strict) except ParseError as exc: if strict: raise BadRequestError(code=exc.code, message=exc.message, **exc.kwargs) subfilters = None # last path_part determines what type of request this is if isinstance(path_part, Field) and not isinstance( path_part, NestedPermissibleABC): # Simple property, such as album_id # return only the value field_name = path_part.data_key or path_part.name result = resource.get(ident=ident, fields=[field_name], strict=strict, session=query_session, head=head) if result is not None and field_name in result: return result[field_name] raise self.make_error("resource_not_found", path=path) # pragma: no cover if isinstance(path_part, Field) or isinstance(path_part, BaseModelResource): # resource collection # any non subresource field would already have been handled try: filters = parser.parse_filters( resource.model, convert_key_names_func=resource.convert_key_name) except FilterParseError as e: if strict: raise BadRequestError(code=e.code, message=e.message, **e.kwargs) filters = None if not (isinstance(path_part, Nested) and not path_part.many): try: offset_limit_info = parser.parse_offset_limit( resource.page_max_size) offset = offset_limit_info.offset limit = offset_limit_info.limit except OffsetLimitParseError as e: if strict: raise BadRequestError(code=e.code, message=e.message, **e.kwargs) offset, limit = None, None sorts = parser.parse_sorts() results = resource.get_collection(filters=filters, subfilters=subfilters, fields=fields, embeds=embeds, sorts=sorts, offset=offset, limit=limit, session=query_session, strict=strict, head=head) if query_params.get("page") is not None or not offset: results.current_page = int(query_params.get("page") or 1) results.page_size = limit or resource.page_max_size return results else: result = resource.get_collection(fields=fields, embeds=embeds, subfilters=subfilters, session=query_session, strict=strict, head=head) if len(result) != 1: # pragma: no cover # failsafe, _get_path_objects will catch this first. raise self.make_error("resource_not_found", path=path) return result[0] elif isinstance(path_part, tuple): # path part is a resource identifier # individual instance return resource.get(ident=path_part, fields=fields, embeds=embeds, subfilters=subfilters, strict=strict, session=query_session, head=head) raise self.make_error("resource_not_found", path=path) # pragma: no cover