from typing import Union

import pytest
from fastapi import FastAPI
from fastapi.exceptions import FastAPIError, ResponseValidationError
from fastapi.responses import JSONResponse, Response
from fastapi.testclient import TestClient
from pydantic import BaseModel


class BaseUser(BaseModel):
    name: str


class User(BaseUser):
    surname: str


class DBUser(User):
    password_hash: str


class Item(BaseModel):
    name: str
    price: float


app = FastAPI()


@app.get("/no_response_model-no_annotation-return_model")
def no_response_model_no_annotation_return_model():
    return User(name="John", surname="Doe")


@app.get("/no_response_model-no_annotation-return_dict")
def no_response_model_no_annotation_return_dict():
    return {"name": "John", "surname": "Doe"}


@app.get("/response_model-no_annotation-return_same_model", response_model=User)
def response_model_no_annotation_return_same_model():
    return User(name="John", surname="Doe")


@app.get("/response_model-no_annotation-return_exact_dict", response_model=User)
def response_model_no_annotation_return_exact_dict():
    return {"name": "John", "surname": "Doe"}


@app.get("/response_model-no_annotation-return_invalid_dict", response_model=User)
def response_model_no_annotation_return_invalid_dict():
    return {"name": "John"}


@app.get("/response_model-no_annotation-return_invalid_model", response_model=User)
def response_model_no_annotation_return_invalid_model():
    return Item(name="Foo", price=42.0)


@app.get(
    "/response_model-no_annotation-return_dict_with_extra_data", response_model=User
)
def response_model_no_annotation_return_dict_with_extra_data():
    return {"name": "John", "surname": "Doe", "password_hash": "secret"}


@app.get(
    "/response_model-no_annotation-return_submodel_with_extra_data", response_model=User
)
def response_model_no_annotation_return_submodel_with_extra_data():
    return DBUser(name="John", surname="Doe", password_hash="secret")


@app.get("/no_response_model-annotation-return_same_model")
def no_response_model_annotation_return_same_model() -> User:
    return User(name="John", surname="Doe")


@app.get("/no_response_model-annotation-return_exact_dict")
def no_response_model_annotation_return_exact_dict() -> User:
    return {"name": "John", "surname": "Doe"}


@app.get("/no_response_model-annotation-return_invalid_dict")
def no_response_model_annotation_return_invalid_dict() -> User:
    return {"name": "John"}


@app.get("/no_response_model-annotation-return_invalid_model")
def no_response_model_annotation_return_invalid_model() -> User:
    return Item(name="Foo", price=42.0)


@app.get("/no_response_model-annotation-return_dict_with_extra_data")
def no_response_model_annotation_return_dict_with_extra_data() -> User:
    return {"name": "John", "surname": "Doe", "password_hash": "secret"}


@app.get("/no_response_model-annotation-return_submodel_with_extra_data")
def no_response_model_annotation_return_submodel_with_extra_data() -> User:
    return DBUser(name="John", surname="Doe", password_hash="secret")


@app.get("/response_model_none-annotation-return_same_model", response_model=None)
def response_model_none_annotation_return_same_model() -> User:
    return User(name="John", surname="Doe")


@app.get("/response_model_none-annotation-return_exact_dict", response_model=None)
def response_model_none_annotation_return_exact_dict() -> User:
    return {"name": "John", "surname": "Doe"}


@app.get("/response_model_none-annotation-return_invalid_dict", response_model=None)
def response_model_none_annotation_return_invalid_dict() -> User:
    return {"name": "John"}


@app.get("/response_model_none-annotation-return_invalid_model", response_model=None)
def response_model_none_annotation_return_invalid_model() -> User:
    return Item(name="Foo", price=42.0)


@app.get(
    "/response_model_none-annotation-return_dict_with_extra_data", response_model=None
)
def response_model_none_annotation_return_dict_with_extra_data() -> User:
    return {"name": "John", "surname": "Doe", "password_hash": "secret"}


