Hi @sloria. Loving the new marshmallow integration! Thanks so much.
I had a suggested tweak to the API I was hoping to run past you. Presently marshmallow schemas are used like:
# example A
@use_args(UserSchema())
def my_pryamid_view(request, args):
pass
I suggest it makes sense to push the construction of the schema instance into the core.Parser
becoming:
# example B
@use_args(UserSchema)
def my_pyramid_view(request, args):
pass
This has a number of benefits:
- 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.
Of course example A over simplifies the construction of the marshmallow schemas since there are a number of arguments that could be supplied with marshmallow construction. What we probably would require is either:
# example C
@use_args(UserSchema, only=('name', 'email'))
def my_pyramid_view(request, args):
pass
or
# example D
@use_args(lambda: UserSchema(only=('name', 'email'))
def my_pyramid_view(request, args):
pass
or
# example E
@use_args(UserSchema, schema_args={'only': ('name', 'email')})
def my_pyramid_view(request, args):
pass
I dislike C because it utilizes kargs
which I think have limitations should the use_args
decorator, for example, require additional arguments be passed to core.Parser
in later versions of the API.
I favour E over D as it allows us to address the issue of setting strict=True
during schema construction.
This would also be compatible with webargs's dictionary based usage. So with dictionaries E becomes:
# example F
user_dict = {
'name': field.String(),
'email': field.Email(),
'password': field.String(),
}
@use_args(user_dict, schema_args={'only': ('name', 'email')})
def my_pyramid_view(request, args):
pass
I'm happy to put a PR together should there be interest in this change.