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

Support for multiple content types in error response

オープン
#1,248 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

主要言語
Python
スター
2k
フォーク
293
平均マージ
34分
マージ済み PR(30日)
1

説明

Describe the bug
Similar to previous issues about multiple content types support like https://github.com/openapi-generators/openapi-python-client/issues/453 or https://github.com/openapi-generators/openapi-python-client/issues/1004

For a single endpoint, the same error code can be returned by different piece of software. For example, an application can return error details as application/json but have some infra elements in front (cloud gateway/load balancer/reverse proxy/firewall) that can block request and also return their own errors in their own format text/json/xml (usually for network errors 401,403,502,503,504).

In my use case, I realized a firewall can sometimes block requests and returns a text/plain with a string Access Forbidden. So I'm trying to represent that in my OpenAPI spec so the generated client can handle these errors properly without crashing, and this works for some of the other openapi generators. But it doesn't work well with this python client, because the content type is not validated in the generated code. It only depends on the first content declared in the schema and seems to ignore the other ones.

So I'm getting the following implementation:

if response.status_code == 403:
  response_403 = APIError.from_dict(response.json())

Which works for json error, but json parsing throw an exception if it's something else (like text/plain)

And if I declare text/plain before application/json, I get:

if response.status_code == 403:
  response_403 = response.text

But in that case, I'm losing any detail about the json error.

What I expect here, is something similar to the oapi-codegen golang implementation.
If there are multiple content types defined for an error code, check that the response content type match before handling it.
So each content type can coexist and be handled separately.

case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403:
    // this is a json error
    var dest APIError
    if err := json.Unmarshal(bodyBytes, &dest); err != nil {
      return nil, err
    }
    response.JSON403 = &dest
case rsp.StatusCode == 403:    
    ... // default case for text/plain error

OpenAPI Spec File

403:
  description: Forbidden
  content:
    application/json:
      schema:
        $ref: '#/components/schemas/APIError'
    text/plain:
      schema:
        type: string

Desktop (please complete the following information):

  • OS: macOS 14.7.4
  • Python Version: 3.11.88
  • openapi-python-client version: 0.24.3

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

application/json と text/plain を持つ、提供された OpenAPI 403 レスポンスを使用して、生成されたクライアントの現在の処理を再現してください。生成されたクライアントのエラーレスポンスのパスを調べ、利用可能であれば、関連するクライアント生成とレスポンステストを実行してください。完了の条件は、生成されたクライアントがレスポンスの Content-Type に基づいて処理を選択し、text/plain を JSON として解析しようとせずに JSON の詳細を利用できることです。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
api
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
45/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。