Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • O openapi-generator
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 3,476
    • Issues 3,476
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 402
    • Merge requests 402
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • OpenAPI Tools
  • openapi-generator
  • Merge requests
  • !11125

[Python] Added Ability to Initialize Models by Passing in Dictionaries

  • Review changes

  • Download
  • Email patches
  • Plain diff
Merged Administrator requested to merge github/fork/Bandwidth/ckoegel-py-models into master Dec 14, 2021
  • Overview 0
  • Commits 7
  • Pipelines 0
  • Changes 228

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
    Commit all changed files. This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master. These must match the expectations made by your contribution. You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./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)

Assignee
Assign to
Reviewers
Request review from
Time tracking
Source branch: github/fork/Bandwidth/ckoegel-py-models