OpenAPITools / OpenAPITools/openapi-generator

[BUG] Python Client allof get_discriminator_class() value Error=unhashable type: 'dict'

Open
#9,992 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Client: Python Issue: Bug
Dominant language
Java
Stars
26.8k
Forks
7.7k
PR merge metrics
PR metrics pending

Description

Bug Report Checklist
  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
openapi-generator version

5.1/5.2

OpenAPI declaration file content or url
openapi: 3.0.1
info:
  title: Test
  version: 0.0.1
servers:
- url: http://localhost:8888/api/v1
tags:
- description: Authentication
  name: auth
paths:
  /authentication:
    post:
      operationId: login
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginPayload'
        description: Login information
        required: true
        x-body-name: body
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserResponse'
          description: successful operation
      summary: Login to the application
      tags:
      - auth
      x-codegen-request-body-name: body
      x-openapi-router-controller: openapi_server.controllers.auth_controller
    x-swagger-router-controller: auth
components:
  schemas:
    LoginPayload:
      example:
        payload:
          password: password
          login: login
      properties:
        payload:
          $ref: '#/components/schemas/Login'
      required:
      - payload
      type: object
    Login:
      example:
        password: password
        login: login
      properties:
        login:
          type: string
        password:
          type: string
      required:
      - login
      - password
      type: object
    Response:
      discriminator:
        propertyName: result
      example:
        result: result
        trace: trace
        statusText: statusText
        message: message
        errors:
        - errors
        statusCode: 0
      properties:
        statusText:
          type: string
        statusCode:
          type: integer
        result:
          type: string
        message:
          type: string
        errors:
          items:
            type: string
          type: array
        trace:
          type: string
      required:
      - message
      - result
      - statusCode
      - statusText
      type: object
    UserResponse:
      allOf:
      - $ref: '#/components/schemas/UserResponse_allOf'
      - $ref: '#/components/schemas/Response'
    User:
      properties:
        id:
          type: integer
        login:
          type: string
        firstName:
          type: string
        lastName:
          type: string
        email:
          type: string
      required:
      - email
      - firstName
      - id
      - lastName
      - login
      - roles
      type: object
    UserResponse_allOf:
      properties:
        result:
          $ref: '#/components/schemas/User'
Generation Details
java -jar ./openapi-generator-cl.jar generate -i ./testallof.yaml -g python \
--additional-properties=packageName=testallof \
-o ../testallof/
Steps to reproduce
  1. Generate Python Client (v 5.2)
java -jar ./openapi-generator-cl.jar generate -i ./testallof.yaml -g python \
--additional-properties=packageName=testallof \
-o ../testallof/
  1. Make Call to API using Python Client
with testallof.ApiClient(configuration) as api_client:
    # Create an instance of the API class
    api_instance = auth_api.AuthApi(api_client)
    try:
        login = Login('<username>', '<password>')
        lpl = LoginPayload(payload=login)
        # Returns necessary cookies to authenticate with embedded external services
        api_response = api_instance.login(body=lpl)
    except testallof.ApiException as e:
        print("Exception when calling AuthApi->authenticate_external_services: %s\n" % e)
  1. The API Call fails when creating the Response instance at the code (model_utils.py)
def get_discriminator_class(model_class,
                            discr_name,
                            discr_value, cls_visited):
...
    if discr_name in model_class.discriminator:
        class_name_to_discr_class = model_class.discriminator[discr_name]
        used_model_class = class_name_to_discr_class.get(discr_value)

with the error

testallof.exceptions.ApiValueError: Invalid inputs given to generate an instance of 'Response'. The input data was invalid for the allOf schema 'Response' in the composed schema 'UserResponse'. Error=unhashable type: 'dict'

More Specifically the error is

get_discriminator_class
    used_model_class = class_name_to_discr_class.get(discr_value)
TypeError: unhashable type: 'dict'
  1. the class_name_to_discr_class is a dictionary of values, even though in this example its a single allOf it returns it as a dictionary
    {'UserResponse': <class 'testallof.model.user_response.UserResponse'>}
  2. discriminator value (discr_value) is a dictionary in this example:
{'id': 1, 'login': '<username>', 'firstName': '<firstname>', 'lastName': '<lastname>', 'email': 'email>', 'isActive': 1}
  1. When doing the class_name_to_discr_class.get(discr_value) it is failing as it cannot lookup via another dictionary
Related issues/PRs
Suggest a fix

No Suggestion, still working out the further downstream logic and goal and becoming more familiar.. will update as i work through the issue

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the generated Python client and model_utils.py, especially get_discriminator_class(), using the supplied OpenAPI document and Java generation command. Reproduce the API call that constructs UserResponse and trace the discriminator and allOf values. Done means the generated client handles this response without the unhashable type: 'dict' error.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, python
Domain
api, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.