-
Notifications
You must be signed in to change notification settings - Fork 373
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
Change OpenAPI backend generator config #4376
base: main
Are you sure you want to change the base?
Change OpenAPI backend generator config #4376
Conversation
api/reviews_api.py
Outdated
@@ -57,7 +57,7 @@ def do_get(self, **kwargs) -> dict[str, list[dict[str, Any]]]: | |||
# Note: We assume that anyone may view approvals. | |||
votes = Vote.get_votes(feature_id=feature_id, gate_id=gate_id) | |||
dicts = [converters.vote_value_to_json_dict(v) for v in votes] | |||
return GetVotesResponse.from_dict({'votes': dicts}).to_dict() | |||
return GetVotesResponse.model_construct(votes=dicts).to_dict() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return GetVotesResponse.model_construct(votes=dicts).to_dict() | |
return GetVotesResponse.from_dict({'votes': dicts}).to_dict() |
model_construct takes in the expected object type for each argument. (votes should expect a variable of type List[Votes]
). However, this is a special case where the existing code does this special conversion to dictionaries first. So instead, you can use the class method from_dict.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This did not work either. This indeed helps convert the dict to model and then using to_dict() to convert it back, but it seems like the serialization & deserialization during the process changed the order of stuff we put in the dict and therefore differ from the test case. How would you suggest circumventing this situation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What error are you seeing? When I tried this suggestion earlier, the test started passing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i got
FAIL: test_do_get__success (api.reviews_api_test.GatesAPITest.test_do_get__success) Handler retrieves all gates associated with a given feature. Traceback (most recent call last): File "/opt/homebrew/Cellar/[email protected]/3.11.8/Frameworks/Python.framework/Versions/3.11/lib/python3.11/unittest/mock.py", line 1375, in patched return func(*newargs, **newkeywargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/mark/chromium-dashboard/api/reviews_api_test.py", line 349, in test_do_get__success self.assertEqual(actual, expected) AssertionError: {'gat[126 chars]e', 'state': 1, 'assignee_emails': [], 'additi[125 chars]ne}]} != {'gat[126 chars]e', 'escalation_email': None, 'state': 1, 'req[265 chars]']}]} Diff is 674 characters long. Set self.maxDiff to None to see it.
Looks like the order is still messed up. The only change I made was to undo the changes in the current commit to return GetVotesResponse.from_dict({'votes': dicts}).to_dict()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That failing test is for a different method than this one. This test should be passing now. Could you verify that?
The GatesAPITest.test_do_get__success test is for another class in the same file. I verified that GatesAPITest.test_do_get__success is failing for me too.
@mock.patch('internals.approval_defs.get_approvers')
def test_do_get__success(self, mock_get_approvers):
"""Handler retrieves all gates associated with a given feature."""
mock_get_approvers.return_value = ['[email protected]']
self.maxDiff = None
with test_app.test_request_context(self.request_path):
actual = self.handler.do_get(feature_id=self.feature_id)
expected = {
"gates": [
{
"id": 1,
"feature_id": self.feature_id,
"stage_id": 1,
"gate_type": 1,
"team_name": "API Owners",
"gate_name": "Intent to Prototype",
"escalation_email": None,
"state": 1,
# "requested_on": None,
# "responded_on": None,
"assignee_emails": [],
# "next_action": None,
"additional_review": False,
'slo_initial_response': 5,
# 'slo_initial_response_took': None,
# 'slo_initial_response_remaining': None,
'possible_assignee_emails': ['[email protected]'],
},
],
}
self.assertEqual(actual, expected)
You will see that it is not an order issue but it is removing the null values instead of defaulting to None. That would be the first thing I would look into.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like if you need to add "nullable: true"
to those fields I commented out in my above comment (similar to escalation_email). Then, it will work. Then you can revert the commented lines I made in the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pasted the wrong test.. my bad. Adding nullable: true
gets the test passed. I'll modify other specs as well to see if all tests could pass. Thanks!
|
Let's take a look at the errors for the non generated files:
There are two types of errors
|
framework/basehandlers.py
Outdated
from framework import csp, permissions, secrets, users, utils, xsrf | ||
from internals import approval_defs, notifier_helpers, user_models |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason for updating the imports like this? This does not hurt the functionality, but it is not the typical import structure used for the project
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like it runs organize imports
. I'll revert it. thanks
FYI, I'm looking into the mypy issues here regarding the generated files not being ignored, and will give an update here when I've found anything Edit: It looks like markxiong0122 might have a solution in the comments below. 🙂 |
Thanks for the detailed explanation! I've updated my code and now it should pass everything other than mypy errors from the generated files |
Regarding the mypy errors in generated files, I found this PR of openapi-generator which already solved the bug: OpenAPITools/openapi-generator#19223. Should we update our tool to the latest release? @jcscottiii |
I think that's a good idea! |
PR Summary:
This PR changed the -g value in the npm command
openapi-backend
fromflask-python
topython
to allow circular imports in our OAS to further land the implementation of OAS on features_api.It also:
from_dict
, we also usemodel_construct
)nullable
value in OAS)