Exemplo n.º 1
0
def test_argmap2schema_doesnt_add_to_class_registry():
    old_n_entries = len(
        list(itertools.chain([classes for _, classes in class_registry._registry.items()]))
    )
    argmap = {'id': fields.Field()}
    argmap2schema(argmap)
    argmap2schema(argmap)
    new_n_entries = len(
        list(itertools.chain([classes for _, classes in class_registry._registry.items()]))
    )
    assert new_n_entries == old_n_entries
Exemplo n.º 2
0
class ServerInfoApi(Resource):
    @doc(description="Return FreeDiscovery server information "
         " (versions, etc).")
    @marshal_with(
        argmap2schema({
            'version':
            wfields.Nested({'number': wfields.Str()}),
            'env':
            wfields.Nested({'python_version': wfields.Str()}),
            'config':
            wfields.Nested({
                'cache_dir': wfields.Str(),
                'debug': wfields.Boolean(),
                'hostname': wfields.Str(),
                'log_file': wfields.Str(),
                'n_workers': wfields.Int(),
                'port': wfields.Int(),
                'server': wfields.Str()
            })
        }))
    def get(self):
        out = {'version': {}, 'env': {}}

        out['version']['number'] = __version__
        out['env']['python_version'] = sys.version
        out['config'] = self._fd_config
        return out
Exemplo n.º 3
0
def test_delimited_list_custom_delimiter(web_request, parser):
    web_request.json = {'ids': '1|2|3'}
    schema_cls = argmap2schema({'ids': fields.DelimitedList(fields.Int(), delimiter='|')})
    schema = schema_cls()

    parsed = parser.parse(schema, web_request)
    assert parsed['ids'] == [1, 2, 3]
Exemplo n.º 4
0
def test_delimited_list_load_list(web_request, parser):
    web_request.json = {'ids': [1, 2, 3]}
    schema_cls = argmap2schema({'ids': fields.DelimitedList(fields.Int())})
    schema = schema_cls()

    parsed = parser.parse(schema, web_request)
    assert parsed['ids'] == [1, 2, 3]
Exemplo n.º 5
0
def test_argmap2schema_with_nesting():
    argmap = {"nest": fields.Nested({"foo": fields.Field()})}
    schema_cls = argmap2schema(argmap)
    assert issubclass(schema_cls, Schema)
    schema = schema_cls()
    assert "nest" in schema.fields
    assert type(schema.fields["nest"]) is fields.Nested
    assert "foo" in schema.fields["nest"].schema.fields
Exemplo n.º 6
0
def test_delimited_list_passed_invalid_type(web_request, parser):
    web_request.json = {'ids': 1}
    schema_cls = argmap2schema({'ids': fields.DelimitedList(fields.Int())})
    schema = schema_cls()

    with pytest.raises(ValidationError) as excinfo:
        parser.parse(schema, web_request)
    assert excinfo.value.messages == {'ids': ['Not a valid list.']}
Exemplo n.º 7
0
def test_delimited_list_custom_delimiter(web_request, parser):
    web_request.json = {"ids": "1|2|3"}
    schema_cls = argmap2schema(
        {"ids": fields.DelimitedList(fields.Int(), delimiter="|")})
    schema = schema_cls()

    parsed = parser.parse(schema, web_request)
    assert parsed["ids"] == [1, 2, 3]
Exemplo n.º 8
0
def test_argmap2schema_with_nesting():
    argmap = {'nest': fields.Nested({'foo': fields.Field()})}
    schema_cls = argmap2schema(argmap)
    assert issubclass(schema_cls, Schema)
    schema = schema_cls()
    assert 'nest' in schema.fields
    assert type(schema.fields['nest']) is fields.Nested
    assert 'foo' in schema.fields['nest'].schema.fields
Exemplo n.º 9
0
def test_delimited_list_as_string(web_request, parser):
    web_request.json = {'ids': '1,2,3'}
    schema_cls = argmap2schema({'ids': fields.DelimitedList(fields.Int(), as_string=True)})
    schema = schema_cls()

    parsed = parser.parse(schema, web_request)
    assert parsed['ids'] == [1, 2, 3]

    dumped = schema.dump(parsed).data
    assert dumped['ids'] == '1,2,3'
Exemplo n.º 10
0
def test_delimited_list_default_delimiter(web_request, parser):
    web_request.json = {'ids': '1,2,3'}
    schema_cls = argmap2schema({'ids': fields.DelimitedList(fields.Int())})
    schema = schema_cls()

    parsed = parser.parse(schema, web_request)
    assert parsed['ids'] == [1, 2, 3]

    dumped = schema.dump(parsed)
    data = dumped.data if MARSHMALLOW_VERSION_INFO[0] < 3 else dumped
    assert data['ids'] == [1, 2, 3]
Exemplo n.º 11
0
    def use_args(
        self,
        argmap,
        req=None,
        locations=core.Parser.DEFAULT_LOCATIONS,
        as_kwargs=False,
        validate=None,
    ):
        """Decorator that injects parsed arguments into a view callable.
        Supports the *Class-based View* pattern where `request` is saved as an instance
        attribute on a view class.

        :param dict argmap: Either a `marshmallow.Schema`, a `dict`
            of argname -> `marshmallow.fields.Field` pairs, or a callable
            which accepts a request and returns a `marshmallow.Schema`.
        :param req: The request object to parse. Pulled off of the view by default.
        :param tuple locations: Where on the request to search for values.
        :param bool as_kwargs: Whether to insert arguments as keyword arguments.
        :param callable validate: Validation function that receives the dictionary
            of parsed arguments. If the function returns ``False``, the parser
            will raise a :exc:`ValidationError`.
        """
        locations = locations or self.locations
        # Optimization: If argmap is passed as a dictionary, we only need
        # to generate a Schema once
        if isinstance(argmap, collections.Mapping):
            argmap = core.argmap2schema(argmap)()

        def decorator(func):
            @functools.wraps(func)
            def wrapper(obj, *args, **kwargs):
                # The first argument is either `self` or `request`
                try:  # get self.request
                    request = req or obj.request
                except AttributeError:  # first arg is request
                    request = obj
                # NOTE: At this point, argmap may be a Schema, callable, or dict
                parsed_args = self.parse(
                    argmap,
                    req=request,
                    locations=locations,
                    validate=validate,
                    force_all=as_kwargs,
                )
                if as_kwargs:
                    kwargs.update(parsed_args)
                    return func(obj, *args, **kwargs)
                else:
                    return func(obj, parsed_args, *args, **kwargs)

            wrapper.__wrapped__ = func
            return wrapper

        return decorator
Exemplo n.º 12
0
def test_delimited_list_as_string(web_request, parser):
    web_request.json = {"ids": "1,2,3"}
    schema_cls = argmap2schema(
        {"ids": fields.DelimitedList(fields.Int(), as_string=True)})
    schema = schema_cls()

    parsed = parser.parse(schema, web_request)
    assert parsed["ids"] == [1, 2, 3]

    dumped = schema.dump(parsed)
    data = dumped.data if MARSHMALLOW_VERSION_INFO[0] < 3 else dumped
    assert data["ids"] == "1,2,3"
Exemplo n.º 13
0
    def use_args(self,
                 argmap,
                 req=None,
                 locations=None,
                 as_kwargs=False,
                 validate=None):
        """Decorator that injects parsed arguments into a view function or method.

        .. warning::
            This will not work with `async def` coroutines. Either use a generator-based
            coroutine decorated with `asyncio.coroutine` or use the
            `parse <webargs.async.AsyncParser.parse>` method.

        Receives the same arguments as `webargs.core.Parser.use_args`.
        """
        locations = locations or self.locations
        request_obj = req
        # Optimization: If argmap is passed as a dictionary, we only need
        # to generate a Schema once
        if isinstance(argmap, collections.Mapping):
            argmap = core.argmap2schema(argmap)()

        def decorator(func):
            req_ = request_obj

            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                req_obj = req_

                # if as_kwargs is passed, must include all args
                force_all = as_kwargs

                if not req_obj:
                    req_obj = self.get_request_from_view_args(
                        func, args, kwargs)
                # NOTE: At this point, argmap may be a Schema, callable, or dict
                parsed_args = yield from self.parse(argmap,
                                                    req=req_obj,
                                                    locations=locations,
                                                    validate=validate,
                                                    force_all=force_all)
                if as_kwargs:
                    kwargs.update(parsed_args)
                    return func(*args, **kwargs)
                else:
                    # Add parsed_args after other positional arguments
                    new_args = args + (parsed_args, )
                    return func(*new_args, **kwargs)

            wrapper.__wrapped__ = func
            return wrapper

        return decorator