@app.get(
    "/response_model_none-annotation-return_submodel_with_extra_data",
    response_model=None,
)
def response_model_none_annotation_return_submodel_with_extra_data() -> User:
    return DBUser(name="John", surname="Doe", password_hash="secret")


@app.get(
    "/response_model_model1-annotation_model2-return_same_model", response_model=User
)
def response_model_model1_annotation_model2_return_same_model() -> Item:
    return User(name="John", surname="Doe")


@app.get(
    "/response_model_model1-annotation_model2-return_exact_dict", response_model=User
)
def response_model_model1_annotation_model2_return_exact_dict() -> Item:
    return {"name": "John", "surname": "Doe"}


@app.get(
    "/response_model_model1-annotation_model2-return_invalid_dict", response_model=User
)
def response_model_model1_annotation_model2_return_invalid_dict() -> Item:
    return {"name": "John"}


@app.get(
    "/response_model_model1-annotation_model2-return_invalid_model", response_model=User
)
def response_model_model1_annotation_model2_return_invalid_model() -> Item:
    return Item(name="Foo", price=42.0)


@app.get(
    "/response_model_model1-annotation_model2-return_dict_with_extra_data",
    response_model=User,
)
def response_model_model1_annotation_model2_return_dict_with_extra_data() -> Item:
    return {"name": "John", "surname": "Doe", "password_hash": "secret"}


@app.get(
    "/response_model_model1-annotation_model2-return_submodel_with_extra_data",
    response_model=User,
)
def response_model_model1_annotation_model2_return_submodel_with_extra_data() -> Item:
    return DBUser(name="John", surname="Doe", password_hash="secret")


@app.get(
    "/response_model_filtering_model-annotation_submodel-return_submodel",
    response_model=User,
)
def response_model_filtering_model_annotation_submodel_return_submodel() -> DBUser:
    return DBUser(name="John", surname="Doe", password_hash="secret")


@app.get("/response_model_list_of_model-no_annotation", response_model=list[User])
def response_model_list_of_model_no_annotation():
    return [
        DBUser(name="John", surname="Doe", password_hash="secret"),
        DBUser(name="Jane", surname="Does", password_hash="secret2"),
    ]


@app.get("/no_response_model-annotation_list_of_model")
def no_response_model_annotation_list_of_model() -> list[User]:
    return [
        DBUser(name="John", surname="Doe", password_hash="secret"),
        DBUser(name="Jane", surname="Does", password_hash="secret2"),
    ]


@app.get("/no_response_model-annotation_forward_ref_list_of_model")
def no_response_model_annotation_forward_ref_list_of_model() -> "list[User]":
    return [
        DBUser(name="John", surname="Doe", password_hash="secret"),
        DBUser(name="Jane", surname="Does", password_hash="secret2"),
    ]


@app.get(
    "/response_model_union-no_annotation-return_model1",
    response_model=Union[User, Item],
)
def response_model_union_no_annotation_return_model1():
    return DBUser(name="John", surname="Doe", password_hash="secret")


@app.get(
    "/response_model_union-no_annotation-return_model2",
    response_model=Union[User, Item],
)
def response_model_union_no_annotation_return_model2():
    return Item(name="Foo", price=42.0)


@app.get("/no_response_model-annotation_union-return_model1")
def no_response_model_annotation_union_return_model1() -> Union[User, Item]:
    return DBUser(name="John", surname="Doe", password_hash="secret")


@app.get("/no_response_model-annotation_union-return_model2")
def no_response_model_annotation_union_return_model2() -> Union[User, Item]:
    return Item(name="Foo", price=42.0)


@app.get("/no_response_model-annotation_response_class")
def no_response_model_annotation_response_class() -> Response:
    return Response(content="Foo")


@app.get("/no_response_model-annotation_json_response_class")
def no_response_model_annotation_json_response_class() -> JSONResponse:
    return JSONResponse(content={"foo": "bar"})


client = TestClient(app)


