Comments (8)
Thanks for the suggestion, @DamianHeard . I think this is worth considering. You make good points about the API here. One alternative I can think of would be to pass a callable that takes the request. That would enable use cases such as:
def make_user_schema(request):
only = request.query['fields']
# Once marshmallow 2.2 is released...
partial = request.method == 'PATCH'
return UserSchema(only=only, partial=partial)
@use_args(make_user_schema)
def my_view(request, args):
#...
Thoughts?
from webargs.
Thanks for you're prompt reply.
So yes I think some sort of setup callable would definitely be useful. In particular, this would solve one of my up coming feature requests in advice: the ability to provide the request in the marshmallow context.
The downside to this suggestion is that it's less declarative as the schema associated with the view is now slightly harder to find in the callable. This might sound like a small thing but this is one of the things me and my co-workers enjoy most about using webargs.
Can I suggest the following iteration on you're suggestion. The callable should accept the schema class along with the request:
def make_schema(cls, request):
only = request.queryu['fields']
partial = request.method == 'PATCH'
return cls(only=only, partial=partial)
@use_args(UserSchema, callable=make_schema)
def my_view(request, args):
# ...
This is more declarative and allows callables to be composed with schemas rather than be hard wired which should promote re-use.
I could for example do:
def use_args_with(cls, schema_args, **kwargs):
return use_args(cls, lambda kls, request: kls(context={'request': request}, **schema_args), **kwargs)
@use_args_with(UserSchema, schema_args={'only': ('name', 'email')})
def my_view(request, args):
# ...
In the event a callable isn't provided I would suggest the Parser
would just fall back on the schemas constructor.
from webargs.
I'm not sure adding a callable
param is the most intuitive solution. What happens if a schema instance is passed? Would the callable
have to handle both instances or classes? A function that returns an instance of a Schema seems more predictable.
You could still easily implement use_args_with
:
def use_args_with(schema_cls, schema_kwargs=None, **kwargs):
schema_kwargs = schema_kwargs or {}
def maker(request):
return schema_cls(only, partial, **schema_kwargs)
return use_args(maker, **kwargs)
@use_args_with(UserSchema, schema_kwargs={'only': ('name', 'email')})
def my_view(request, args):
from webargs.
How would you modify this approach to work when the schema is specified as a dict
? Since the Parser
is presently responsible for constructing the schema it wouldn't be available in the closure.
from webargs.
How would you modify this approach to work when the schema is specified as a dict?
def use_args_with(schema_cls, schema_kwargs=None, **kwargs):
if not issubclass(schema_cls, Schema):
schema_cls = argmap2schema(schema_cls)
schema_kwargs = schema_kwargs or {}
def maker(request):
return schema_cls(only, partial, **schema_kwargs)
return use_args(maker, **kwargs)
Edit: Fix conditional.
from webargs.
Thanks for your speedy response.
While I don't love that it will certainly produce the required result. The main downside I see is that between the various parser implemention and the decorators there's already a lot of places converting dict
s objects to ma.Schema
and this would continue that proliferation rather than taking advantage of what's already been implemented.
I agree that in my suggestion supplying callable
a schema has already been instantiated is far from clearly defined. If you recall my earlier points I was leaning towards ultimately removing support for passing in instantiated schemas for the following reasons:
- The current approach requires API users to explicitly set strict=True either in the schema constructor or the schema Meta class. This could be ensured internally if core.Parser handles construction.
- Since webargs presently requires schema instances be constructed at module scope and usage of the marshmallow context will persist between requests. Re-constructing the schema each requests ensures no state can persist.
- Presently core.Parser is already responsible for schema construction with dictionary based webargs usage. The proposed change would bring the two usages more into line.
That said I can see this might be a major departure from your thoughts and maybe entirely unpalatable. In addition to this, I don't for example have a solution of how one would easily supply constructor arguments to the schema without also using a callable or making further modifications to the decorators.
I'm still happy to put a PR together if you're happy for me to push it over the line in my own time. If I come up with an alternative approach I'll be sure to slap it up here for discussion prior to then.
from webargs.
Good points in favor of passing a Schema class over an instance. However, I'm not sure we want to completely drop support for passing instances. Passing an instance can be useful (1) when the constructor args don't need to be dynamic and (2) for performance reasons (avoiding the overhead of instantiating a Schema).
The main advantage of allowing a callable is that it enforces the mutual exclusivity of passing a dict
vs. Schema class vs. Schema instance.
from webargs.
Added in f77b288
from webargs.
Related Issues (20)
- The type of "argmap" allows for `Mapping[str, Field]`, but `Schema.from_dict` only supports `Dict[str, Field]` HOT 1
- Consider trying pre-commit.ci for autoupdate PRs + faster CI HOT 9
- [RFC] Revisiting our CI setup: GH Actions, RTD HOT 8
- potential documentation issue in quickstart/error-handling HOT 3
- Parse a schema that contains both file and form data HOT 2
- How to strip empty strings from list of strings in args using DjangoParser? HOT 3
- Tags cleanup HOT 2
- How to use partial loading with nested field HOT 2
- When setting location to `files`, custom field's `_deserialize` and `_validated` methods were not called HOT 7
- aiohttp. body argument is deprecated for http web exceptions HOT 1
- Update minimum supported versions of frameworks in next major release HOT 1
- Release version 8.2.0 HOT 4
- [Question] how to use this with line item like data? HOT 2
- Is there possible add Quixote web framework support HOT 2
- [Question] How to set up the Schema that will validate against a list of allowed enum values? HOT 1
- Dealing with empty values in `DelimitedFieldMixin` HOT 2
- Being able to handle ValidationError in Flask view methods without custom error handler HOT 4
- webargs.core.Parser should describe default for unknown either as marshmallow.EXCLUDE or "exclude" HOT 1
- RFC: support passing the whole parsed arguments as a keyword argument HOT 10
- Please consider using Mapping instead of Dict in ArgsMap to avoid type checker errors HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from webargs.