Exemplo n.º 14
0
    def use_args(self,
                 argmap,
                 req=None,
                 locations=None,
                 as_kwargs=False,
                 validate=None):
        locations = locations or self.locations
        request_obj = req

        if isinstance(argmap, collections.Mapping):
            argmap = argmap2schema(argmap)()

        def decorator(func):
            req_ = request_obj

            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                req_obj = req_

                # if as_kwargs is passed, must include all args
                force_all = as_kwargs

                if not req_obj:
                    req_obj = self.get_request_from_view_args(
                        func, args, kwargs)
                # NOTE: At this point, argmap may be a Schema, or a callable
                try:
                    parsed_args = self.parse(argmap,
                                             req=req_obj,
                                             locations=locations,
                                             validate=validate,
                                             force_all=force_all)
                except ParamException:
                    return jsonify({'ret': -1, 'msg': 'params error'}), 400
                else:
                    if as_kwargs:
                        kwargs.update(parsed_args)
                        return func(*args, **kwargs)
                    else:
                        # Add parsed_args after other positional arguments
                        new_args = args + (parsed_args, )
                        return func(*new_args, **kwargs)

            wrapper.__wrapped__ = func
            return wrapper

        return decorator
Exemplo n.º 15
0
    def use_args(self,
                 argmap,
                 req=None,
                 locations=None,
                 as_kwargs=False,
                 validate=None):
        """Decorator that injects parsed arguments into a view function or method.

        .. warning::
            This will not work with `async def` coroutines. Either use a generator-based
            coroutine decorated with `asyncio.coroutine` or use the
            `parse <webargs.async.AsyncParser.parse>` method.

        Receives the same arguments as `webargs.core.Parser.use_args`.
        """
        locations = locations or self.locations
        if isinstance(argmap, ma.Schema):
            schema = argmap
        else:
            schema = core.argmap2schema(argmap)()
        request_obj = req

        def decorator(func):
            req_ = request_obj

            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                req_obj = req_

                # if as_kwargs is passed, must include all args
                force_all = as_kwargs

                if not req_obj:
                    req_obj = self.get_request_from_view_args(
                        func, args, kwargs)
                parsed_args = None
                if as_kwargs:
                    kwargs.update(parsed_args)
                    return func(*args, **kwargs)
                else:
                    # Add parsed_args after other positional arguments
                    new_args = args + (parsed_args, )
                    return func(*new_args, **kwargs)

            return wrapper

        return decorator
Exemplo n.º 16
0
def test_argmap2schema():
    argmap = {
        'id': fields.Int(required=True),
        'title': fields.Str(),
        'description': fields.Str(),
        'content_type': fields.Str(load_from='content-type')
    }

    schema_cls = argmap2schema(argmap)
    assert issubclass(schema_cls, Schema)

    schema = schema_cls()

    for each in ['id', 'title', 'description', 'content_type']:
        assert each in schema.fields
    assert schema.fields['id'].required
    assert schema.opts.strict is True
Exemplo n.º 17
0
def test_delimited_list_as_string_v2(web_request, parser):
    web_request.json = {"dates": "2018-11-01,2018-11-02"}
    schema_cls = argmap2schema({
        "dates":
        fields.DelimitedList(fields.DateTime(format="%Y-%m-%d"),
                             as_string=True)
    })
    schema = schema_cls()

    parsed = parser.parse(schema, web_request)
    assert parsed["dates"] == [
        datetime.datetime(2018, 11, 1),
        datetime.datetime(2018, 11, 2),
    ]

    dumped = schema.dump(parsed)
    data = dumped.data if MARSHMALLOW_VERSION_INFO[0] < 3 else dumped
    assert data["dates"] == "2018-11-01,2018-11-02"
