diff --git a/fastapi/openapi/models.py b/fastapi/openapi/models.py index 70865548f..613285930 100644 --- a/fastapi/openapi/models.py +++ b/fastapi/openapi/models.py @@ -346,7 +346,7 @@ class Tag(BaseModel): class BaseAdditionalResponse(BaseModel): description: str - content_type: str = None + content_type: Optional[str] = None class AdditionalResponse(BaseAdditionalResponse): @@ -356,7 +356,7 @@ class AdditionalResponse(BaseAdditionalResponse): # NOTE: waiting for pydantic to allow `typing.Type[BasicModel]` type # so, going for `Any` and extra validation on # routing methods - models: Optional[List[Any]] = PSchema([], title="Additional Response Models") + models: List[Any] = PSchema([], title="Additional Response Models") class AdditionalResponseDescription(BaseAdditionalResponse): diff --git a/fastapi/openapi/utils.py b/fastapi/openapi/utils.py index a1271676f..9b0e4ed30 100644 --- a/fastapi/openapi/utils.py +++ b/fastapi/openapi/utils.py @@ -206,7 +206,7 @@ def get_openapi_path( }, } for add_response_code, add_response in route.additional_responses.items(): - add_response_schema = {} + add_response_schema: Dict[str, Any] = {} if ( add_response.content_type or route.content_type.media_type ) == "application/json" and add_response.schema_field is not None: diff --git a/fastapi/routing.py b/fastapi/routing.py index d7ef1c7f7..062df5645 100644 --- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -150,7 +150,7 @@ class APIRoute(routing.Route): add_response.status_code not in existed_codes ), f"(Duplicated Status Code): Response with status code [{add_response.status_code}] already defined!" existed_codes.append(add_response.status_code) - response_models = [m for m in add_response.models] + response_models: List[Any] = [m for m in add_response.models] valid_response_models = True try: valid_response_models = all( @@ -306,56 +306,6 @@ class APIRouter(routing.Router): ), "A path prefix must not end with '/', as the routes will start with '/'" for route in router.routes: if isinstance(route, APIRoute): - # really ugly hack and repitition - prev_add_resp = route.additional_responses - existed_codes = [422, route.status_code] + [ - int(c) for c in prev_add_resp.keys() - ] - for add_response in additional_responses: - assert ( - add_response.status_code not in existed_codes - ), f"(Duplicated Status Code): Response with status code [{add_response.status_code}] already defined!" - existed_codes.append(add_response.status_code) - response_models = [m for m in add_response.models] - valid_response_models = True - try: - valid_response_models = all( - [issubclass(m, BaseModel) for m in response_models] - ) - except AttributeError as ae: - valid_response_models = False - if not valid_response_models: - raise ValueError( - "All response models must be" - "a subclass of `pydantic.BaseModel`" - "model." - ) - if ( - add_response.content_type == "application/json" - or lenient_issubclass(route.content_type, JSONResponse) - ): - if len(response_models): - schema_field = Field( - name=f"Additional_response_{add_response.status_code}", - type_=Union[tuple(response_models)], - class_validators=[], - default=None, - required=False, - model_config=UnconstrainedConfig, - schema=Schema(None), - ) - else: - schema_field = None - else: - schema_field = None - add_resp_description = AdditionalResponseDescription( - description=add_response.description, - content_type=add_response.content_type, - schema_field=schema_field, - ) - route.additional_responses[ - add_response.status_code - ] = add_resp_description self.add_api_route( prefix + route.path, route.endpoint, @@ -365,7 +315,7 @@ class APIRouter(routing.Router): summary=route.summary, description=route.description, response_description=route.response_description, - additional_responses=route.additional_responses, + additional_responses=additional_responses, deprecated=route.deprecated, methods=route.methods, operation_id=route.operation_id,