-
-
Notifications
You must be signed in to change notification settings - Fork 631
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
Add option to throw validation error on extra keys #524
Comments
FYI, there's another example of how to do this in the docs: http://marshmallow.readthedocs.io/en/latest/extending.html#validating-original-input-data |
@lafrech Oh, right. That's practically the same, just using As it's in the docs, I assume maintainers have a negative stand on supporting this through a parameter? |
Duplicate of #515. |
We do not currently have plans to add this feature. I recommend using the recipe in the docs for now. I am not completely opposed to adding this in the future, given a strong case and enough user support. Closing this for now, but will reopen if there is need for further discussion. |
+1 for adding built in support for this. |
I now need to support this together with With something like: class Sch(Schema):
foo = fields.Int()
@validates_schema(pass_original=True)
def v(self, data, orig_data):
...
raise ValidationError('Extra arguments passed.', ...) With I can iterate the array and find the extra keys per index, but I cannot sensibly report the errors per index (because raising Any workarounds? Also see #621 as related. |
+1 In my case it's to avoid ambiguity. The API expects a set of keys to be present per method and only those keys. We use Marshmallow to power an API and you really want the boundaries of each API method to be crisp. I don't want anyone to be able to "think"/"guess" that a key is valid because the API accepts it without sending an error. A different use case is what I got from one of our developers today: "I'm creating a page with a title and a slug but the API doesn't accept the slug. It gives no error, it just creates a slug based on the title instead." Turns out the user sent the following JSON payload:
But our API wants The backup option for us is to force So that's my use case. |
Somehow related to #595, which is the exact opposite. Just in case this issue is reopened one day and we can come with a solution that covers both needs. |
There has been some recent discussion about how |
Aren't these independent things?
Just because Or maybe you meant it is technically independent, but it would be more consistent to apply a similar logic here. Or maybe I'm just confused. |
I thought this could use a second look since we are starting to favor strictness by default when it helps detect common developer mistakes. Ignoring extra data is a valid use case, but it can lead to silent data loss. As general rules, I think:
|
OK, I get your point. I don't mind reopening this.
Yes, as much as possible.
Alright. Regarding this specific case, I think there's no safe side of the fence. Passing transparently unknown fields car also be a security flaw. I rely on my schemas to guard the entrance of my database. I'd hate to realize that I've been accepting data from field I did not explicitly declare, that might even override DB attribute that are meant to be dealt with internally. In fact, I prefer to reject too much than to accept too much, but that's a matter of use case. The feature in #595 could be nice, but I don't think I'd make it default. Especially since it provides no validation. (Well, unless we enhance it by adding the possibility to specify a |
I feel like I have seen this in another serialization library before. I can't seem to find a reference at the moment.
Edit: Found it. https://github.com/alecthomas/voluptuous#extra-dictionary-keys |
Colander has similar options:
https://docs.pylonsproject.org/projects/colander/en/latest/api.html#colander.Mapping |
This API makes sense. Currently, Marshmallow only provides We could even go further and let the user set a default |
The recipe provided also falls apart when using the |
Here's a more thorough review of this behavior in other validation libraries: https://gist.github.com/sloria/2fac357710f13e855a5b9cf8f05a4da0 |
just bumping this to show interest, this would be nice functionality to have. In our usage of marshmallow, we have shared schemas that are used to both validate serialized data coming too and from our database, but also for the url parameters of the api fronting this data to ensure request arguments coming in for those columns are valid query arguments. For my data tier I am happy to have unexpected things be dropped, however when validating query parameters at the web request level I would like to be able to tell people interacting with the API what invalid arguments they supplied. |
Yeah, I think we should move forward with this. We will need to decide on a default:
We also need to decide on an API. A class Meta option probably makes sense. from marshmallow import RAISE, REMOVE, ALLOW
class UserSchema(Schema):
class Meta:
unknown = ALLOW Thoughts? |
As we discussed in my PR, I really lean toward specifying that kind of behavior at instanciation time: UserSchema(unknown=ALLOW) It allows one schema to be used in different contexts, where you might want different behaviors on unknown keys. Also, it seems to me that the implementation would be at least as simple. |
I agree with @ramnes that the ability to designate behavior per-context would be very useful, and schema re-use would be very straightforward. It more or less fits my use-case exactly 💸 . |
There you go: #838 😉 |
We still need to decide on a default. I think we should rule out "allow"--it is too permissive for the common use case. That leaves "ignore" and "raise". Let's take a poll: Add an emoji reaction to this comment with your vote. 😄 = "ignore" - Discard unknown fields but don't error. This is the current behavior. DRF, Colander, and Valideer have this as the default. |
If you do anything other than keep the current behavior, I'd imagine that would delay the release to a minor or possibly a major version. Is that the plan regardless? If backwards compatible changes can provide the features faster in a future patch, I would much prefer that, then maybe upset the status quo in a major. |
This change will be applied to Marshmallow v3 (major version) in any case. It could be backported to Marshmallow v2 with "ignore" as default, but I don't think this is planned. |
Another thought: |
🚲🏠
|
Yeah, to be honest I don't give much importance to those three values naming, it's not like people are going to use them all the time; they'll just check the doc or use their autocompletion. Whatever you guys prefer will do it just fine. |
OK, my turn. I like BTW, there could be an evolution in the future allowing to specify a default |
I like those.
Sure, we could even add support for |
|
Input data is not modified, so unknown keys are not removed from it. |
Doesn't kwarg name |
would it be a high level of effort to make it an addition to the typical MarshalResult() to be handled |
@tuukkamustonen Yes, but "ignoring" could still be conflated with "ignore validation without removing", which is why
@ptdel |
This is closed by #838 . Thanks everyone for your input. I've created follow-up issues for the changes/enhancements discussed in this issue and the PR.
|
Product version of our project was broken because of this commit)) |
@BOPOHOB, not sure what you mean, here. This feature was included in a 3.0 beta version. For production purpose, the 2.x branch is recommended. If you're using 3.x beta, you should expect things to break from times to times. Also, this feature itself shouldn't be breaking. The breaking change is |
@lafrech Yes, it was my bad) But we did not expect such changes in 3.0.0b subminor |
@nicktimko Keep the conversation constructive please. https://marshmallow.readthedocs.io/en/dev/code_of_conduct.html If someone discovers marshmallow via the github page, the readme instructs them to install the prerelease version without any warning that it is a beta version. We might want to consider making it a little clearer. https://github.com/marshmallow-code/marshmallow#get-it-now |
in marshmallow V3 you can do it using metsa class like below class UserSchema(Schema): |
Any specific reason on why this feature is available on def test_validate(self):
class ModelSchema(Schema):
class Meta:
unknown = RAISE
name = fields.String()
schema = ModelSchema()
data = dict(name='jfaleiro', xyz=2)
schema.validate(data) # OK
schema.load(data) # fail |
@jfaleiro This feature is avaialable on
|
I guess I'm having somehow the same question: I'd just like to validate, but ignore unknown fields. |
I'm not sure if I'm missing something, but I would like to throw error if extra keys are provided, as in:
I've been using the following implementation (taken from marshmallow-code/webargs#87 (comment)):
I would expect this to be a common need, however, so could it be supported by the library out-of-the-box?
The text was updated successfully, but these errors were encountered: