Ejemplo n.º 1
0
    def is_valid(self, raise_exception=False):
        errors = []

        try:
            self._validated_data = self.load(self.initial_data).data
        except (ValidationError, IncorrectTypeError) as err:
            errors.extend(err.messages.get('errors', []))

        try:
            data, serializers = self.load_profile_updates()
            self._validated_profile_updates_data = data
            self._profile_updates_serializers = serializers
        except (ValidationError, IncorrectTypeError) as err:
            errors.extend(err.messages.get('errors', []))

        if errors:
            self._validated_data = {}
            self._validated_profile_updates_data = []
            self._errors = errors
            if raise_exception:
                err = ValidationError(u'Invalid data.')
                err.messages = {'errors': errors}
                raise err
            return False

        self._errors = {}
        return True
Ejemplo n.º 2
0
    def is_valid(self, raise_exception=False):
        errors = []

        try:
            self._validated_data = self.load(self.initial_data).data
        except (ValidationError, IncorrectTypeError) as err:
            errors.extend(err.messages.get('errors', []))

        try:
            data, serializers = self.load_profile_updates()
            self._validated_profile_updates_data = data
            self._profile_updates_serializers = serializers
        except (ValidationError, IncorrectTypeError) as err:
            errors.extend(err.messages.get('errors', []))

        if errors:
            self._validated_data = {}
            self._validated_profile_updates_data = []
            self._errors = errors
            if raise_exception:
                err = ValidationError(u'Invalid data.')
                err.messages = {
                    'errors': errors
                }
                raise err
            return False

        self._errors = {}
        return True
Ejemplo n.º 3
0
 async def _async_on_validation_error(
     self, error: ValidationError, req: core.Request, schema: Schema,
     location: str, *, error_status_code: typing.Optional[int],
     error_headers: typing.Optional[typing.Mapping[str, str]]
 ) -> typing.NoReturn:
     # rewrite messages to be namespaced under the location which created
     # them
     # e.g. {"json":{"foo":["Not a valid integer."]}}
     #      instead of
     #      {"foo":["Not a valid integer."]}
     error.messages = {location: error.messages}
     error_handler = self.error_callback or self.handle_error
     # an async error handler was registered, await it
     if inspect.iscoroutinefunction(error_handler):
         async_error_handler = typing.cast(AsyncErrorHandler, error_handler)
         await async_error_handler(
             error,
             req,
             schema,
             error_status_code=error_status_code,
             error_headers=error_headers,
         )
         # workaround for mypy not understanding `await Awaitable[NoReturn]`
         # see: https://github.com/python/mypy/issues/8974
         raise NotImplementedError("unreachable")
     # the error handler was synchronous (e.g. Parser.handle_error) so it
     # will raise an error
     else:
         error_handler(
             error,
             req,
             schema,
             error_status_code=error_status_code,
             error_headers=error_headers,
         )
Ejemplo n.º 4
0
 async def _on_validation_error(
         self, error: ValidationError, req: Request, schema: Schema,
         location: str, *, error_status_code: typing.Union[int, None],
         error_headers: typing.Union[typing.Mapping[str, str],
                                     None]) -> None:
     # rewrite messages to be namespaced under the location which created
     # them
     # e.g. {"json":{"foo":["Not a valid integer."]}}
     #      instead of
     #      {"foo":["Not a valid integer."]}
     error.messages = {location: error.messages}
     error_handler = self.error_callback or self.handle_error
     await error_handler(
         error,
         req,
         schema,
         error_status_code=error_status_code,
         error_headers=error_headers,
     )