Exemplo n.º 18
0
    def use_args(self, argmap, req=None, locations=None, as_kwargs=False, validate=None):
        """Decorator that injects parsed arguments into a view function or method.

        .. warning::
            This will not work with `async def` coroutines. Either use a generator-based
            coroutine decorated with `asyncio.coroutine` or use the
            `parse <webargs.async.AsyncParser.parse>` method.

        Receives the same arguments as `webargs.core.Parser.use_args`.
        """
        locations = locations or self.locations
        request_obj = req
        # Optimization: If argmap is passed as a dictionary, we only need
        # to generate a Schema once
        if isinstance(argmap, collections.Mapping):
            argmap = core.argmap2schema(argmap)()

        def decorator(func):
            req_ = request_obj

            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                req_obj = req_

                # if as_kwargs is passed, must include all args
                force_all = as_kwargs

                if not req_obj:
                    req_obj = self.get_request_from_view_args(func, args, kwargs)
                # NOTE: At this point, argmap may be a Schema, callable, or dict
                parsed_args = yield from self.parse(argmap,
                                                    req=req_obj, locations=locations,
                                                    validate=validate, force_all=force_all)
                if as_kwargs:
                    kwargs.update(parsed_args)
                    return func(*args, **kwargs)
                else:
                    # Add parsed_args after other positional arguments
                    new_args = args + (parsed_args, )
                    return func(*new_args, **kwargs)
            return wrapper
        return decorator
Exemplo n.º 19
0
    def use_args(self, argmap, req=None, locations=core.Parser.DEFAULT_LOCATIONS,
                 as_kwargs=False, validate=None):
        """Decorator that injects parsed arguments into a view callable.
        Supports the *Class-based View* pattern where `request` is saved as an instance
        attribute on a view class.

        :param dict argmap: Either a `marshmallow.Schema`, a `dict`
            of argname -> `marshmallow.fields.Field` pairs, or a callable
            which accepts a request and returns a `marshmallow.Schema`.
        :param req: The request object to parse. Pulled off of the view by default.
        :param tuple locations: Where on the request to search for values.
        :param bool as_kwargs: Whether to insert arguments as keyword arguments.
        :param callable validate: Validation function that receives the dictionary
            of parsed arguments. If the function returns ``False``, the parser
            will raise a :exc:`ValidationError`.
        """
        locations = locations or self.locations
        # Optimization: If argmap is passed as a dictionary, we only need
        # to generate a Schema once
        if isinstance(argmap, collections.Mapping):
            argmap = core.argmap2schema(argmap)()

        def decorator(func):
            @functools.wraps(func)
            def wrapper(obj, *args, **kwargs):
                # The first argument is either `self` or `request`
                try:  # get self.request
                    request = req or obj.request
                except AttributeError:  # first arg is request
                    request = obj
                # NOTE: At this point, argmap may be a Schema, callable, or dict
                parsed_args = self.parse(argmap, req=request,
                                         locations=locations, validate=validate,
                                         force_all=as_kwargs)
                if as_kwargs:
                    kwargs.update(parsed_args)
                    return func(obj, *args, **kwargs)
                else:
                    return func(obj, parsed_args, *args, **kwargs)
            return wrapper
        return decorator
Exemplo n.º 20
0
    def use_args(self, argmap, req=None, locations=None, as_kwargs=False, validate=None):
        """Decorator that injects parsed arguments into a view function or method.

        .. warning::
            This will not work with `async def` coroutines. Either use a generator-based
            coroutine decorated with `asyncio.coroutine` or use the
            `parse <webargs.async.AsyncParser.parse>` method.

        Receives the same arguments as `webargs.core.Parser.use_args`.
        """
        locations = locations or self.locations
        if isinstance(argmap, ma.Schema):
            schema = argmap
        else:
            schema = core.argmap2schema(argmap)()
        request_obj = req

        def decorator(func):
            req_ = request_obj

            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                req_obj = req_

                # if as_kwargs is passed, must include all args
                force_all = as_kwargs

                if not req_obj:
                    req_obj = self.get_request_from_view_args(func, args, kwargs)
                parsed_args = None
                if as_kwargs:
                    kwargs.update(parsed_args)
                    return func(*args, **kwargs)
                else:
                    # Add parsed_args after other positional arguments
                    new_args = args + (parsed_args, )
                    return func(*new_args, **kwargs)
            return wrapper
        return decorator