def test_no_response_model_no_annotation_return_model():
    response = client.get("/no_response_model-no_annotation-return_model")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_no_response_model_no_annotation_return_dict():
    response = client.get("/no_response_model-no_annotation-return_dict")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_response_model_no_annotation_return_same_model():
    response = client.get("/response_model-no_annotation-return_same_model")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_response_model_no_annotation_return_exact_dict():
    response = client.get("/response_model-no_annotation-return_exact_dict")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_response_model_no_annotation_return_invalid_dict():
    with pytest.raises(ResponseValidationError) as excinfo:
        client.get("/response_model-no_annotation-return_invalid_dict")
    assert "missing" in str(excinfo.value)


def test_response_model_no_annotation_return_invalid_model():
    with pytest.raises(ResponseValidationError) as excinfo:
        client.get("/response_model-no_annotation-return_invalid_model")
    assert "missing" in str(excinfo.value)


def test_response_model_no_annotation_return_dict_with_extra_data():
    response = client.get("/response_model-no_annotation-return_dict_with_extra_data")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_response_model_no_annotation_return_submodel_with_extra_data():
    response = client.get(
        "/response_model-no_annotation-return_submodel_with_extra_data"
    )
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_no_response_model_annotation_return_same_model():
    response = client.get("/no_response_model-annotation-return_same_model")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_no_response_model_annotation_return_exact_dict():
    response = client.get("/no_response_model-annotation-return_exact_dict")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_no_response_model_annotation_return_invalid_dict():
    with pytest.raises(ResponseValidationError) as excinfo:
        client.get("/no_response_model-annotation-return_invalid_dict")
    assert "missing" in str(excinfo.value)


def test_no_response_model_annotation_return_invalid_model():
    with pytest.raises(ResponseValidationError) as excinfo:
        client.get("/no_response_model-annotation-return_invalid_model")
    assert "missing" in str(excinfo.value)


def test_no_response_model_annotation_return_dict_with_extra_data():
    response = client.get("/no_response_model-annotation-return_dict_with_extra_data")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_no_response_model_annotation_return_submodel_with_extra_data():
    response = client.get(
        "/no_response_model-annotation-return_submodel_with_extra_data"
    )
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_response_model_none_annotation_return_same_model():
    response = client.get("/response_model_none-annotation-return_same_model")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_response_model_none_annotation_return_exact_dict():
    response = client.get("/response_model_none-annotation-return_exact_dict")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_response_model_none_annotation_return_invalid_dict():
    response = client.get("/response_model_none-annotation-return_invalid_dict")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John"}


def test_response_model_none_annotation_return_invalid_model():
    response = client.get("/response_model_none-annotation-return_invalid_model")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "Foo", "price": 42.0}


def test_response_model_none_annotation_return_dict_with_extra_data():
    response = client.get("/response_model_none-annotation-return_dict_with_extra_data")
    assert response.status_code == 200, response.text
    assert response.json() == {
        "name": "John",
        "surname": "Doe",
        "password_hash": "secret",
    }


def test_response_model_none_annotation_return_submodel_with_extra_data():
    response = client.get(
        "/response_model_none-annotation-return_submodel_with_extra_data"
    )
    assert response.status_code == 200, response.text
    assert response.json() == {
        "name": "John",
        "surname": "Doe",
        "password_hash": "secret",
    }


def test_response_model_model1_annotation_model2_return_same_model():
    response = client.get("/response_model_model1-annotation_model2-return_same_model")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_response_model_model1_annotation_model2_return_exact_dict():
    response = client.get("/response_model_model1-annotation_model2-return_exact_dict")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_response_model_model1_annotation_model2_return_invalid_dict():
    with pytest.raises(ResponseValidationError) as excinfo:
        client.get("/response_model_model1-annotation_model2-return_invalid_dict")
    assert "missing" in str(excinfo.value)


def test_response_model_model1_annotation_model2_return_invalid_model():
    with pytest.raises(ResponseValidationError) as excinfo:
        client.get("/response_model_model1-annotation_model2-return_invalid_model")
    assert "missing" in str(excinfo.value)


