class Place(types.Type): type = validators.String() id = validators.String(allow_null=True) name = validators.String(allow_null=True) local_name = validators.String(allow_null=True) class_name = validators.String(allow_null=True) subclass_name = validators.String(allow_null=True) geometry = validators.Object(allow_null=True) address = validators.Object(allow_null=True) blocks = BlocksValidator(allowed_blocks=BLOCKS_BY_VERBOSITY.get(LONG)) meta = PlaceMeta
def __new__(cls, name, bases, attrs): properties = [] for key, value in list(attrs.items()): assert key not in RESERVED_KEYS, RESERVED_KEY_MESSAGE if hasattr(value, 'validate'): attrs.pop(key) properties.append((key, value)) # If this class is subclassing another Type, add that Type's properties. # Note that we loop over the bases in reverse. This is necessary in order # to maintain the correct order of properties. for base in reversed(bases): if hasattr(base, 'validator'): properties = [(key, base.validator.properties[key]) for key in base.validator.properties if key not in attrs] + properties properties = sorted(properties, key=lambda item: item[1]._creation_counter) required = [ key for key, value in properties if not value.has_default() ] attrs['validator'] = validators.Object(def_name=name, properties=properties, required=required, additional_properties=None) attrs['_creation_counter'] = validators.Validator._creation_counter validators.Validator._creation_counter += 1 return super(TypeMetaclass, cls).__new__(cls, name, bases, attrs)
def __new__(cls, name, bases, attrs): properties = [] for key, value in list(attrs.items()): if key in ['keys', 'items', 'values', 'get', 'validator']: msg = ('Cannot use reserved name "%s" on Type "%s", as it ' 'clashes with the class interface.') raise ConfigurationError(msg % (key, name)) elif hasattr(value, 'validate'): attrs.pop(key) properties.append((key, value)) # If this class is subclassing another Type, add that Type's properties. # Note that we loop over the bases in reverse. This is necessary in order # to maintain the correct order of properties. for base in reversed(bases): if hasattr(base, 'validator'): properties = [(key, base.validator.properties[key]) for key in base.validator.properties if key not in attrs] + properties properties = sorted(properties, key=lambda item: item[1]._creation_counter) required = [ key for key, value in properties if not value.has_default() ] attrs['validator'] = validators.Object(def_name=name, properties=properties, required=required, additional_properties=None) attrs['_creation_counter'] = validators.Validator._creation_counter validators.Validator._creation_counter += 1 return super(TypeMetaclass, cls).__new__(cls, name, bases, attrs)
def resolve(self, parameter: inspect.Parameter, path_params: ValidatedPathParams, query_params: ValidatedQueryParams): params = path_params if (parameter.name in path_params) else query_params has_default = parameter.default is not parameter.empty allow_null = parameter.default is None param_validator = { parameter.empty: validators.Any(), str: validators.String(allow_null=allow_null), int: validators.Integer(allow_null=allow_null), float: validators.Number(allow_null=allow_null), bool: validators.Boolean(allow_null=allow_null) }[parameter.annotation] validator = validators.Object( properties=[(parameter.name, param_validator)], required=[] if has_default else [parameter.name]) try: params = validator.validate(params, allow_coerce=True) except validators.ValidationError as exc: raise exceptions.NotFound(exc.detail) return params.get(parameter.name, parameter.default)
def get_link(self, base_url, path, path_info, operation, operation_info, schema_definitions): """ Return a single link in the document. """ name = operation_info.get('operationId') title = operation_info.get('summary') description = operation_info.get('description') if name is None: name = _simple_slugify(title) if not name: return None # Parameters are taken both from the path info, and from the operation. parameters = path_info.get('parameters', []) parameters += operation_info.get('parameters', []) fields = [ self.get_field(parameter, schema_definitions) for parameter in parameters ] default_encoding = None if any([field.location == 'body' for field in fields]): default_encoding = 'application/json' elif any([field.location == 'formData' for field in fields]): default_encoding = 'application/x-www-form-urlencoded' form_fields = [ field for field in fields if field.location == 'formData' ] body_field = Field( name='body', location='body', schema=validators.Object(properties={ field.name: validators.Any() if field.schema is None else field.schema for field in form_fields }, required=[ field.name for field in form_fields if field.required ])) fields = [ field for field in fields if field.location != 'formData' ] fields.append(body_field) encoding = lookup(operation_info, ['consumes', 0], default_encoding) return Link(name=name, url=urljoin(base_url, path), method=operation, title=title, description=description, fields=fields, encoding=encoding)
class Anime(types.Type): id = validators.Integer(allow_null=True) title = validators.String(max_length=2500) year = validators.Integer(minimum=1900, maximum=2050) episodes = validators.Integer(maximum=9999) status = validators.String(enum=list(ANIME_VALID_STATUS)) type = validators.String(allow_null=True) animeSeason = validators.Object(allow_null=True) picture = validators.String(allow_null=True) sources = validators.Array(allow_null=True)
def resolve(self, route: Route, path_params: http.PathParams) -> ValidatedPathParams: path_fields = route.link.get_path_fields() validator = validators.Object( properties=[(field.name, field.schema if field.schema else validators.Any()) for field in path_fields], required=[field.name for field in path_fields]) try: path_params = validator.validate(path_params, allow_coerce=True) except validators.ValidationError as exc: raise exceptions.NotFound(exc.detail) return ValidatedPathParams(path_params)
def resolve(self, route: Route, query_params: http.QueryParams) -> ValidatedQueryParams: query_fields = route.link.get_query_fields() validator = validators.Object( properties=[(field.name, field.schema if field.schema else validators.Any()) for field in query_fields], required=[field.name for field in query_fields if field.required]) try: query_params = validator.validate(query_params, allow_coerce=True) except validators.ValidationError as exc: raise exceptions.BadRequest(exc.detail) return ValidatedQueryParams(query_params)
def __init__(self, properties: Dict[str, validators.Validator], defaults: dict = None) -> None: required = [] settings = defaults or {} for name, prop in properties.items(): value = os.getenv(name) if value is not None: settings[name] = value if not prop.has_default(): required.append(name) validator = validators.Object(properties, required=required) self.settings = Settings( validator.validate(settings, allow_coerce=True))
def request(self, name: str, **params): link = self.lookup_link(name) validator = validators.Object( properties={field.name: validators.Any() for field in link.fields}, required=[field.name for field in link.fields if field.required], additional_properties=False) validator.validate(params) method = link.method url = self.get_url(link, params) query_params = self.get_query_params(link, params) (content, encoding) = self.get_content_and_encoding(link, params) return self.transport.send(method, url, query_params=query_params, content=content, encoding=encoding)
def __new__(cls, name, bases, attrs): properties = [] for key, value in list(attrs.items()): if key in ['keys', 'items', 'values', 'get', 'validator']: msg = ('Cannot use reserved name "%s" on Type "%s", as it ' 'clashes with the class interface.') raise ConfigurationError(msg % (key, name)) elif isinstance(value, validators.Validator): attrs.pop(key) properties.append((key, value)) properties = sorted(properties, key=lambda item: item[1]._creation_counter) required = [ key for key, value in properties if not value.has_default() ] attrs['validator'] = validators.Object(def_name=name, properties=properties, required=required, additional_properties=None) return super(TypeMetaclass, cls).__new__(cls, name, bases, attrs)
def request(self, operation_id: str, **params): link = self.lookup_operation(operation_id) validator = validators.Object( properties={field.name: validators.Any() for field in link.fields}, required=[field.name for field in link.fields if field.required], additional_properties=False) try: validator.validate(params) except exceptions.ValidationError as exc: raise exceptions.ClientError(messages=exc.messages) from None method = link.method url = self.get_url(link, params) query_params = self.get_query_params(link, params) (content, encoding) = self.get_content_and_encoding(link, params) return self.transport.send(method, url, query_params=query_params, content=content, encoding=encoding)
class Place(types.Type): PLACE_TYPE = '' type = validators.String() id = validators.String(allow_null=True) name = validators.String(allow_null=True) local_name = validators.String(allow_null=True) class_name = validators.String(allow_null=True) subclass_name = validators.String(allow_null=True) geometry = validators.Object(allow_null=True) address = validators.Object(allow_null=True) blocks = BlocksValidator(allowed_blocks=BLOCKS_BY_VERBOSITY.get(LONG)) def __init__(self, *args, **kwargs): if not args: if not self.PLACE_TYPE: raise Exception('Missing PLACE_TYPE in class %s', self.__class__.__name__) kwargs['type'] = self.PLACE_TYPE super().__init__(*args, **kwargs) @classmethod def load_place(cls, es_place, lang, settings, verbosity): raise NotImplementedError @classmethod def build_admins(cls, raw_admins): admins = [] if not raw_admins is None: for raw_admin in raw_admins: admin = { "id": raw_admin.get("id"), "label": raw_admin.get("label"), "name": raw_admin.get("name"), "class_name": raw_admin.get("zone_type"), "postcodes": raw_admin.get("zip_codes") } admins.append(admin) return admins @classmethod def build_street(cls, raw_street): return { "id": raw_street.get("id"), "name": raw_street.get("name"), "label": raw_street.get("label"), "postcodes": raw_street.get("zip_codes") } @staticmethod def get_raw_address(es_place): return es_place.get("address") or {} @classmethod def get_raw_street(cls, es_place): raw_address = cls.get_raw_address(es_place) if raw_address.get('type') == 'street': return raw_address return raw_address.get("street") or {} @classmethod def get_raw_admins(cls, es_place): return es_place.get("administrative_regions") or [] @staticmethod def build_admin(es_place): return None @classmethod def get_postcodes(cls, es_place): return cls.get_raw_address(es_place).get("zip_codes") @classmethod def build_address(cls, es_place): """ Method to build the address field for an Address, a Street, an Admin or a POI. """ raw_address = cls.get_raw_address(es_place) raw_street = cls.get_raw_street(es_place) raw_admins = cls.get_raw_admins(es_place) postcodes = cls.get_postcodes(es_place) if postcodes is not None: if isinstance(postcodes, list): postcodes = ';'.join(postcodes) id = raw_address.get("id") name = raw_address.get("name") housenumber = raw_address.get("house_number") label = raw_address.get("label") admins = cls.build_admins(raw_admins) street = cls.build_street(raw_street) return { "id": id, "name": name, "housenumber": housenumber, "postcode": postcodes, "label": label, "admin": cls.build_admin(es_place), "street": street, "admins": admins }
def generate_fields(self, url, method, handler): if not self.documented: return [] fields = [] for name, param in signature(handler).parameters.items(): if issubclass(param.annotation, _PathParam): if issubclass(param.annotation, int): validator_cls = validators.Integer elif issubclass(param.annotation, float): validator_cls = validators.Number elif issubclass(param.annotation, str): validator_cls = validators.String else: raise exceptions.ConfigurationError( f"Cannot handle {name} of {handler}") location = 'path' schema = validator_cls() field = Field(name=name, location=location, schema=schema) fields.append(field) elif issubclass(param.annotation, _QueryParam): if param.default is param.empty: kwargs = {} elif param.default is None: # TODO handle Optional kwargs = {'default': None, 'allow_null': True} else: kwargs = {'default': param.default} if issubclass(param.annotation, int): validator_cls = validators.Integer elif issubclass(param.annotation, float): validator_cls = validators.Number elif issubclass(param.annotation, str): validator_cls = validators.String elif getattr(param.annotation, '__bool__', None): validator_cls = validators.Boolean else: raise exceptions.ConfigurationError( f"Cannot handle {name} of {handler}") location = 'query' schema = validator_cls(**kwargs) field = Field(name=name, location=location, schema=schema) fields.append(field) elif issubclass(param.annotation, _BodyData): location = 'body' schema = validators.Object() field = Field(name=name, location=location, schema=schema) fields.append(field) elif issubclass(param.annotation, ParamData): raise exceptions.ConfigurationError( f"{param.annotation} do not support documentation.") else: # fallback to original generate_fields() method path_names = [ item.strip('{}').lstrip('+') for item in re.findall('{[^}]*}', url) ] if name in path_names: schema = { param.empty: None, int: validators.Integer(), float: validators.Number(), str: validators.String() }[param.annotation] field = Field(name=name, location='path', schema=schema) fields.append(field) elif param.annotation in (param.empty, int, float, bool, str, http.QueryParam): if param.default is param.empty: kwargs = {} elif param.default is None: kwargs = {'default': None, 'allow_null': True} else: kwargs = {'default': param.default} schema = { param.empty: None, int: validators.Integer(**kwargs), float: validators.Number(**kwargs), bool: validators.Boolean(**kwargs), str: validators.String(**kwargs), http.QueryParam: validators.String(**kwargs), }[param.annotation] field = Field(name=name, location='query', schema=schema) fields.append(field) elif issubclass(param.annotation, types.Type): if method in ('GET', 'DELETE'): items = param.annotation.validator.properties.items() for name, validator in items: field = Field(name=name, location='query', schema=validator) fields.append(field) else: field = Field(name=name, location='body', schema=param.annotation.validator) fields.append(field) return fields
from apistar.parse import parse_yaml APISTAR_CONFIG = validators.Object( properties=[ ( "schema", validators.Object( properties=[ ("path", validators.String()), ("format", validators.String(enum=["openapi", "swagger"])), ], additional_properties=False, required=["path", "format"], ), ), ( "docs", validators.Object( properties=[ ("theme", validators.String(enum=["apistar", "redoc", "swaggerui"])) ], additional_properties=False, ), ), ], additional_properties=False, required=["schema"], )
class Metadata(types.Type): resources = validators.Object(title="resources", description="Resource list") admin = validators.String(title="admin", description="Admin URL") schema = validators.String(title="schema", description="OpenAPI schema URL")
from apistar import types, validators SETTINGS_VALIDATOR = validators.Object( properties={ "enforce_https": validators.Boolean(default=False), "mode": validators.String(default="proxy", enum=["proxy", "redirect"]), }, default={"enforce_https": False, "mode": "proxy"}, ) class RouteWithoutSource(types.Type): target = validators.String() settings = SETTINGS_VALIDATOR class Route(types.Type): source = validators.String() target = validators.String() settings = SETTINGS_VALIDATOR
import pytest from apistar import validators from apistar.exceptions import (ErrorMessage, Marker, ParseError, ValidationError) from apistar.parse import parse_json VALIDATOR = validators.Object(properties={'a': validators.Integer()}, required=['a'], additional_properties=False) def test_empty_string(): with pytest.raises(ParseError) as exc: parse_json(b'', VALIDATOR) error_messages = exc.value.get_error_messages() expecting = [ErrorMessage('No content.', Marker(0))] assert error_messages == expecting def test_object_missing_property_name(): with pytest.raises(ParseError) as exc: parse_json('{', VALIDATOR) error_messages = exc.value.get_error_messages() expecting = [ ErrorMessage('Expecting property name enclosed in double quotes.', Marker(1)) ] assert error_messages == expecting
import json import re from urllib.parse import urljoin, urlparse from apistar import validators from apistar.codecs import BaseCodec, JSONSchemaCodec from apistar.codecs.jsonschema import JSON_SCHEMA from apistar.compat import dict_type from apistar.document import Document, Field, Link, Section from apistar.parse import infer_json_or_yaml, parse_json, parse_yaml SCHEMA_REF = validators.Object( properties={"$ref": validators.String(pattern="^#/components/schemas/")}) REQUESTBODY_REF = validators.Object( properties={ "$ref": validators.String(pattern="^#/components/requestBodies/") }) RESPONSE_REF = validators.Object( properties={"$ref": validators.String(pattern="^#/components/responses/")}) OPEN_API = validators.Object( def_name="OpenAPI", title="OpenAPI", properties=[ ("openapi", validators.String()), ("info", validators.Ref("Info")), ("servers", validators.Array(items=validators.Ref("Server"))), ("paths", validators.Ref("Paths")), ("components", validators.Ref("Components")), ("security", validators.Array(items=validators.Ref("SecurityRequirement"))),
schema=validators.Integer(minimum=0, maximum=1000)) ]), # Body parameters Link(url='/type_body_param/', method='POST', handler=type_body_param), Link(url='/schema_enforced_body_param/', method='POST', name='schema_enforced_body_param', encoding='application/json', fields=[ Field(name='param', location='body', schema=validators.Object( properties={ 'name': validators.String(max_length=10), 'age': validators.Integer( minimum=0, allow_null=True, default=None), })) ]), ]) routes = bind( document, { 'str_path_param': str_path_param, 'int_path_param': int_path_param, 'schema_enforced_str_path_param': schema_enforced_str_path_param, 'schema_enforced_int_path_param': schema_enforced_int_path_param, 'str_query_param': str_query_param, 'int_query_param': int_query_param, 'str_query_param_with_default': str_query_param_with_default,
import json import re from urllib.parse import urljoin, urlparse from apistar import validators from apistar.codecs import BaseCodec, JSONSchemaCodec from apistar.codecs.jsonschema import JSON_SCHEMA from apistar.compat import dict_type from apistar.document import Document, Field, Link, Section from apistar.exceptions import ParseError SCHEMA_REF = validators.Object( properties={'$ref': validators.String(pattern='^#/components/schemas/')} ) OPEN_API = validators.Object( def_name='OpenAPI', title='OpenAPI', properties=[ ('openapi', validators.String()), ('info', validators.Ref('Info')), ('servers', validators.Array(items=validators.Ref('Server'))), ('paths', validators.Ref('Paths')), ('components', validators.Ref('Components')), ('security', validators.Ref('SecurityRequirement')), ('tags', validators.Array(items=validators.Ref('Tag'))), ('externalDocs', validators.Ref('ExternalDocumentation')), ], pattern_properties={ '^x-': validators.Any(),
import re from urllib.parse import urljoin from apistar import validators from apistar.compat import dict_type from apistar.document import Document, Field, Link, Section from apistar.schemas.jsonschema import JSON_SCHEMA, JSONSchema SCHEMA_REF = validators.Object( properties={'$ref': validators.String(pattern='^#/definitiions/')}) RESPONSE_REF = validators.Object( properties={'$ref': validators.String(pattern='^#/responses/')}) SWAGGER = validators.Object( def_name='Swagger', title='Swagger', properties=[ ('swagger', validators.String()), ('info', validators.Ref('Info')), ('paths', validators.Ref('Paths')), ('host', validators.String()), ('basePath', validators.String()), ('schemes', validators.Array(items=validators.String())), ('consumes', validators.Array(items=validators.String())), ('produces', validators.Array(items=validators.String())), ('definitions', validators.Object(additional_properties=validators.Any())), ('parameters', validators.Object( additional_properties=validators.Ref('Parameters'))), ('responses',
from apistar import types, validators SETTINGS_VALIDATOR = validators.Object( properties={ 'enforce_https': validators.Boolean(default=False), 'mode': validators.String( default='proxy', enum=['proxy', 'redirect'], ), }, default={ 'enforce_https': False, 'mode': 'proxy', }, ) class RouteWithoutSource(types.Type): target = validators.String() settings = SETTINGS_VALIDATOR class Route(types.Type): source = validators.String() target = validators.String() settings = SETTINGS_VALIDATOR
JSON_SCHEMA = validators.Object( def_name='JSONSchema', properties=[ ('$ref', validators.String()), ('type', validators.String() | validators.Array(items=validators.String())), ('enum', validators.Array(unique_items=True, min_items=1)), ('definitions', validators.Object( additional_properties=validators.Ref('JSONSchema'))), # String ('minLength', validators.Integer(minimum=0)), ('maxLength', validators.Integer(minimum=0)), ('pattern', validators.String(format='regex')), ('format', validators.String()), # Numeric ('minimum', validators.Number()), ('maximum', validators.Number()), ('exclusiveMinimum', validators.Boolean()), ('exclusiveMaximum', validators.Boolean()), ('multipleOf', validators.Number(minimum=0.0, exclusive_minimum=True)), # Object ('properties', validators.Object(additional_properties=validators.Ref('JSONSchema')) ), ('minProperties', validators.Integer(minimum=0)), ('maxProperties', validators.Integer(minimum=0)), ('patternProperties', validators.Object( additional_properties=validators.Ref('JSONSchema'))), ('additionalProperties', validators.Ref('JSONSchema') | validators.Boolean()), ('required', validators.Array(items=validators.String(), min_items=1, unique_items=True)), # Array ('items', validators.Ref('JSONSchema') | validators.Array(items=validators.Ref('JSONSchema'), min_items=1)), ('additionalItems', validators.Ref('JSONSchema') | validators.Boolean()), ('minItems', validators.Integer(minimum=0)), ('maxItems', validators.Integer(minimum=0)), ('uniqueItems', validators.Boolean()), ], )
from apistar import validators from apistar.codecs import BaseCodec from apistar.parse import parse_yaml APISTAR_CONFIG = validators.Object( properties=[ ('schema', validators.Object(properties=[ ('path', validators.String()), ('format', validators.String(enum=['openapi', 'swagger'])), ], additional_properties=False, required=['path', 'format'])), ('docs', validators.Object( properties=[ ('theme', validators.String(enum=['apistar', 'redoc', 'swaggerui'])), ], additional_properties=False, )) ], additional_properties=False, required=['schema'], ) class ConfigCodec(BaseCodec): media_type = 'application/x-yaml' format = 'apistar'
def load_type(typename, struct, allow_null): attrs = {'allow_null': True} if allow_null else {} if typename == 'string': if 'minLength' in struct: attrs['min_length'] = struct['minLength'] if 'maxLength' in struct: attrs['max_length'] = struct['maxLength'] if 'pattern' in struct: attrs['pattern'] = struct['pattern'] if 'format' in struct: attrs['format'] = struct['format'] return validators.String(**attrs) if typename in ['number', 'integer']: if 'minimum' in struct: attrs['minimum'] = struct['minimum'] if 'maximum' in struct: attrs['maximum'] = struct['maximum'] if 'exclusiveMinimum' in struct: attrs['exclusive_minimum'] = struct['exclusiveMinimum'] if 'exclusiveMaximum' in struct: attrs['exclusive_maximum'] = struct['exclusiveMaximum'] if 'multipleOf' in struct: attrs['multiple_of'] = struct['multipleOf'] if 'format' in struct: attrs['format'] = struct['format'] if typename == 'integer': return validators.Integer(**attrs) return validators.Number(**attrs) if typename == 'boolean': return validators.Boolean(**attrs) if typename == 'object': if 'properties' in struct: attrs['properties'] = dict_type([ (key, decode(value)) for key, value in struct['properties'].items() ]) if 'required' in struct: attrs['required'] = struct['required'] if 'minProperties' in struct: attrs['min_properties'] = struct['minProperties'] if 'maxProperties' in struct: attrs['max_properties'] = struct['maxProperties'] if 'required' in struct: attrs['required'] = struct['required'] if 'patternProperties' in struct: attrs['pattern_properties'] = dict_type([ (key, decode(value)) for key, value in struct['patternProperties'].items() ]) if 'additionalProperties' in struct: if isinstance(struct['additionalProperties'], bool): attrs['additional_properties'] = struct['additionalProperties'] else: attrs['additional_properties'] = decode( struct['additionalProperties']) return validators.Object(**attrs) if typename == 'array': if 'items' in struct: if isinstance(struct['items'], list): attrs['items'] = [decode(item) for item in struct['items']] else: attrs['items'] = decode(struct['items']) if 'additionalItems' in struct: if isinstance(struct['additionalItems'], bool): attrs['additional_items'] = struct['additionalItems'] else: attrs['additional_items'] = decode(struct['additionalItems']) if 'minItems' in struct: attrs['min_items'] = struct['minItems'] if 'maxItems' in struct: attrs['max_items'] = struct['maxItems'] if 'uniqueItems' in struct: attrs['unique_items'] = struct['uniqueItems'] return validators.Array(**attrs) assert False
import yaml from apistar import validators from apistar.codecs import BaseCodec from apistar.exceptions import ParseError CONFIG = validators.Object( properties=[ ('schema', validators.Object(properties=[ ('path', validators.String()), ('format', validators.String()), ], additional_properties=False, required=['path', 'format'])), ], additional_properties=False, required=['schema'], ) class ConfigCodec(BaseCodec): media_type = 'application/x-yaml' format = 'apistar' def decode(self, bytestring, **options): content = bytestring.decode('utf-8') content = content.strip() if not content: raise ParseError(message='No content.', short_message='No content.',
JSON_SCHEMA = validators.Object( def_name="JSONSchema", properties=[ ("$ref", validators.String()), ("type", validators.String() | validators.Array(items=validators.String())), ("enum", validators.Array(unique_items=True, min_items=1)), ( "definitions", validators.Object(additional_properties=validators.Ref("JSONSchema")), ), # String ("minLength", validators.Integer(minimum=0)), ("maxLength", validators.Integer(minimum=0)), ("pattern", validators.String(format="regex")), ("format", validators.String()), # Numeric ("minimum", validators.Number()), ("maximum", validators.Number()), ("exclusiveMinimum", validators.Boolean()), ("exclusiveMaximum", validators.Boolean()), ("multipleOf", validators.Number(minimum=0.0, exclusive_minimum=True)), # Object ( "properties", validators.Object(additional_properties=validators.Ref("JSONSchema")), ), ("minProperties", validators.Integer(minimum=0)), ("maxProperties", validators.Integer(minimum=0)), ( "patternProperties", validators.Object(additional_properties=validators.Ref("JSONSchema")), ), ("additionalProperties", validators.Ref("JSONSchema") | validators.Boolean()), ( "required", validators.Array(items=validators.String(), min_items=1, unique_items=True), ), # Array ( "items", validators.Ref("JSONSchema") | validators.Array(items=validators.Ref("JSONSchema"), min_items=1), ), ("additionalItems", validators.Ref("JSONSchema") | validators.Boolean()), ("minItems", validators.Integer(minimum=0)), ("maxItems", validators.Integer(minimum=0)), ("uniqueItems", validators.Boolean()), ], )
import json import re from urllib.parse import urljoin, urlparse import yaml from apistar import validators from apistar.codecs import BaseCodec, JSONSchemaCodec from apistar.codecs.jsonschema import JSON_SCHEMA from apistar.compat import dict_type from apistar.document import Document, Field, Link, Section from apistar.exceptions import ParseError SCHEMA_REF = validators.Object( properties={'$ref': validators.String(pattern='^#/components/schemas/')}) RESPONSE_REF = validators.Object( properties={'$ref': validators.String(pattern='^#/components/responses/')}) SWAGGER = validators.Object( def_name='Swagger', title='Swagger', properties=[ ('swagger', validators.String()), ('info', validators.Ref('Info')), ('paths', validators.Ref('Paths')), ('host', validators.String()), ('basePath', validators.String()), ('schemes', validators.Array(items=validators.String())), ('consumes', validators.Array(items=validators.String())), ('produces', validators.Array(items=validators.String())), ('definitions',
def load_type(typename, struct, allow_null): attrs = {"allow_null": True} if allow_null else {} if typename == "string": if "minLength" in struct: attrs["min_length"] = struct["minLength"] if "maxLength" in struct: attrs["max_length"] = struct["maxLength"] if "pattern" in struct: attrs["pattern"] = struct["pattern"] if "format" in struct: attrs["format"] = struct["format"] return validators.String(**attrs) if typename in ["number", "integer"]: if "minimum" in struct: attrs["minimum"] = struct["minimum"] if "maximum" in struct: attrs["maximum"] = struct["maximum"] if "exclusiveMinimum" in struct: attrs["exclusive_minimum"] = struct["exclusiveMinimum"] if "exclusiveMaximum" in struct: attrs["exclusive_maximum"] = struct["exclusiveMaximum"] if "multipleOf" in struct: attrs["multiple_of"] = struct["multipleOf"] if "format" in struct: attrs["format"] = struct["format"] if typename == "integer": return validators.Integer(**attrs) return validators.Number(**attrs) if typename == "boolean": return validators.Boolean(**attrs) if typename == "object": if "properties" in struct: attrs["properties"] = dict_type( [(key, decode(value)) for key, value in struct["properties"].items()] ) if "required" in struct: attrs["required"] = struct["required"] if "minProperties" in struct: attrs["min_properties"] = struct["minProperties"] if "maxProperties" in struct: attrs["max_properties"] = struct["maxProperties"] if "required" in struct: attrs["required"] = struct["required"] if "patternProperties" in struct: attrs["pattern_properties"] = dict_type( [ (key, decode(value)) for key, value in struct["patternProperties"].items() ] ) if "additionalProperties" in struct: if isinstance(struct["additionalProperties"], bool): attrs["additional_properties"] = struct["additionalProperties"] else: attrs["additional_properties"] = decode(struct["additionalProperties"]) return validators.Object(**attrs) if typename == "array": if "items" in struct: if isinstance(struct["items"], list): attrs["items"] = [decode(item) for item in struct["items"]] else: attrs["items"] = decode(struct["items"]) if "additionalItems" in struct: if isinstance(struct["additionalItems"], bool): attrs["additional_items"] = struct["additionalItems"] else: attrs["additional_items"] = decode(struct["additionalItems"]) if "minItems" in struct: attrs["min_items"] = struct["minItems"] if "maxItems" in struct: attrs["max_items"] = struct["maxItems"] if "uniqueItems" in struct: attrs["unique_items"] = struct["uniqueItems"] return validators.Array(**attrs) assert False