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

Create abstract validator classes #1653

Merged
merged 2 commits into from
Mar 2, 2023

Conversation

RobbeSneyders
Copy link
Member

@RobbeSneyders RobbeSneyders commented Feb 27, 2023

As promised, an AbstractRequestBodyValidator class. This has 2 advantages:

  • Groups all common code
  • Provides a base for custom validators

Looking at the remaining logic in the subclasses, I'm quite happy with the current abstraction. A lot of the complexity comes from substituting the default body when no body is received.

I'll leave some additional comments in-line.

@RobbeSneyders RobbeSneyders added this to the Connexion 3.0 milestone Feb 27, 2023
@RobbeSneyders RobbeSneyders force-pushed the feature/abstract-requestbody-validator branch 2 times, most recently from f7c30ba to c6bc75c Compare February 27, 2023 19:44
connexion/json_schema.py Show resolved Hide resolved
connexion/middleware/exceptions.py Show resolved Hide resolved
connexion/middleware/request_validation.py Outdated Show resolved Hide resolved
@@ -291,7 +290,7 @@ def _transform_form(self, form_parameters: t.List[dict]) -> dict:

default = param.get("default")
if default is not None:
defaults[param["name"]] = default
prop["default"] = default
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also needs to be added for each property separately, so if a body is sent without the property, the default value is added.

connexion/operations/swagger2.py Show resolved Hide resolved
encoding=encoding,
strict_validation=strict_validation,
)
self._uri_parser = uri_parser
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not completely happy with this. The __init__ arguments for the validators are fixed in the request_validation , so it doesn't really make sense that individual validators define additional parameters.
On the other hand, we do support form data specifically, so I can live with it. Open for better solutions though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't have a better idea at the moment :)

@RobbeSneyders
Copy link
Member Author

We should provide a similar base class for the ResponseBodyValidators.

@RobbeSneyders RobbeSneyders force-pushed the feature/abstract-requestbody-validator branch from c6bc75c to 3a2b000 Compare February 27, 2023 19:53
@coveralls
Copy link

coveralls commented Feb 27, 2023

Pull Request Test Coverage Report for Build 4308721132

  • 151 of 158 (95.57%) changed or added relevant lines in 9 files are covered.
  • 2 unchanged lines in 1 file lost coverage.
  • Overall coverage increased (+0.7%) to 92.997%

Changes Missing Coverage Covered Lines Changed/Added Lines %
connexion/validators/abstract.py 76 78 97.44%
connexion/validators/json.py 35 40 87.5%
Files with Coverage Reduction New Missed Lines %
connexion/lifecycle.py 2 86.08%
Totals Coverage Status
Change from base Build 4270694070: 0.7%
Covered Lines: 3267
Relevant Lines: 3513

💛 - Coveralls

@RobbeSneyders RobbeSneyders force-pushed the feature/abstract-requestbody-validator branch from 3a2b000 to 005ed0f Compare March 1, 2023 00:11
@RobbeSneyders
Copy link
Member Author

Added an AbstractResponseBodyValidator class and aligned the Request one. Commits are atomic, which is useful to review.

@RobbeSneyders RobbeSneyders changed the title Create AbstractRequestBodyValidator class Create abstract validator classes Mar 1, 2023
@RobbeSneyders RobbeSneyders force-pushed the feature/abstract-requestbody-validator branch 2 times, most recently from 840517e to aa47094 Compare March 1, 2023 21:55
@RobbeSneyders RobbeSneyders force-pushed the feature/abstract-requestbody-validator branch from aa47094 to 4e8e57e Compare March 1, 2023 22:54
connexion/middleware/exceptions.py Show resolved Hide resolved
strict_validation: bool,
uri_parser: t.Optional[AbstractURIParser] = None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just realized now that we are still using a uri_parser for form data (i.e. request body), which is not ideal.
Can't remember completely, but it's actually to parse arrays and/or parameters that are specified multiple times?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The form data body is the same format as a query string, just sent as body. So I think it's logical to use the uri_parser here as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, true for the case of application/x-www-form-urlencoded but for multipart/form-data the parameters are sent in different parts instead of query string.
But indeed, not necessarily as surprising as I thought (URI <> body) :)

encoding=encoding,
strict_validation=strict_validation,
)
self._uri_parser = uri_parser
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't have a better idea at the moment :)

@@ -443,11 +446,8 @@ def test_nullable_parameter(simple_app):
resp = app_client.put("/v1.0/nullable-parameters", content="null", headers=headers)
assert resp.json() == "it was None"

resp = app_client.put("/v1.0/nullable-parameters", content="None", headers=headers)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can we delete this one now?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In query parameters it's impossible to represent null there:

So connexion supports "null" and "None" as null values, so you can send:

  • ?key=null
  • ?key=None
    (I'm actually not a fan of supporting "None" here, since it's Python specific, but if we still need to support "null", the benefit of dropping it is probably too small.)

In json, null can be represented:

{
    "key": null
}

or for a null body (eg. try json.dumps(None)):

"null"

So we don't need to support "None" here.
We actually don't need to support "null" here either, since we should always parse it before checking, in which case it's parsed to None. This is why I replaced all is_null(body) checks in the body validators with body is None.

@RobbeSneyders RobbeSneyders merged commit 50cfc83 into main Mar 2, 2023
@RobbeSneyders RobbeSneyders deleted the feature/abstract-requestbody-validator branch March 2, 2023 20:59
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

Successfully merging this pull request may close these issues.

None yet

3 participants