Exemplo n.º 21
0
def test_argmap2schema():
    data_key_kwargs = {
        'load_from' if (MARSHMALLOW_VERSION_INFO[0] < 3) else 'data_key':
        'content-type'
    }
    argmap = {
        'id': fields.Int(required=True),
        'title': fields.Str(),
        'description': fields.Str(),
        'content_type': fields.Str(**data_key_kwargs)
    }

    schema_cls = argmap2schema(argmap)
    assert issubclass(schema_cls, Schema)

    schema = schema_cls()

    for each in ['id', 'title', 'description', 'content_type']:
        assert each in schema.fields
    assert schema.fields['id'].required
    if MARSHMALLOW_VERSION_INFO[0] < 3:
        assert schema.opts.strict is True
Exemplo n.º 22
0
def test_argmap2schema():
    data_key_kwargs = {
        "load_from" if (MARSHMALLOW_VERSION_INFO[0] < 3) else "data_key":
        "content-type"
    }
    argmap = {
        "id": fields.Int(required=True),
        "title": fields.Str(),
        "description": fields.Str(),
        "content_type": fields.Str(**data_key_kwargs),
    }

    schema_cls = argmap2schema(argmap)
    assert issubclass(schema_cls, Schema)

    schema = schema_cls()

    for each in ["id", "title", "description", "content_type"]:
        assert each in schema.fields
    assert schema.fields["id"].required
    if MARSHMALLOW_VERSION_INFO[0] < 3:
        assert schema.opts.strict is True
Exemplo n.º 23
0
    def use_args(self, argmap, req=None, locations=core.Parser.DEFAULT_LOCATIONS,
                 as_kwargs=False, validate=None):
        """Decorator that injects parsed arguments into a view callable.
        Supports the *Class-based View* pattern where `request` is saved as an instance
        attribute on a view class.

        :param dict argmap: Either a `marshmallow.Schema` or a `dict`
            of argname -> `marshmallow.fields.Field` pairs.
        :param req: The request object to parse. Pulled off of the view by default.
        :param tuple locations: Where on the request to search for values.
        :param bool as_kwargs: Whether to insert arguments as keyword arguments.
        :param callable validate: Validation function that receives the dictionary
            of parsed arguments. If the function returns ``False``, the parser
            will raise a :exc:`ValidationError`.
        """
        locations = locations or self.locations
        if isinstance(argmap, ma.Schema):
            schema = argmap
        else:
            schema = core.argmap2schema(argmap)()

        def decorator(func):
            @functools.wraps(func)
            def wrapper(obj, *args, **kwargs):
                # The first argument is either `self` or `request`
                try:  # get self.request
                    request = req or obj.request
                except AttributeError:  # first arg is request
                    request = obj
                parsed_args = self.parse(schema, req=request, locations=locations,
                                         validate=validate, force_all=as_kwargs)
                if as_kwargs:
                    kwargs.update(parsed_args)
                    return func(obj, *args, **kwargs)
                else:
                    return func(obj, parsed_args, *args, **kwargs)
            return wrapper
        return decorator
Exemplo n.º 24
0
 def __init__(self, nested, *args, **kwargs):
     if isinstance(nested, dict):
         nested = argmap2schema(nested)
     super(Nested, self).__init__(nested, *args, **kwargs)
Exemplo n.º 25
0
 def __init__(self, nested, *args, **kwargs):
     if isinstance(nested, dict):
         nested = argmap2schema(nested)
     super(Nested, self).__init__(nested, *args, **kwargs)
Exemplo n.º 26
0
def get_schema(argmap):
    if isinstance(argmap, Schema):
        return argmap
    else:
        return argmap2schema(argmap)()