def validate_page(self): limit = self._page.get('limit', self.DEFAULT_LIMIT) offset = self._page.get('offset', self.DEFAULT_OFFSET) try: limit = int(limit) except ValueError: detail = 'Requested page limit "{}" is not integer.'.format(limit) error = ApiError().InvalidQueryParameter(detail).Parameter('page[limit]') raise ViewValidationError(errors=error) if limit > self.MAX_LIMIT: detail = 'Requested page limit "{}" is too big. Maximum is {}'.format(limit, self.MAX_LIMIT) error = ApiError().InvalidQueryParameter(detail).Parameter('page[limit]') raise ViewValidationError(errors=error) try: offset = int(offset) except ValueError: detail = 'Requested page offset "{}" is not integer.'.format(offset) error = ApiError().InvalidQueryParameter(detail).Parameter('page[offset]') raise ViewValidationError(errors=error) self._page.update({ 'limit': limit, 'offset': offset, })
async def validate_body(self): if self.Meta.multipart: if self.request.content_type != 'multipart/form-data': logger.debug('Expected a multipart request but received "{}"'.format(self.request.content_type)) error = ApiError().InvalidFormat('multipart/form-data content type is required') raise ViewError(errors=error) return if not self.Meta.body_data_schema: return try: data = await self.request.json() except JSONDecodeError as e: logger.debug('Bad request: {}, error: {}'.format(await self.request.text(), e.args)) raise ViewError(errors=ApiError().InvalidFormat('Invalid json')) try: validate_json(data, self.Meta.body_data_schema) except ValidationError as e: logger.debug('Bad request data: {}, error: {}'.format(data, e.message)) error = ApiError().InvalidDataSchema(e.message).Pointer(e.path) raise ViewValidationError(errors=error) self.body_data = data
def validate_filters(self): filter_keys = set([re.sub('__(lte|gte|ne)$', '', filter_key) for filter_key in self._filters.keys()]) unavailable_filters = filter_keys - set(self.available_filters) if unavailable_filters: errors = [] for filter_name in unavailable_filters: detail = 'Requested filter is not available - "{}"'.format(filter_name) errors.append(ApiError().InvalidQueryParameter(detail).Parameter('filter[{}]'.format(filter_name))) raise ViewValidationError(errors=errors) for filter_field, filter_value in self._filters.items(): is_comparison_operator = filter_field.endswith('lte') or filter_field.endswith('gte') if is_comparison_operator and isinstance(filter_value, list): detail = 'Requested filter[{}] comparison operation not applied to list.'.format(filter_field) error = ApiError().InvalidFilterOperator(detail).Parameter('filter[{}]'.format(filter_field)) raise ViewValidationError(errors=error)
async def handle(request): try: return await handler(request) except HTTPCustomError: raise except HTTPNotFound as e: error = ApiError().EntityNotFound(e.body.decode()) raise HTTPCustomError(error, HTTPNotFound.status_code) except HTTPClientError as e: # this case for 403, 405 and etc. client errors error = ApiError().BaseClientError(e.reason, e.body.decode()) raise HTTPCustomError(error, e.status_code) except Exception as e: logger.exception(e) detail = str(e) if is_debug else INTERNAL_SERVER_ERROR_MESSAGE error = ApiError().InternalError(detail) raise HTTPCustomError(error)
def validate_includes(self): unavailable_includes = set(self._include.keys()) - set(self.available_includes) if unavailable_includes: errors = [] for include in unavailable_includes: detail = 'Requested include is not available - "{}"'.format(str(include)) errors.append(ApiError().InvalidQueryParameter(detail).Parameter('include')) raise ViewValidationError(errors=errors) self._validate_include_params()
def validate_fields(self): if not self._fields: return unavailable_fields = set(self._fields) - set(self.available_fields) if unavailable_fields: errors = [] for field in unavailable_fields: detail = 'Requested field is not available - "{}"'.format(field) errors.append(ApiError().InvalidQueryParameter(detail).Parameter('fields')) raise ViewValidationError(errors=errors)
def validate_sort(self): if not self._sort: return clean_sort_fields = [sort_field.strip('-') for sort_field in self._sort] unavailable_sort_fields = set(clean_sort_fields) - set(self.available_sort_fields) if unavailable_sort_fields: errors = [] for field in unavailable_sort_fields: detail = 'Requested sort field is not available - "{}"'.format(field) errors.append(ApiError().InvalidQueryParameter(detail).Parameter('sort')) raise ViewValidationError(errors=errors)