openapi-generators / openapi-generators/openapi-python-client

Incorrect generation of `_parse_response `

Offen
#1,125 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Vorherrschende Sprache
Python
Sterne
2k
Forks
293
Ø Merge
34 Min.
Gemergte PRs (30 T.)
1

Beschreibung

Lovely package BTW!

Describe the bug
Code generation for parsing API response does not generate the code that creates the Python model after the response is completed. This happens when using a $ref to define the response instead of just defining the response body inside the path definition.

OpenAPI Spec File

openapi: 3.0.3

info:
  title: Example
  description: |
    Example API definition.
  version: 1.0.0

security:
    - BearerAuth: []

paths:

  /v2/task/{task_id}:
    get:
      summary: Get the summary of a task.
      responses:
        '200':
          $ref: '#/components/responses/task_summary'
        '400':
          $ref: '#/components/responses/bad_request'
        '403':
          $ref: '#/components/responses/not_authorized'
      parameters:
        - $ref: '#/components/parameters/task_id'

components:

  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

  parameters:
    task_id:
      name: task_id
      in: path
      description: The unique identifier of the task targeted by the request.
      required: true
      schema:
        $ref: '#/components/schemas/TaskId'

  responses:

    task_summary:
      description: Summary of the task at the time the request was made.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/TaskSummary'

    bad_submit_task_request:
      description: |
        The request is invalid. This may indicate an error when parsing a parameter, or an error when parsing or validating the request body. The response body may contain a JSON array with a list of validation errors.
      content:
        application/json:
          schema:
            type: object
            properties:
              validation_errors:
                type: array
                minItems: 1
                items:
                  type: string

    not_authorized:
      description: |
        User is not authorized to perform this task. 

    bad_request:
      description: |
        The request is invalid. This may indicate an error when parsing a parameter.

  schemas:
  
    TaskId:
      type: string
      minLength: 1
      maxLength: 256
      pattern: "^[a-zA-Z0-9][a-zA-Z0-9-]*$"
      example: '80cf75f2-4700-4006-9203-4376b091ee4e'
      description: A unique identifier for a task. Must not be an empty string.

    TaskSummary:
      type: "object"
      description: Summary of existing task, including task status.
      properties:
        task_status:
          $ref: '#/components/schemas/TaskStatus'
      required:
        - task_status

    TaskStatus:
      type: string
      enum:
        - Created
        - PayloadProcessing
        - Scheduled
        - Completed
        - Cancelled
        - Failed
      description: |
        Reports status of the task. Lifecycle of a normal task is Created -> PayloadProcessing -> Scheduled -> Completed.
        where PayloadProcessing - the task is going trough additional compilation/validation/optimization, 
        Scheduled - the task is in the qpu queue, Completed - the task has been executed.

the code that gets generated here is:

def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[Any]:
    if response.status_code == HTTPStatus.OK:
        return None
    if response.status_code == HTTPStatus.BAD_REQUEST:
        return None
    if response.status_code == HTTPStatus.FORBIDDEN:
        return None
    if client.raise_on_unexpected_status:
        raise errors.UnexpectedStatus(response.status_code, response.content)
    else:
        return None

which is not correct. The additional context shows the expected behavior.

Desktop (please complete the following information):

  • OS: macOS: 14.4.1
  • Python Version: 3.12.1
  • openapi-python-client: 0.21.5 [e.g. 0.1.0]

Additional context
Note if I modify the path:

  /v2/task/{task_id}:
    get:
      summary: Get the summary of a task.
      responses:
        '200':
          description: Summary of the task at the time the request was made.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskSummary'
        '400':
          $ref: '#/components/responses/bad_request'
        '403':
          $ref: '#/components/responses/not_authorized'
      parameters:
        - $ref: '#/components/parameters/task_id'

it generates the correct code:

def _parse_response(
    *, client: Union[AuthenticatedClient, Client], response: httpx.Response
) -> Optional[Union[Any, TaskSummary]]:
    if response.status_code == HTTPStatus.OK:
        response_200 = TaskSummary.from_dict(response.json())

        return response_200
    if response.status_code == HTTPStatus.BAD_REQUEST:
        response_400 = cast(Any, None)
        return response_400
    if response.status_code == HTTPStatus.FORBIDDEN:
        response_403 = cast(Any, None)
        return response_403
    if client.raise_on_unexpected_status:
        raise errors.UnexpectedStatus(response.status_code, response.content)
    else:
        return None

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Reproduziere den generierten Client anhand der bereitgestellten OpenAPI-Spezifikation und vergleiche den Pfad zur Antwortverarbeitung, wenn die Antwort inline statt über einen $ref definiert ist. Verfolge den Codegenerierungspfad, der _parse_response erstellt; abgeschlossen ist die Aufgabe, wenn die referenzierte 200-Antwort TaskSummary.from_dict(response.json()) generiert, während andere Statuscodes ihre erwartete Verarbeitung beibehalten.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
openapi, python
Bereich
api, tooling
Issue-Typ
Bug
Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
48/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.