Esempio n. 1
0
    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
Esempio n. 2
0
    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)
Esempio n. 3
0
class Product(types.Type):
    name = validators.String(max_length=10)
    rating = validators.Integer(allow_null=True,
                                default=None,
                                minimum=0,
                                maximum=100)
    created = validators.DateTime()
Esempio n. 4
0
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
Esempio n. 5
0
from kapi.compat import dict_type
from kapi.exceptions import ParseError

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'))
         ),
Esempio n. 6
0
import pytest

from kapi import validators
from kapi.exceptions import (ErrorMessage, Marker, ParseError, ValidationError)
from kapi.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
Esempio n. 7
0
class User(types.Type):
    name = validators.String(max_length=10)
    age = validators.Integer(minimum=0, allow_null=True, default=None)