예제 #1
0
    def convert(self, value: ty.Any, path: t.Path, *args: ty.Any,
                **context: ty.Any) -> ty.Optional[OpenAPIObject]:
        result: ty.Optional[OpenAPIObject] = super(OpenAPIObjectType,
                                                   self).convert(
                                                       value, path, **context)

        if result is None:
            return None

        security_schemes: ty.Mapping[str, AnySecuritySchemeObject] = {}
        components: ty.Optional[ComponentsObject] = result.components
        if components is not None and components.security_schemes:
            security_schemes = components.security_schemes

        errors: ty.List[t.Error] = []
        security: ty.Optional[
            ty.Sequence[SecurityRequirementObject]] = result.security
        if security:
            for i, security_requirement in enumerate(security):
                for scheme_name in security_requirement.additional_properties.keys(
                ):
                    if scheme_name not in security_schemes:
                        errors.append(
                            t.Error(
                                path / 'security' / i,
                                self.messages['undefined_security_scheme'].
                                format(scheme_name)))

        paths: PathsObject = result.paths
        for path_, path_item in paths.pattern_properties.items():
            for http_method in HTTP_METHODS:
                if http_method not in path_item:
                    continue

                operation: OperationObject = path_item[http_method]
                security = operation.security
                if security is None:
                    continue
                for i, security_requirement in enumerate(security):
                    for scheme_name in security_requirement.additional_properties.keys(
                    ):
                        if scheme_name not in security_schemes:
                            errors.append(
                                t.Error(
                                    path / 'paths' / path_ / http_method /
                                    'security' / i,
                                    self.messages['undefined_security_scheme'].
                                    format(scheme_name)))

        if errors:
            raise t.SchemaError(*errors)

        return result
예제 #2
0
    def _convert(self, value: ty.Any, path: t.Path, *args: ty.Any,
                 **context: ty.Any) -> SchemaObject:
        result: SchemaObject = super(SchemaObjectType,
                                     self)._convert(value, path, **context)

        if result.type is None:
            inferred = []
            for schema_type, keywords in TYPE_SPECIFIC_KEYWORDS.items():
                if any(keyword for keyword in keywords if keyword in value):
                    inferred.append(schema_type)

            if len(inferred) > 1:
                raise t.SchemaError(
                    t.Error(path, self.messages['ambiguous_type']))

            elif inferred:
                result.properties['type'] = inferred[0]

        if result.deprecated:
            warnings.warn(self.messages['deprecated'].format(path),
                          DeprecationWarning)

        if result.required:
            result.properties['required'] = set(result.required)

        result.path = path
        return result
예제 #3
0
    def convert(self,
                value: ty.Any,
                path: t.Path,
                *args: ty.Any,
                operation_ids: ty.Optional[OperationIds] = None,
                **context: ty.Any) -> ty.Optional[OperationObject]:
        assert operation_ids is not None

        result: ty.Optional[OperationObject] = super(
            OperationObjectType, self).convert(value, path, **context)

        if result is None:
            return None

        if result.deprecated:
            warnings.warn(self.messages['deprecated'].format(path),
                          DeprecationWarning)

        operation_id = result.operation_id
        if operation_id is not None:
            if operation_id in operation_ids:
                raise t.SchemaError(
                    t.Error(
                        path / 'operationId',
                        self.messages['operation_id'].format(
                            operation_id, operation_ids[operation_id])))

            operation_ids[operation_id] = path / 'operationId'

        return result
예제 #4
0
    def _convert(self,
                 value: ty.Mapping[str, str],
                 path: t.Path,
                 *args: ty.Any,
                 strict: bool = True,
                 entity: ty.Optional[t.ConvertibleEntity] = None,
                 **context: ty.Any) -> ty.Any:
        try:
            value = self.style.extract(value, self.name)
        except (ValueError, TypeError, LookupError):
            raise t.SchemaError(
                t.Error(path, self.messages['extract'].format(self.name)))

        if value is t.Undefined and self.required:
            raise t.SchemaError(t.Error(path, self.messages['required']))

        elif value is not t.Undefined:
            if not value and self.allow_empty_value is not None and not self.allow_empty_value:
                raise t.SchemaError(t.Error(path, self.messages['empty']))

            if entity == t.ConvertibleEntity.REQUEST:
                try:
                    value = self.style.deserialize(value)
                except (TypeError, ValueError):
                    raise t.SchemaError(
                        t.Error(path, self.messages['deserialize']))

        if entity == t.ConvertibleEntity.REQUEST:
            strict = self.strict

        result = self.subtype.convert(value,
                                      path,
                                      strict=strict,
                                      entity=entity,
                                      **context)

        if entity == t.ConvertibleEntity.RESPONSE:
            try:
                return self.style.serialize(result)
            except (TypeError, ValueError):
                raise t.SchemaError(t.Error(path, self.messages['serialize']))

        return result
예제 #5
0
    def convert(self, value: ty.Any, path: t.Path, *args: ty.Any, **context: ty.Any) -> ty.Optional[T]:
        result = self.subtype.convert(value, path, *args, **context)

        if result is None:
            return None

        k, v = next(iter(value.items()))
        best = self._get_best_matched(k)

        if best is None:
            raise t.SchemaError(t.Error(path, self.messages['unallowed'].format(
                k, comma_delimited(self.allowed))))

        return best.convert(v, path, **context)
예제 #6
0
    def _convert(self,
                 value: AnyStorage,
                 path: t.Path,
                 *args: ty.Any,
                 strict: bool = False,
                 **context: ty.Any) -> Part:
        content_type = value.content_type or self.default_content_type

        adapted: ty.Dict[str, ty.Any] = {'headers': value.headers}

        if content_type is not None:
            adapted['contentType'] = content_type

        strict = False
        if isinstance(value, FileStorage):
            adapted['content'] = value.stream

        else:
            adapted['content'] = value.value

            if content_type is not None:
                handler = get_media_handler(content_type)
                if handler is not None:
                    strict = True
                    try:
                        adapted['content'] = handler.deserialize(value.value)
                    except (ValueError, TypeError):
                        raise t.SchemaError(
                            t.Error(path, self.messages['deserialize']))

        result = self.subtype.convert(adapted, path, strict=strict, **context)
        assert result is not None

        return Part(custom_headers=result['headers'],
                    content=result['content'],
                    storage=value)
예제 #7
0
    def convert(
        self, value: ty.Any, path: t.Path, *args: ty.Any, **context: ty.Any
    ) -> ty.Optional[ty.Mapping[ty.Pattern, ty.Optional[T]]]:
        mapping: ty.Optional[ty.Mapping[
            str,
            ty.Optional[T]]] = self.subtype.convert(value, path, *args,
                                                    **context)

        if mapping is None:
            return None

        result: ty.Dict[ty.Pattern, ty.Optional[T]] = {}
        errors: ty.List[t.Error] = []
        for key in mapping.keys():
            try:
                result[re.compile(key)] = mapping[key]
            except re.error:
                errors.append(
                    t.Error(path, self.messages['invalid_key'].format(key)))

        if errors:
            raise t.SchemaError(*errors)

        return result
예제 #8
0
    def convert(self, value: ty.Any, path: t.Path, *args: ty.Any, **context: ty.Any) -> ty.Any:
        if value is t.Undefined and self.required:
            raise t.SchemaError(t.Error(path, self.messages['required']))

        return self.subtype.convert(value, path, *args, **context)