Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The substitute for 'use=lambda' in new API #69

Closed
imhoffd opened this issue Oct 8, 2015 · 8 comments
Closed

The substitute for 'use=lambda' in new API #69

imhoffd opened this issue Oct 8, 2015 · 8 comments

Comments

@imhoffd
Copy link
Contributor

imhoffd commented Oct 8, 2015

Just putting this here for others who may be wondering what to do after use= (the callable that let you preprocess the value, see this in pre 0.16.0 code).

For 0.16.0 onwards, use of marshmallow is encouraged. Marshmallow brings a whole slew of serialization/deserialization features, which is exactly what you're doing when you take web requests from various frameworks and turn them into native python data types: deserializing.

use= used to let you change the value of a field while it was parsed. You can accomplish that and more now with marshmallow's post_load decorator:

from marshmallow import Schema, post_load
from webargs import fields

class ArgSchema(Schema):
    name = fields.Str(required=True, location='querystring')

    @post_load
    def uppercase_name(self, data):
        data['name'] = data['name'].upper()
        return data

See the documentation for how to use marshmallow schemas in webargs.

Since you now have access to all fields in the data argument of your post_load method, you can do cross preprocessing, meaning you can change the value of one field based upon the value of another.

@sloria
Copy link
Member

sloria commented Oct 8, 2015

Thanks @dwieeb!

Another way to get the same functionality as use is through a custom field.

class Use(fields.Field):

    def __init__(self, func, child=None, **kwargs):
        super().__init__(**kwargs)
        self.func = func
        self.child = child

    def _deserialize(self, value, attr, data):
        if self.child:
            value = self.child.deserialize(value, attr, data)
        return self.func(value)

@use_args({
    'foo': Use(lambda v: v.upper(), fields.Str())
})
def myview(args):
    #...

@imhoffd
Copy link
Contributor Author

imhoffd commented Oct 8, 2015

Interesting. Perhaps this could exist in the webargs codebase as fields.Lambda or fields.Alter or something?

@sloria
Copy link
Member

sloria commented Oct 8, 2015

Perhaps in the future. In the interest of keeping the core small, I'm going to hold off on adding this to the code base for now.

@imhoffd
Copy link
Contributor Author

imhoffd commented Oct 8, 2015

👍 I agree.

Besides, I think I would actually prefer the marshmallow solution, as it allows access to other fields and does not require custom fields.

Thanks for webargs. With the marshmallow integration it's the best solution out there even without being "stable"... And I've used pretty much everything out there for flask, including rolling my own.

@sloria
Copy link
Member

sloria commented Oct 9, 2015

Thanks for the encouraging words!

@sloria
Copy link
Member

sloria commented Nov 17, 2015

I've moved this to the Wiki here: https://github.com/sloria/webargs/wiki/Recipes . Thanks again @dwieeb !

@sloria sloria closed this as completed Nov 17, 2015
@imhoffd
Copy link
Contributor Author

imhoffd commented Nov 17, 2015

You didn't need to do that; I'm not sure if a migration guide of a lesser used feature from an alpha version is helpful to people, especially as the 1.0 code base matures.

What's more important is that the documentation somehow shows the pre-processing and post-processing of schemas. Currently, there's just a link to the marshmallow api in the "marshmallow integration" section. People coming into webargs with no prior marshmallow experience may be looking in the docs for how to process values before they enter their route functions. Right now, it looks as if webargs doesn't have this.

I could get around to writing up something for the docs if I find time.

@sloria
Copy link
Member

sloria commented Nov 17, 2015

I agree; I think it would be useful to have some documentation for pre- and post-processing behavior. I would certainly welcome a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants