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

Defining location for a block of fields #90

Closed
tuukkamustonen opened this issue Feb 18, 2016 · 3 comments

Comments

@tuukkamustonen
Copy link
Contributor

commented Feb 18, 2016

Reading the docs, I can see that one can restrict locations for all parameters as whole as in:

@use_args({...}, locations=('json', 'form'))

But if I mix parameters from different locations together (and I only accept parameter from one location), I still need to provide location for each parameter separately:

@use_args({
    'command': fields.Str(location='json),
    'recurse': fields.Bool(location='query')
}, locations=('json', 'query'))  # location here does not actually have effect afaik

Is it ok to provide @use_args twice to achieve something like:

@use_args({...}, locations=('json',))
@use_args({...}, locations=('headers',))
@use_args({...}, locations=('query',))

Or could we do it via nesting or something:

@use_args([
    {'schema': {...}, locations=('json',)},
    {'schema': {...}, locations=('headers',)},
    {'schema': {...}, locations=('query',)}
])

And maybe have built-in decorators for most common locations:

@headers({...})
@cookies({...})
@json({...})
...

If there were lots of parameters to validate, these would slightly reduce the size of the boilerplate.

@sloria

This comment has been minimized.

Copy link
Member

commented Apr 8, 2016

I have just confirmed that "stacking" use_args works.

query_args = {
    'page': fields.Int()
}
json_args = {
    'name': fields.Str(),
}
@app.route('/stacked', methods=['GET', 'POST'])
@use_args(query_args, locations=('query', ))
@use_args(json_args, locations=('json', ))
def viewfunc(query_parsed, json_parsed):
    return jsonify({
        'json': json_parsed,
        'query': query_parsed
    })

The decorator shortcuts could easily implemented with partial

import functools
query = functools.partial(use_args, locations=('query', ))
json = functools.partial(use_args, locations=('json', ))

@query(query_args)
@json(json_args)
def viewfunc(query_parsed, json_parsed):
    #...

In the interest of keeping the webargs API small, I probably won't be adding these into the codebase. They're simple enough for users to implement.

sloria added a commit that referenced this issue Apr 8, 2016

@sloria sloria added the question label Apr 8, 2016

@sloria sloria closed this Apr 8, 2016

@tuukkamustonen

This comment has been minimized.

Copy link
Contributor Author

commented Apr 9, 2016

@sloria That's pretty neat, thanks!

For me this is fine, but considering the overall user-friendliness of the library, I think it would make sense to add those couple of lines to the codebase. It's way more descriptive to specify @headers and @cookies, etc. and I assume people are rarely mixing the locations anyway.

Though this is just my assumption, I suggest to reconsider :)

@sloria

This comment has been minimized.

Copy link
Member

commented Apr 9, 2016

@tuukkamustonen It wouldn't just be a couple lines. It would be 6 lines for each of the locations * 8 frameworks = 48 LOC, plus tests. Also, naming is a bit tricky; @json, for example, would shadow the oft-imported json from the stdlib.

I would be much more open to adding a section in the Advanced Usage docs that had snippets for shortcuts like this. PRs welcome =) .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.