class LogGame(types.Type): season: int = validators.Number( 1, 11, description="Overwatch season from 1 to 11.") sr: int = validators.Number( 0, 5000, description="You SR at the end of the game from 0 to 5000.") map: str = validators.String( enum=MAP_CHOICES, allow_null=True, description=f"Name of the map the game was played.", ) heroes: List[str] = validators.Array( items=validators.String(enum=HERO_CHOICES), unique_items=True, allow_null=True, description=f"List of heroes name that you played for that game.", ) comment: str = validators.String( allow_null=True, description="Free text field to leave a comment for that game.") thrower_team: bool = validators.Boolean( allow_null=True, description="If there was a thrower in your team.") thrower_enemy_team: bool = validators.Boolean( allow_null=True, description="If there was a thrower in the enemy team.") leaver_team: bool = validators.Boolean( allow_null=True, description="If there was a leaver on your team.") leaver_enemy_team: bool = validators.Boolean( allow_null=True, description="If there was a leaver on the enemy team.") group_with: List[str] = validators.Array( items=validators.String(), allow_null=True, unique_items=True, description="List of people of you grouped with for this game.", )
def generate_fields(self, url, method, handler): fields = [] path_names = [ item.strip("{}").lstrip("+") for item in re.findall("{[^}]*}", url) ] parameters = inspect.signature(handler).parameters for name, param in parameters.items(): 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"): for ( name, validator, ) in param.annotation.validator.properties.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
class PuppyOutputType(types.Type): id = validators.Number(title="id", description="ID") name = validators.String(title="name", description="Name") number = validators.Integer(title="number", description="Number") time = validators.DateTime(title="time", description="Time") float = validators.Number(title="float", description="Float", allow_null=True) bool = validators.Boolean(title="bool", description="Boolean")
class GameType(types.Type): name = validators.String() platform = validators.String() score = validators.Number() resolution_tested = validators.String(pattern="^\d+x\d+$") genre = validators.Array() players = validators.Array() language = validators.Number() awesome_city = CityType
def generate_fields(self, url, method, handler): fields = [] path_names = [ item.strip('{}').lstrip('+') for item in re.findall('{[^}]*}', url) ] parameters = inspect.signature(handler).parameters for name, param in parameters.items(): 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'): for name, validator in param.annotation.validator.properties.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
class BaseExtractionJSONParams(CoercingType): """Common extraction parameters validator""" domains = validators.Array( items=DomainValidator(enum=list(TAG_DOMAINS.keys())), unique_items=True, description= 'List of domains to search, if not provided ALL domains will be included', allow_null=True, ) offset = validators.Integer(minimum=0, allow_null=True, description='The paging offset') limit = validators.Integer( minimum=1, maximum=10000, default=10, allow_null=True, description='The paging limit.', ) min_score = validators.Number( minimum=0.1, allow_null=True, description= 'The minimum search score required. No default is applied when not provided. ' 'Ignored when `constant_score` is on.', ) constant_score = validators.Boolean( default=True, allow_null=False, description= 'Disables relevance scoring when `True`. All results will have score `1`.', )
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)
class Movie(types.Type): id = validators.Integer(allow_null=True) # assign in POST genre = validators.Array(items=validators.String(enum=list(VALID_GENRES))) director_name = validators.String(max_length=100) year = validators.Integer(minimum=1900, maximum=2050) language = validators.String(max_length=100, enum=list(VALID_LANGUAGES), allow_null=True) title = validators.String(max_length=200) rating = validators.Number(minimum=0, maximum=10)
class PuppyInputType(types.Type): name = validators.String(title="name", description="Name") number = validators.Integer(title="number", description="Number", default=0) time = validators.DateTime(title="time", description="Time") float = validators.Number(title="float", description="Float", allow_null=True) bool = validators.Boolean(title="bool", description="Boolean", default=False)
class GradesBlock(BaseBlock): BLOCK_TYPE = "grades" total_grades_count = validators.Integer() global_grade = validators.Number() url = validators.String(allow_null=True) @classmethod def from_es(cls, es_poi, lang): raw_grades = es_poi.get_raw_grades() or {} total_grades_count = raw_grades.get('total_grades_count', None) global_grade = raw_grades.get('global_grade', None) if total_grades_count is None or global_grade is None: return None return cls(total_grades_count=total_grades_count, global_grade=global_grade, url=es_poi.get_reviews_url() or None)
def test_number_validator_enum_positive(): v = validators.Number(enum=[0.1]) assert v.validate(0.1) == 0.1
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
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")), ),
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
('$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',
class Animal(types.Type): id = validators.Integer(allow_null=True) animal = validators.String(enum=list(VALID_ANIMAL_NAMES)) latitude = validators.Number(minimum=-90.0, maximum=90.) longitude = validators.Number(minimum=-180.0, maximum=180)
def test_number_validator_enum_negative(): v = validators.Number(enum=[0.1]) with pytest.raises(exceptions.ValidationError): v.validate(0.2)
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
class ParticleType(Type): value = validators.Number(allow_null=True) quality_index = validators.Integer(minimum=1, maximum=5, allow_null=True)
class Location(types.Type): latitude = validators.Number(maximum=90.0, minimum=-90.0) longitude = validators.Number(maximum=180.0, minimum=-180.0)
class Prisoner(types.Type): bracelet_ip = validators.String(max_length=100) wanted = validators.Boolean(default=False) username = validators.String(max_length=30) latitude = validators.Number(maximum=90, minimum=-90) longitude = validators.Number(maximum=180, minimum=-180)
enum=['query', 'header', 'path', 'formData', 'body'])), ('description', validators.String(format='textarea')), ('required', validators.Boolean()), # in: "body" ('schema', JSON_SCHEMA | SCHEMA_REF), # in: "query"|"header"|"path"|"formData" ('type', validators.String()), ('format', validators.String()), ('allowEmptyValue', validators.Boolean()), ('items', JSON_SCHEMA), # TODO: Should actually be a restricted subset ('collectionFormat', validators.String( enum=['csv', 'ssv', 'tsv', 'pipes', 'multi'])), ('default', validators.Any()), ('maximum', validators.Number()), ('exclusiveMaximum', validators.Boolean()), ('minimum', validators.Number()), ('exclusiveMinimum', validators.Boolean()), ('maxLength', validators.Integer()), ('minLength', validators.Integer()), ('pattern', validators.String()), ('maxItems', validators.Integer()), ('minItems', validators.Integer()), ('uniqueItems', validators.Boolean()), ('enum', validators.Array(items=validators.Any())), ('multipleOf', validators.Integer()), ], pattern_properties={ '^x-': validators.Any(), },
class Env(types.Type): debug = validators.Boolean(default=True), udp_ip = validators.String(default=os.environ['UDP_IP'] if os. environ['UDP_IP'] else '172.17.10.20') udp_port = validators.Number(default=int(os.environ['UDP_PORT']) if os. environ['UDP_PORT'] else 10001)