def test_response_model_model1_annotation_model2_return_dict_with_extra_data():
    response = client.get(
        "/response_model_model1-annotation_model2-return_dict_with_extra_data"
    )
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_response_model_model1_annotation_model2_return_submodel_with_extra_data():
    response = client.get(
        "/response_model_model1-annotation_model2-return_submodel_with_extra_data"
    )
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_response_model_filtering_model_annotation_submodel_return_submodel():
    response = client.get(
        "/response_model_filtering_model-annotation_submodel-return_submodel"
    )
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_response_model_list_of_model_no_annotation():
    response = client.get("/response_model_list_of_model-no_annotation")
    assert response.status_code == 200, response.text
    assert response.json() == [
        {"name": "John", "surname": "Doe"},
        {"name": "Jane", "surname": "Does"},
    ]


def test_no_response_model_annotation_list_of_model():
    response = client.get("/no_response_model-annotation_list_of_model")
    assert response.status_code == 200, response.text
    assert response.json() == [
        {"name": "John", "surname": "Doe"},
        {"name": "Jane", "surname": "Does"},
    ]


def test_no_response_model_annotation_forward_ref_list_of_model():
    response = client.get("/no_response_model-annotation_forward_ref_list_of_model")
    assert response.status_code == 200, response.text
    assert response.json() == [
        {"name": "John", "surname": "Doe"},
        {"name": "Jane", "surname": "Does"},
    ]


def test_response_model_union_no_annotation_return_model1():
    response = client.get("/response_model_union-no_annotation-return_model1")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_response_model_union_no_annotation_return_model2():
    response = client.get("/response_model_union-no_annotation-return_model2")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "Foo", "price": 42.0}


def test_no_response_model_annotation_union_return_model1():
    response = client.get("/no_response_model-annotation_union-return_model1")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "John", "surname": "Doe"}


def test_no_response_model_annotation_union_return_model2():
    response = client.get("/no_response_model-annotation_union-return_model2")
    assert response.status_code == 200, response.text
    assert response.json() == {"name": "Foo", "price": 42.0}


def test_no_response_model_annotation_return_class():
    response = client.get("/no_response_model-annotation_response_class")
    assert response.status_code == 200, response.text
    assert response.text == "Foo"


def test_no_response_model_annotation_json_response_class():
    response = client.get("/no_response_model-annotation_json_response_class")
    assert response.status_code == 200, response.text
    assert response.json() == {"foo": "bar"}


def test_invalid_response_model_field():
    app = FastAPI()
    with pytest.raises(FastAPIError) as e:

        @app.get("/")
        def read_root() -> Union[Response, None]:
            return Response(content="Foo")  # pragma: no cover

    assert "valid Pydantic field type" in e.value.args[0]
    assert "parameter response_model=None" in e.value.args[0]


