openapi-generators / openapi-generators/openapi-python-client
Incorrect generation of `_parse_response `
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 2k
- Forks
- 293
- Merge moyen
- 34 min
- PR mergées (30 j)
- 1
Description
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
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Reproduisez le client généré à l’aide de la spécification OpenAPI fournie, en comparant le chemin d’analyse de la réponse lorsque celle-ci est définie inline plutôt que par l’intermédiaire d’un $ref. Suivez le chemin de génération de code qui construit _parse_response ; le travail est terminé lorsque la réponse 200 référencée génère TaskSummary.from_dict(response.json()), tandis que les autres statuts conservent leur traitement attendu.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- openapi, python
- Domaine
- api, tooling
- Type d'issue
- Bug
- Difficulté
- 3/5
- Temps estimé
- 1-2 jours
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 48/100