luolingchun / flask-openapi3

Generate REST API and OpenAPI documentation for your Flask project.
https://luolingchun.github.io/flask-openapi3/
MIT License
205 stars 34 forks source link

Apply multi responses to one HttpStatus or apply arbitrary str as responses key #136

Open p3rs1st opened 10 months ago

p3rs1st commented 10 months ago

In current flask-openapi3, I can only map 200 to Resp, 201: Resp1.

app = OpenAPI(__name__)

class Resp(BaseModel):
  a: int

class Resp1(BaseModel):
  b: int

@app.get("/", responses={200: Resp, 201: Resp1})
def book():
  pass

But I want to map all of these to one HttpStatus, because they are both HttpStatus 200. like

responses = {200: [Resp, Resp1]}

Or allow the key of responses can be arbitrary str like

responses = {"success": Resp, "success1": Resp1}
luolingchun commented 10 months ago

You can do this:

https://docs.pydantic.dev/latest/concepts/models/#rootmodel-and-custom-root-types

from pydantic import RootModel

class Resp(BaseModel):
  a: int

class Resp1(BaseModel):
  b: int

class UnionRespResp2(RootModel):
    root:Union[Resp, Resp1]

@app.get("/", responses={200: UnionRespResp2})
def book():
  pass
p3rs1st commented 10 months ago

Thanks, now I can see the schema of the responses, but I want the example value to be shown both of them.

image

However, I can only see one of the example value like

image

If I want to see the both example value of the responses, how should I do?

luolingchun commented 10 months ago

When you don't have a configuration example, the Swagger UI automatically generates one. You can do this by configuring openapi_extra fields in the model_config.

from typing import Union

from pydantic import BaseModel, RootModel

from flask_openapi3 import OpenAPI

app = OpenAPI(__name__)

class Resp(BaseModel):
    a: str

class Resp1(BaseModel):
    b: int

class UnionRespResp2(RootModel):
    root: Union[Resp, Resp1]

    model_config = {
        "openapi_extra": {
            "examples": {
                "Success Example": {
                    "summary": "Success Example",
                    "value": {
                        "a": "sss"
                    }
                },
                "Fail Example": {
                    "summary": "Fail Example",
                    "value": {
                        "b": -1
                    }
                }
            }
        }
    }

@app.get("/", responses={200: UnionRespResp2})
def book():
    return "ok"

if __name__ == "__main__":
    app.run(debug=True)

image