class EncodingObjectType(BaseOpenAPIObjectType[EncodingObject], result_class=EncodingObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'contentType': CommaDelimitedArrayType( item_type=t.StringType(), max_items=2, validators=(CONTENT_TYPE_VALIDATOR,)), 'headers': t.MapType[HeaderObject]( t.ReferenceType[HeaderObject](t.LazyType[HeaderObject](lambda: HeaderObjectType()))), 'style': t.StringType( enum=( PARAMETER_STYLE.FORM, PARAMETER_STYLE.SPACE_DELIMITED, PARAMETER_STYLE.PIPE_DELIMITED, PARAMETER_STYLE.DEEP_OBJECT ), default=PARAMETER_STYLE.FORM ), 'explode': t.BooleanType(), 'allowReserved': t.BooleanType( enum=[False], messages={'enum': "`allowReserved` permanently unsupported"}, default=False ), 'x-parameterType': t.StringType(enum=PARAMETER_TYPE), }
class BaseSecuritySchemeObjectType(BaseOpenAPIObjectType[T_base]): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'type': t.StringType(enum=SECURITY_SCHEME_TYPE), 'description': t.StringType() } REQUIRED: ty.ClassVar[t.Required] = {'type'}
class XmlObjectType(BaseOpenAPIObjectType[XmlObject], result_class=XmlObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'name': t.StringType(), 'namespace': t.StringType(), 'prefix': t.StringType(), 'attribute': t.BooleanType(default=False), 'wrapped': t.BooleanType(default=False) }
class DiscriminatorObjectType(BaseOpenAPIObjectType[DiscriminatorObject], result_class=DiscriminatorObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'propertyName': t.StringType(min_length=1), 'mapping': t.MapType[str](t.StringType(min_length=1)) } REQUIRED: ty.ClassVar[t.Required] = {'propertyName'}
class ExampleObjectType(BaseOpenAPIObjectType[ExampleObject], result_class=ExampleObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'summary': t.StringType(), 'description': t.StringType(), 'value': t.AnyType(), 'externalValue': t.StringType() }
class TagObjectType(BaseOpenAPIObjectType[TagObject], result_class=TagObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'name': t.StringType(), 'description': t.StringType(), 'externalDocs': ExternalDocumentationObjectType() } REQUIRED: ty.ClassVar[t.Required] = {'name'}
class LinkObjectType(BaseOpenAPIObjectType[LinkObject], result_class=LinkObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'operationRef': t.StringType(), 'operationId': t.StringType(), 'parameters': t.MapType(t.AnyType()), 'requestBody': t.AnyType(), 'description': t.StringType(), 'server': ServerObjectType() }
class HttpSecuritySchemeObjectType( BaseSecuritySchemeObjectType[HttpSecuritySchemeObject], result_class=HttpSecuritySchemeObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'scheme': t.StringType(), 'bearerFormat': t.StringType() } REQUIRED: ty.ClassVar[t.Required] = {'scheme'}
class ServerVariableObjectType(BaseOpenAPIObjectType[ServerVariableObject], result_class=ServerVariableObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'enum': t.ArrayType[str](t.StringType()), 'default': t.StringType(), 'description': t.StringType() } REQUIRED: ty.ClassVar[t.Required] = {'default'}
class ServerObjectType(BaseOpenAPIObjectType[ServerObject], result_class=ServerObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'url': t.StringType(), 'description': t.StringType(), 'variables': t.MapType[ServerVariableObject](ServerVariableObjectType()) } REQUIRED: ty.ClassVar[t.Required] = { 'url' }
class InfoObjectType(BaseOpenAPIObjectType[InfoObject], result_class=InfoObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'title': t.StringType(), 'description': t.StringType(), 'termsOfService': t.URIType(), 'contact': ContactObjectType(), 'license': LicenseObjectType(), 'version': t.StringType() } REQUIRED: ty.ClassVar[t.Required] = {'title', 'version'}
class HeaderParameterObjectType( NamedParameterObjectType[HeaderParameterObject], result_class=HeaderParameterObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { # type: ignore 'in': t.StringType(enum=(PARAMETER_LOCATION.HEADER, )), 'style': t.StringType(enum=(PARAMETER_STYLE.SIMPLE, ), default=PARAMETER_STYLE.SIMPLE) } REQUIRED: ty.ClassVar[t.Required] = {'in'}
class APIKeySecuritySchemeObjectType( BaseSecuritySchemeObjectType[APIKeySecuritySchemeObject], result_class=APIKeySecuritySchemeObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'name': t.StringType(), 'in': t.StringType(enum=(PARAMETER_LOCATION.QUERY, PARAMETER_LOCATION.HEADER, PARAMETER_LOCATION.COOKIE)) } REQUIRED: ty.ClassVar[t.Required] = {'name', 'in'}
class CookieParameterObjectType( NamedParameterObjectType[CookieParameterObject], result_class=CookieParameterObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { # type: ignore 'in': t.StringType(enum=(PARAMETER_LOCATION.COOKIE, )), 'style': t.StringType(enum=(PARAMETER_STYLE.FORM, ), default=PARAMETER_STYLE.FORM) } REQUIRED: ty.ClassVar[t.Required] = {'in'}
class OAuthFlowObjectType(BaseOpenAPIObjectType[OAuthFlowObject], result_class=OAuthFlowObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'authorizationUrl': t.StringType(), 'tokenUrl': t.StringType(), 'refreshUrl': t.StringType(), 'scopes': t.MapType[str](t.StringType()) } REQUIRED: ty.ClassVar[t.Required] = { 'authorizationUrl', 'tokenUrl', 'scopes' }
def _generate_string_type(schema: o.SchemaObject) -> t.StringType: return t.StringType(nullable=schema.nullable, default=schema.default, min_length=schema.min_length, max_length=schema.max_length, enum=schema.enum, pattern=schema.pattern)
class ResponseObjectType(BaseOpenAPIObjectType[ResponseObject], result_class=ResponseObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'description': t.StringType(), 'headers': t.MapType[HeaderObject](t.ReferenceType[HeaderObject]( HeaderObjectType())), 'content': t.MapType[MediaTypeObject](MediaTypeObjectType(), validators=(CONTENT_TYPE_VALIDATOR, )), 'links': t.MapType[LinkObject](t.ReferenceType[LinkObject](LinkObjectType())) } REQUIRED: ty.ClassVar[t.Required] = {'description'} def convert(self, value: ty.Mapping, path: t.Path, *args: ty.Any, **context: ty.Any) -> ty.Optional[ResponseObject]: result: ty.Optional[ResponseObject] = super(ResponseObjectType, self).convert( value, path, **context) if result is None: return None result.path = path return result
class NamedParameterObjectType(BaseParameterObjectType[T_named]): PROPERTIES: ty.ClassVar[t.Properties] = { # type: ignore 'name': t.StringType() } REQUIRED: ty.ClassVar[t.Required] = {'name'}
def _generate_part( self, schema: o.SchemaObject, property_encoding: ty.Optional[o.EncodingObject] = None ) -> PartAdapter: properties: ty.MutableMapping[str, t.AbstractConvertible] = {} allowed_content_types: ty.Optional[ty.Iterable[str]] = None headers = None if property_encoding is not None: allowed_content_types = property_encoding.content_type headers = property_encoding.headers default_content_type = schema.default_content_type if not allowed_content_types and default_content_type is not None: allowed_content_types = (default_content_type, ) properties['contentType'] = t.StringType( pattern=o.CONTENT_TYPE_PATTERN, validators=(AllowedContentTypeValidator(allowed_content_types), ), messages={'pattern': "Invalid content type"}) properties['headers'] = self.headers_factory.generate(headers or {}) properties['content'] = self.type_factory.generate(schema) return PartAdapter(t.ObjectType(properties=properties, required={'headers', 'content'}), default_content_type=default_content_type)
class QueryParameterObjectType(NamedParameterObjectType[QueryParameterObject], result_class=QueryParameterObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { # type: ignore 'in': t.StringType(enum=(PARAMETER_LOCATION.QUERY, )), 'allowEmptyValue': t.BooleanType(default=False), 'style': t.StringType( enum=(PARAMETER_STYLE.FORM, PARAMETER_STYLE.SPACE_DELIMITED, PARAMETER_STYLE.PIPE_DELIMITED, PARAMETER_STYLE.DEEP_OBJECT), default=PARAMETER_STYLE.FORM) } REQUIRED: ty.ClassVar[t.Required] = {'in'}
class ContactObjectType(BaseOpenAPIObjectType[ContactObject], result_class=ContactObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'name': t.StringType(), 'url': t.URIType(), 'email': t.EmailType() }
class OpenIdConnectSecuritySchemeObjectType( BaseSecuritySchemeObjectType[OpenIdConnectSecuritySchemeObject], result_class=OpenIdConnectSecuritySchemeObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'openIdConnectUrl': t.StringType() } REQUIRED: ty.ClassVar[t.Required] = {'openIdConnectUrl'}
class PathParameterObjectType(NamedParameterObjectType[PathParameterObject], result_class=PathParameterObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { # type: ignore 'in': t.StringType(enum=(PARAMETER_LOCATION.PATH, )), 'required': t.BooleanType( enum=[True], messages={'enum': "For path parameter this property must be True"}), 'style': t.StringType(enum=(PARAMETER_STYLE.SIMPLE, PARAMETER_STYLE.LABEL, PARAMETER_STYLE.MATRIX), default=PARAMETER_STYLE.SIMPLE) } REQUIRED: ty.ClassVar[t.Required] = {'in', 'required'}
class LicenseObjectType(BaseOpenAPIObjectType[LicenseObject], result_class=LicenseObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'name': t.StringType(), 'url': t.URIType() } REQUIRED: ty.ClassVar[t.Required] = {'name'}
class ExternalDocumentationObjectType( BaseOpenAPIObjectType[ExternalDocumentationObject], result_class=ExternalDocumentationObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'description': t.StringType(), 'url': t.URIType() } REQUIRED: ty.ClassVar[t.Required] = { 'url' }
class HeaderObjectType(BaseParameterObjectType[HeaderObject], result_class=HeaderObject): __slots__ = () MESSAGES: ty.ClassVar[t.Messages] = { 'deprecated': "Header '{0}' is deprecated" } PROPERTIES: ty.ClassVar[t.Properties] = { 'style': t.StringType(enum=(PARAMETER_STYLE.SIMPLE, ), default=PARAMETER_STYLE.SIMPLE), 'explode': t.BooleanType(default=False) }
class RequestBodyObjectType(BaseOpenAPIObjectType[RequestBodyObject], result_class=RequestBodyObject): __slots__ = () PROPERTIES: ty.ClassVar[t.Properties] = { 'description': t.StringType(), 'content': t.MapType[MediaTypeObject](MediaTypeObjectType(), validators=(CONTENT_TYPE_VALIDATOR,)), 'required': t.BooleanType(default=False) } REQUIRED: ty.ClassVar[t.Required] = { 'content' } def convert(self, value: ty.Any, path: t.Path, *args: ty.Any, **context: ty.Any) -> ty.Optional[RequestBodyObject]: result: ty.Optional[RequestBodyObject] = super(RequestBodyObjectType, self).convert(value, path, **context) if result is None: return None result.path = path return result
class BaseParameterObjectType(BaseOpenAPIObjectType[T_base]): __slots__ = () MESSAGES: ty.ClassVar[t.Messages] = { 'deprecated': "Parameter '{0}' is deprecated", 'mutually_exclusive_schema_content_keywords': "The keywords `schema` and `content` are mutually exclusive" } PROPERTIES: ty.ClassVar[t.Properties] = { 'description': t.StringType(), 'required': t.BooleanType(default=False), 'deprecated': t.BooleanType(default=False), 'style': t.StringType(enum=PARAMETER_STYLE), 'explode': t.BooleanType(), 'allowReserved': t.BooleanType( enum=[False], messages={'enum': "`allowReserved` permanently unsupported"}, default=False), 'schema': t.ReferenceType[SchemaObject](SchemaObjectType()), 'example': t.AnyType(), 'examples': t.MapType[ExampleObject](t.ReferenceType[ExampleObject]( ExampleObjectType())), 'content': t.MapType['MediaTypeObject'](value_type=t.LazyType['MediaTypeObject']( lambda: MediaTypeObjectType()), min_values=1, max_values=1, validators=(CONTENT_TYPE_VALIDATOR, )), 'x-parameterType': t.StringType(enum=PARAMETER_TYPE), } def convert(self, value: ty.Any, path: t.Path, *args: ty.Any, **context: ty.Any) -> ty.Optional[T_base]: result: ty.Optional[T_base] = super(BaseParameterObjectType, self).convert( value, path, **context) if result is None: return result if result.deprecated: warnings.warn(self.messages['deprecated'].format(path), DeprecationWarning) result.path = path return result def validate_mutually_exclusive_schema_content_keywords( self, value: T_base, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if 'schema' in value and 'content' in value: return self.messages['mutually_exclusive_schema_content_keywords'] return None
class SchemaObjectType(BaseOpenAPIObjectType[SchemaObject], result_class=SchemaObject): __slots__ = () MESSAGES: ty.ClassVar[t.Messages] = { 'ambiguous_type': "The schema type is ambiguous", 'deprecated': "The schema '{0}' is deprecated", 'format': "Format is applicable only for primitive types", 'items_required_for_type_array': "`items` must be specified for array type", 'invalid_type_for_minimum': "`minimum` can only be used for number types", 'invalid_type_for_maximum': "`maximum` can only be used for number types", 'must_be_greater_than_minimum': "The value of `maximum` must be greater than or equal to the value of `minimum`", 'exclusive_minimum_required_minimum': "When `exclusiveMinimum` is set, `minimum` is required", 'exclusive_maximum_required_maximum': "When `exclusiveMaximum` is set, `maximum` is required", 'invalid_type_for_multiple_of': "`multipleOf` can only be used for number types", 'invalid_type_for_min_length': "`minLength` can only be used for string types", 'invalid_type_for_max_length': "`maxLength` can only be used for string types", 'must_be_greater_than_min_length': "The value of `maxLength` must be greater than or equal to the `minLength` value", 'invalid_type_for_min_items': "`minItems` can only be used for array types", 'invalid_type_for_max_items': "`maxItems` can only be used for array types", 'must_be_greater_than_min_items': "The value of `maxItems` must be greater than or equal to the value of `minItems`", 'invalid_type_for_unique_items': "`uniqueItems` can only be used for array types", 'invalid_type_for_properties': "`properties` can only be used for object types", 'invalid_type_for_additional_properties': "`additionalProperties` can only be used for object types", 'invalid_type_for_required': "`required` can only be used for object types", 'invalid_type_for_min_properties': "`minProperties` can only be used for object types", 'invalid_type_for_max_properties': "`maxProperties` can only be used for object types", 'must_be_greater_than_min_properties': "The value of `maxProperties` must be greater than or equal to `minProperties`", 'improperly_discriminator_usage': "The `discriminator` can only be used with the keywords `anyOf` or `oneOf`", 'read_only_and_write_only_are_mutually_exclusive': "`readOnly` and `writeOnly` are mutually exclusive and cannot be set simultaneously", 'improperly_x_merge_usage': "The types of all subschemas in `allOf` must be the same when `x-merge` is true", } PROPERTIES: ty.ClassVar[t.Properties] = { 'type': t.StringType(enum=SCHEMA_TYPE), 'format': t.StringType(), 'title': t.StringType(), 'description': t.StringType(), 'default': t.AnyType(), 'nullable': t.BooleanType(default=False), 'enum': t.ArrayType(t.AnyType(), min_items=1, unique_items=True), 'readOnly': t.BooleanType(default=False), 'writeOnly': t.BooleanType(default=False), 'xml': XmlObjectType(), 'externalDocs': ExternalDocumentationObjectType(), 'example': t.AnyType(), 'deprecated': t.BooleanType(default=False), 'multipleOf': t.NumberType(minimum=0, exclusive_minimum=True), 'minimum': t.NumberType(), 'maximum': t.NumberType(), 'exclusiveMinimum': t.BooleanType(default=False), 'exclusiveMaximum': t.BooleanType(default=False), 'minLength': t.IntegerType(minimum=0, default=0), 'maxLength': t.IntegerType(minimum=0), 'pattern': t.RegexType(t.StringType(min_length=1)), 'discriminator': t.LazyType[DiscriminatorObject](lambda: DiscriminatorObjectType()), 'allOf': t.ArrayType[SchemaObject](t.ReferenceType[SchemaObject]( t.LazyType[SchemaObject](lambda: SchemaObjectType())), min_items=1), 'anyOf': t.ArrayType[SchemaObject](ReferenceSaver(t.ReferenceType[SchemaObject]( t.LazyType[SchemaObject](lambda: SchemaObjectType()))), min_items=1), 'oneOf': t.ArrayType[SchemaObject](ReferenceSaver(t.ReferenceType[SchemaObject]( t.LazyType[SchemaObject](lambda: SchemaObjectType()))), min_items=1), 'not': t.ArrayType[SchemaObject](t.ReferenceType[SchemaObject]( t.LazyType[SchemaObject](lambda: SchemaObjectType())), min_items=1), 'items': t.ReferenceType[SchemaObject]( t.LazyType[SchemaObject](lambda: SchemaObjectType())), 'minItems': t.IntegerType(minimum=0, default=0), 'maxItems': t.IntegerType(minimum=0), 'uniqueItems': t.BooleanType(default=False), 'required': t.ArrayType[str](t.StringType(), min_items=1, unique_items=True), 'properties': t.MapType[SchemaObject](t.ReferenceType[SchemaObject]( t.LazyType[SchemaObject](lambda: SchemaObjectType()))), 'minProperties': t.IntegerType(minimum=0, default=0), 'maxProperties': t.IntegerType(minimum=0), 'additionalProperties': t.OneOfType([ t.BooleanType(), t.ReferenceType[SchemaObject]( t.LazyType[SchemaObject](lambda: SchemaObjectType())) ], default=True), 'x-patternProperties': RegexMapType[SchemaObject](t.MapType[SchemaObject]( t.LazyType[SchemaObject](lambda: SchemaObjectType()))), 'x-merge': t.BooleanType(default=False), } 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 def validate_format(self, value: SchemaObject, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if value.format is not None and value.type not in PRIMITIVE_SCHEMA_TYPES: return self.messages['format'] return None def validate_items(self, value: SchemaObject, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if value.type == SCHEMA_TYPE.ARRAY and value.items_ is None: return self.messages['items_required_for_type_array'] return None def validate_discriminator(self, value: SchemaObject, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if value.discriminator is None: return None if value.all_of is not None or value.not_ is not None: return self.messages['improperly_discriminator_usage'] return None def validate_minimum(self, value: SchemaObject, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if value.minimum is None: return None if value.type not in (SCHEMA_TYPE.NUMBER, SCHEMA_TYPE.INTEGER): return self.messages['invalid_type_for_minimum'] return None def validate_maximum(self, value: SchemaObject, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if value.maximum is None: return None if value.type not in (SCHEMA_TYPE.NUMBER, SCHEMA_TYPE.INTEGER): return self.messages['invalid_type_for_maximum'] if value.minimum is not None and value.maximum < value.minimum: return self.messages['must_be_greater_than_minimum'] return None def validate_exclusive_minimum(self, value: SchemaObject, original: ty.Mapping, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if 'exclusiveMinimum' in original and value.minimum is None: return self.messages['exclusive_minimum_required_minimum'] return None def validate_exclusive_maximum(self, value: SchemaObject, original: ty.Mapping, **context: ty.Any) -> t.ValidationResult: if 'exclusiveMaximum' in original and value.maximum is None: return self.messages['exclusive_maximum_required_maximum'] return None def validate_multiple_of(self, value: SchemaObject, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if value.multiple_of is not None and value.type not in ( SCHEMA_TYPE.NUMBER, SCHEMA_TYPE.INTEGER): return self.messages['invalid_type_for_multiple_of'] return None def validate_min_length(self, value: SchemaObject, original: ty.Mapping, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if 'minLength' in original and value.type != SCHEMA_TYPE.STRING: return self.messages['invalid_type_for_min_length'] return None def validate_max_length(self, value: SchemaObject, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if value.max_length is None: return None if value.type != SCHEMA_TYPE.STRING: return self.messages['invalid_type_for_max_length'] if value.max_length < value.min_length: return self.messages['must_be_greater_than_min_length'] return None def validate_min_items(self, value: SchemaObject, original: ty.Mapping, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if 'minItems' in original and value.type != SCHEMA_TYPE.ARRAY: return self.messages['invalid_type_for_min_items'] return None def validate_max_items(self, value: SchemaObject, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if value.max_items is None: return None if value.type != SCHEMA_TYPE.ARRAY: return self.messages['invalid_type_for_max_items'] if value.max_items < value.min_items: return self.messages['must_be_greater_than_min_items'] return None def validate_unique_items(self, value: SchemaObject, original: ty.Mapping, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if 'uniqueItems' in original and value.type != SCHEMA_TYPE.ARRAY: return self.messages['invalid_type_for_unique_items'] return None def validate_properties(self, value: SchemaObject, original: ty.Mapping, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if 'properties' in original and value.type != SCHEMA_TYPE.OBJECT: return self.messages['invalid_type_for_properties'] return None def validate_additional_properties( self, value: SchemaObject, original: ty.Mapping, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if 'additionalProperties' in original and value.type != SCHEMA_TYPE.OBJECT: return self.messages['invalid_type_for_additional_properties'] return None def validate_required(self, value: SchemaObject, original: ty.Mapping, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if 'required' in original and value.type != SCHEMA_TYPE.OBJECT: return self.messages['invalid_type_for_required'] return None def validate_min_properties(self, value: SchemaObject, original: ty.Mapping, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if 'minProperties' in original and value.type != SCHEMA_TYPE.OBJECT: return self.messages['invalid_type_for_min_properties'] return None def validate_max_properties(self, value: SchemaObject, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if value.max_properties is None: return None if value.type != SCHEMA_TYPE.OBJECT: return self.messages['invalid_type_for_max_properties'] if value.max_properties < value.min_properties: return self.messages['must_be_greater_than_min_properties'] return None def validate_read_only_write_only(self, value: SchemaObject, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if value.read_only and value.write_only: return self.messages[ 'read_only_and_write_only_are_mutually_exclusive'] return None def validate_x_merge(self, value: SchemaObject, *args: ty.Any, **context: ty.Any) -> t.ValidationResult: if not value.is_mergeable or value.all_of is None: return None subschema_types = [subschema.type for subschema in value.all_of] if not are_all_items_equal( subschema_types) or subschema_types[0] is None: return self.messages['improperly_x_merge_usage'] return None
class OpenAPIObjectType(BaseOpenAPIObjectType[OpenAPIObject], result_class=OpenAPIObject): __slots__ = () MESSAGES: ty.ClassVar[t.Messages] = { 'undefined_security_scheme': "Undefined security scheme '{0}'" } PROPERTIES: ty.ClassVar[t.Properties] = { 'openapi': t.StringType(pattern=re.compile(r'^3\.0\.[0-2]$'), messages={'pattern': "Unsupported version of OpenAPI"}), 'info': InfoObjectType(), 'servers': t.ArrayType[ServerObject](ServerObjectType()), 'paths': PathsObjectType(), 'components': ComponentsObjectType(), 'security': t.ArrayType[SecurityRequirementObject]( SecurityRequirementObjectType(min_properties=1)), 'tags': t.ArrayType[TagObject](TagObjectType(), unique_items=True, unique_item_properties=['name']), 'externalDocs': ExternalDocumentationObjectType() } REQUIRED: ty.ClassVar[t.Required] = {'openapi', 'info', 'paths'} 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