Created by: ckoegel
Python models created from openapi schema do not accept positional objects as arguments. More information about what the goal of this PR is can be found at this issue. This was mostly caused by the invalid_pos_args.mustache
file instantly raising an error if positional arguments were passed in. This has been updated to accept dictionaries as a valid positional argument. The dictionaries are merged into the kwargs dictionary that the function uses to initialize. This allows users to pass in dictionaries to create models, which was previously allowed with the **
operator, but this allows for an alternative method of creating these objects.
The main function of this PR allows for the creation of nested objects. The setattr
function called when initializing the model validates the type of each kwarg before setting the attribute, meaning if nested dictionaries are passed in, the validate_and_convert_types
function will raise a type error if those nested dictionaries need to be used in the creation of another object since their types do not match. The solution for this was already partially implemented, since the validate_and_convert_types
function has logic to attempt to convert non-matching attribute types, but this needed to be modified to allow for attempting to convert dictionaries. Once the logic was added to allow a dictionary to be converted, the logic within attempt_convert_item
automatically uses the dictionary to initialize a new instance of its respective model. This allows for any amount of nested dictionaries to be passed into a model initialization and their corresponding models be created. Errors will still be thrown if the positional arguments are incorrectly formatted, or if the model that needs to be created from a dictionary does not match the dictionary's contents.
This can be validated by using this spec and this command: java -jar ./modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g python -i messaging.json -o sdk/
in the root of the project to generate an SDK. Then running the FastApi app below and making a POST to the endpoint with the body below should successfully create both a BandwidthCallbackMessage and a BandwidthMessage, which can be seen in the output of the FastApi app.
FastApi App:
from fastapi import FastAPI, Request
from openapi_client.model.bandwidth_callback_message import BandwidthCallbackMessage
app = FastAPI()
@app.post('/msg-resp')
async def rec_message(request: Request):
body = await request.json()
bw_callback = BandwidthCallbackMessage(body)
print("Type of request: ", type(bw_callback))
print("Type of callback message: ", type(bw_callback.message))
print("Request: \n", bw_callback)
return 200
Request Body:
{
"time": "2021-12-14T19:48:29.806Z",
"type": "message-received",
"to": "+19195551234",
"description": "Incoming message received",
"message": {
"id": "id-abcd",
"owner": "+19195551234",
"applicationId": "app-id-abcd",
"time": "2021-12-14T19:48:29.641Z",
"segmentCount": 1,
"direction": "in",
"to": [
"+19195551234"
],
"from": "+19195554321",
"text": "Hello World"
}
}
PR checklist
-
Read the contribution guidelines. -
Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community. -
Run the following to build the project and update samples: ./mvnw clean package ./bin/generate-samples.sh ./bin/utils/export_docs_generators.sh
./bin/generate-samples.sh bin/configs/java*
. For Windows users, please run the script in Git BASH. -
File the PR against the correct branch: master
(5.3.0),6.0.x
-
If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.
@taxpon (2017/07) @frol (2017/07) @mbohlool (2017/07) @cbornet (2017/09) @kenjones-cisco (2017/11) @tomplus (2018/10) @Jyhess (2019/01) @arun-nalla (2019/11) @spacether (2019/11)