def test_openapi_schema():
    response = client.get("/openapi.json")
    assert response.status_code == 200, response.text
    assert response.json() == {
        "openapi": "3.1.0",
        "info": {"title": "FastAPI", "version": "0.1.0"},
        "paths": {
            "/no_response_model-no_annotation-return_model": {
                "get": {
                    "summary": "No Response Model No Annotation Return Model",
                    "operationId": "no_response_model_no_annotation_return_model_no_response_model_no_annotation_return_model_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {"application/json": {"schema": {}}},
                        }
                    },
                }
            },
            "/no_response_model-no_annotation-return_dict": {
                "get": {
                    "summary": "No Response Model No Annotation Return Dict",
                    "operationId": "no_response_model_no_annotation_return_dict_no_response_model_no_annotation_return_dict_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {"application/json": {"schema": {}}},
                        }
                    },
                }
            },
            "/response_model-no_annotation-return_same_model": {
                "get": {
                    "summary": "Response Model No Annotation Return Same Model",
                    "operationId": "response_model_no_annotation_return_same_model_response_model_no_annotation_return_same_model_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/response_model-no_annotation-return_exact_dict": {
                "get": {
                    "summary": "Response Model No Annotation Return Exact Dict",
                    "operationId": "response_model_no_annotation_return_exact_dict_response_model_no_annotation_return_exact_dict_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/response_model-no_annotation-return_invalid_dict": {
                "get": {
                    "summary": "Response Model No Annotation Return Invalid Dict",
                    "operationId": "response_model_no_annotation_return_invalid_dict_response_model_no_annotation_return_invalid_dict_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/response_model-no_annotation-return_invalid_model": {
                "get": {
                    "summary": "Response Model No Annotation Return Invalid Model",
                    "operationId": "response_model_no_annotation_return_invalid_model_response_model_no_annotation_return_invalid_model_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/response_model-no_annotation-return_dict_with_extra_data": {
                "get": {
                    "summary": "Response Model No Annotation Return Dict With Extra Data",
                    "operationId": "response_model_no_annotation_return_dict_with_extra_data_response_model_no_annotation_return_dict_with_extra_data_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/response_model-no_annotation-return_submodel_with_extra_data": {
                "get": {
                    "summary": "Response Model No Annotation Return Submodel With Extra Data",
                    "operationId": "response_model_no_annotation_return_submodel_with_extra_data_response_model_no_annotation_return_submodel_with_extra_data_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/no_response_model-annotation-return_same_model": {
                "get": {
                    "summary": "No Response Model Annotation Return Same Model",
                    "operationId": "no_response_model_annotation_return_same_model_no_response_model_annotation_return_same_model_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/no_response_model-annotation-return_exact_dict": {
                "get": {
                    "summary": "No Response Model Annotation Return Exact Dict",
                    "operationId": "no_response_model_annotation_return_exact_dict_no_response_model_annotation_return_exact_dict_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/no_response_model-annotation-return_invalid_dict": {
                "get": {
                    "summary": "No Response Model Annotation Return Invalid Dict",
                    "operationId": "no_response_model_annotation_return_invalid_dict_no_response_model_annotation_return_invalid_dict_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/no_response_model-annotation-return_invalid_model": {
                "get": {
                    "summary": "No Response Model Annotation Return Invalid Model",
                    "operationId": "no_response_model_annotation_return_invalid_model_no_response_model_annotation_return_invalid_model_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/no_response_model-annotation-return_dict_with_extra_data": {
                "get": {
                    "summary": "No Response Model Annotation Return Dict With Extra Data",
                    "operationId": "no_response_model_annotation_return_dict_with_extra_data_no_response_model_annotation_return_dict_with_extra_data_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/no_response_model-annotation-return_submodel_with_extra_data": {
                "get": {
                    "summary": "No Response Model Annotation Return Submodel With Extra Data",
                    "operationId": "no_response_model_annotation_return_submodel_with_extra_data_no_response_model_annotation_return_submodel_with_extra_data_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/response_model_none-annotation-return_same_model": {
                "get": {
                    "summary": "Response Model None Annotation Return Same Model",
                    "operationId": "response_model_none_annotation_return_same_model_response_model_none_annotation_return_same_model_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {"application/json": {"schema": {}}},
                        }
                    },
                }
            },
            "/response_model_none-annotation-return_exact_dict": {
                "get": {
                    "summary": "Response Model None Annotation Return Exact Dict",
                    "operationId": "response_model_none_annotation_return_exact_dict_response_model_none_annotation_return_exact_dict_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {"application/json": {"schema": {}}},
                        }
                    },
                }
            },
            "/response_model_none-annotation-return_invalid_dict": {
                "get": {
                    "summary": "Response Model None Annotation Return Invalid Dict",
                    "operationId": "response_model_none_annotation_return_invalid_dict_response_model_none_annotation_return_invalid_dict_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {"application/json": {"schema": {}}},
                        }
                    },
                }
            },
            "/response_model_none-annotation-return_invalid_model": {
                "get": {
                    "summary": "Response Model None Annotation Return Invalid Model",
                    "operationId": "response_model_none_annotation_return_invalid_model_response_model_none_annotation_return_invalid_model_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {"application/json": {"schema": {}}},
                        }
                    },
                }
            },
            "/response_model_none-annotation-return_dict_with_extra_data": {
                "get": {
                    "summary": "Response Model None Annotation Return Dict With Extra Data",
                    "operationId": "response_model_none_annotation_return_dict_with_extra_data_response_model_none_annotation_return_dict_with_extra_data_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {"application/json": {"schema": {}}},
                        }
                    },
                }
            },
            "/response_model_none-annotation-return_submodel_with_extra_data": {
                "get": {
                    "summary": "Response Model None Annotation Return Submodel With Extra Data",
                    "operationId": "response_model_none_annotation_return_submodel_with_extra_data_response_model_none_annotation_return_submodel_with_extra_data_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {"application/json": {"schema": {}}},
                        }
                    },
                }
            },
            "/response_model_model1-annotation_model2-return_same_model": {
                "get": {
                    "summary": "Response Model Model1 Annotation Model2 Return Same Model",
                    "operationId": "response_model_model1_annotation_model2_return_same_model_response_model_model1_annotation_model2_return_same_model_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/response_model_model1-annotation_model2-return_exact_dict": {
                "get": {
                    "summary": "Response Model Model1 Annotation Model2 Return Exact Dict",
                    "operationId": "response_model_model1_annotation_model2_return_exact_dict_response_model_model1_annotation_model2_return_exact_dict_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/response_model_model1-annotation_model2-return_invalid_dict": {
                "get": {
                    "summary": "Response Model Model1 Annotation Model2 Return Invalid Dict",
                    "operationId": "response_model_model1_annotation_model2_return_invalid_dict_response_model_model1_annotation_model2_return_invalid_dict_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/response_model_model1-annotation_model2-return_invalid_model": {
                "get": {
                    "summary": "Response Model Model1 Annotation Model2 Return Invalid Model",
                    "operationId": "response_model_model1_annotation_model2_return_invalid_model_response_model_model1_annotation_model2_return_invalid_model_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/response_model_model1-annotation_model2-return_dict_with_extra_data": {
                "get": {
                    "summary": "Response Model Model1 Annotation Model2 Return Dict With Extra Data",
                    "operationId": "response_model_model1_annotation_model2_return_dict_with_extra_data_response_model_model1_annotation_model2_return_dict_with_extra_data_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/response_model_model1-annotation_model2-return_submodel_with_extra_data": {
                "get": {
                    "summary": "Response Model Model1 Annotation Model2 Return Submodel With Extra Data",
                    "operationId": "response_model_model1_annotation_model2_return_submodel_with_extra_data_response_model_model1_annotation_model2_return_submodel_with_extra_data_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/response_model_filtering_model-annotation_submodel-return_submodel": {
                "get": {
                    "summary": "Response Model Filtering Model Annotation Submodel Return Submodel",
                    "operationId": "response_model_filtering_model_annotation_submodel_return_submodel_response_model_filtering_model_annotation_submodel_return_submodel_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {"$ref": "#/components/schemas/User"}
                                }
                            },
                        }
                    },
                }
            },
            "/response_model_list_of_model-no_annotation": {
                "get": {
                    "summary": "Response Model List Of Model No Annotation",
                    "operationId": "response_model_list_of_model_no_annotation_response_model_list_of_model_no_annotation_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {
                                        "title": "Response Response Model List Of Model No Annotation Response Model List Of Model No Annotation Get",
                                        "type": "array",
                                        "items": {"$ref": "#/components/schemas/User"},
                                    }
                                }
                            },
                        }
                    },
                }
            },
            "/no_response_model-annotation_list_of_model": {
                "get": {
                    "summary": "No Response Model Annotation List Of Model",
                    "operationId": "no_response_model_annotation_list_of_model_no_response_model_annotation_list_of_model_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {
                                        "title": "Response No Response Model Annotation List Of Model No Response Model Annotation List Of Model Get",
                                        "type": "array",
                                        "items": {"$ref": "#/components/schemas/User"},
                                    }
                                }
                            },
                        }
                    },
                }
            },
            "/no_response_model-annotation_forward_ref_list_of_model": {
                "get": {
                    "summary": "No Response Model Annotation Forward Ref List Of Model",
                    "operationId": "no_response_model_annotation_forward_ref_list_of_model_no_response_model_annotation_forward_ref_list_of_model_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {
                                        "title": "Response No Response Model Annotation Forward Ref List Of Model No Response Model Annotation Forward Ref List Of Model Get",
                                        "type": "array",
                                        "items": {"$ref": "#/components/schemas/User"},
                                    }
                                }
                            },
                        }
                    },
                }
            },
            "/response_model_union-no_annotation-return_model1": {
                "get": {
                    "summary": "Response Model Union No Annotation Return Model1",
                    "operationId": "response_model_union_no_annotation_return_model1_response_model_union_no_annotation_return_model1_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {
                                        "title": "Response Response Model Union No Annotation Return Model1 Response Model Union No Annotation Return Model1 Get",
                                        "anyOf": [
                                            {"$ref": "#/components/schemas/User"},
                                            {"$ref": "#/components/schemas/Item"},
                                        ],
                                    }
                                }
                            },
                        }
                    },
                }
            },
            "/response_model_union-no_annotation-return_model2": {
                "get": {
                    "summary": "Response Model Union No Annotation Return Model2",
                    "operationId": "response_model_union_no_annotation_return_model2_response_model_union_no_annotation_return_model2_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {
                                        "title": "Response Response Model Union No Annotation Return Model2 Response Model Union No Annotation Return Model2 Get",
                                        "anyOf": [
                                            {"$ref": "#/components/schemas/User"},
                                            {"$ref": "#/components/schemas/Item"},
                                        ],
                                    }
                                }
                            },
                        }
                    },
                }
            },
            "/no_response_model-annotation_union-return_model1": {
                "get": {
                    "summary": "No Response Model Annotation Union Return Model1",
                    "operationId": "no_response_model_annotation_union_return_model1_no_response_model_annotation_union_return_model1_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {
                                        "title": "Response No Response Model Annotation Union Return Model1 No Response Model Annotation Union Return Model1 Get",
                                        "anyOf": [
                                            {"$ref": "#/components/schemas/User"},
                                            {"$ref": "#/components/schemas/Item"},
                                        ],
                                    }
                                }
                            },
                        }
                    },
                }
            },
            "/no_response_model-annotation_union-return_model2": {
                "get": {
                    "summary": "No Response Model Annotation Union Return Model2",
                    "operationId": "no_response_model_annotation_union_return_model2_no_response_model_annotation_union_return_model2_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {
                                "application/json": {
                                    "schema": {
                                        "title": "Response No Response Model Annotation Union Return Model2 No Response Model Annotation Union Return Model2 Get",
                                        "anyOf": [
                                            {"$ref": "#/components/schemas/User"},
                                            {"$ref": "#/components/schemas/Item"},
                                        ],
                                    }
                                }
                            },
                        }
                    },
                }
            },
            "/no_response_model-annotation_response_class": {
                "get": {
                    "summary": "No Response Model Annotation Response Class",
                    "operationId": "no_response_model_annotation_response_class_no_response_model_annotation_response_class_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {"application/json": {"schema": {}}},
                        }
                    },
                }
            },
            "/no_response_model-annotation_json_response_class": {
                "get": {
                    "summary": "No Response Model Annotation Json Response Class",
                    "operationId": "no_response_model_annotation_json_response_class_no_response_model_annotation_json_response_class_get",
                    "responses": {
                        "200": {
                            "description": "Successful Response",
                            "content": {"application/json": {"schema": {}}},
                        }
                    },
                }
            },
        },
        "components": {
            "schemas": {
                "Item": {
                    "title": "Item",
                    "required": ["name", "price"],
                    "type": "object",
                    "properties": {
                        "name": {"title": "Name", "type": "string"},
                        "price": {"title": "Price", "type": "number"},
                    },
                },
                "User": {
                    "title": "User",
                    "required": ["name", "surname"],
                    "type": "object",
                    "properties": {
                        "name": {"title": "Name", "type": "string"},
                        "surname": {"title": "Surname", "type": "string"},
                    },
                },
            }
        },
    }