Ejemplo n.º 5
0
 def _on_validation_error(
     self,
     error: ValidationError,
     req: Request,
     schema: ma.Schema,
     location: str,
     *,
     error_status_code: typing.Optional[int],
     error_headers: typing.Optional[typing.Mapping[str, str]]
 ) -> typing.NoReturn:
     # rewrite messages to be namespaced under the location which created
     # them
     # e.g. {"json":{"foo":["Not a valid integer."]}}
     #      instead of
     #      {"foo":["Not a valid integer."]}
     error.messages = {location: error.messages}
     error_handler: ErrorHandler = self.error_callback or self.handle_error
     error_handler(
         error,
         req,
         schema,
         error_status_code=error_status_code,
         error_headers=error_headers,
     )
Ejemplo n.º 6
0
    def load_profile_updates(self):
        if UPDATES_PROFILE not in self.initial_data.get('links',
                                                        {}).get('profile', []):
            return [], []
        for alias, profile in iteritems(self.initial_data.get('aliases', {})):
            if profile == UPDATES_PROFILE:
                break
        else:
            return [], []

        errors = []
        validated_data = []
        profile_serializers = []
        for i, update in enumerate(
                self.initial_data.get('meta', {}).get(alias, [])):
            if 'type' not in update:
                errors.append({
                    'detail': '`data` object must include `type` key.',
                    'source': {
                        'pointer': '/meta/{}/{}/data'.format(alias, i)
                    }
                })
                continue

            type_ = update['type']
            data = {
                'data': update,
            }

            try:
                serializer_class = get_schema(type_)
            except ImproperlyConfigured:
                errors.append({
                    'detail': 'Invalid type: {}.'.format(type_),
                    'source': {
                        'pointer': '/meta/{}/{}/data/type'.format(alias, i),
                    },
                })
                continue

            serializer = serializer_class(
                data=data,
                partial=set(
                    serializer_class.opts.model._ordered_fields).difference(
                        {'id'}))

            try:
                validated_data.append(serializer.validated_data)
                profile_serializers.append(serializer)
            except (ValidationError, IncorrectTypeError) as err:
                errors.extend({
                    'detail': error['detail'],
                    'source': {
                        'pointer':
                        '/meta/{}/{}{}'.format(alias, i, error['source']
                                               ['pointer'])
                    },
                } for error in err.messages.get('errors', []))
                continue

        if errors:
            err = ValidationError(u'Invalid data for updates.')
            err.messages = {'errors': errors}
            raise err

        return validated_data, profile_serializers
Ejemplo n.º 7
0
    def load_profile_updates(self):
        if UPDATES_PROFILE not in self.initial_data.get(
                'links', {}).get('profile', []):
            return [], []
        for alias, profile in iteritems(self.initial_data.get('aliases', {})):
            if profile == UPDATES_PROFILE:
                break
        else:
            return [], []

        errors = []
        validated_data = []
        profile_serializers = []
        for i, update in enumerate(
                self.initial_data.get('meta', {}).get(alias, [])):
            if 'type' not in update:
                errors.append({
                    'detail': '`data` object must include `type` key.',
                    'source': {
                        'pointer': '/meta/{}/{}/data'.format(alias, i)
                    }
                })
                continue

            type_ = update['type']
            data = {
                'data': update,
            }

            try:
                serializer_class = get_schema(type_)
            except ImproperlyConfigured:
                errors.append({
                    'detail': 'Invalid type: {}.'.format(type_),
                    'source': {
                        'pointer': '/meta/{}/{}/data/type'.format(alias, i),
                    },
                })
                continue

            serializer = serializer_class(
                data=data,
                partial=set(
                    serializer_class.opts.model._ordered_fields).difference(
                        {'id'}))

            try:
                validated_data.append(serializer.validated_data)
                profile_serializers.append(serializer)
            except (ValidationError, IncorrectTypeError) as err:
                errors.extend({
                    'detail': error['detail'],
                    'source': {
                        'pointer': '/meta/{}/{}{}'.format(
                            alias, i, error['source']['pointer'])
                    },
                } for error in err.messages.get('errors', []))
                continue

        if errors:
            err = ValidationError(u'Invalid data for updates.')
            err.messages = {
                'errors': errors
            }
            raise err

        return validated_data, profile_serializers