from fastapi import routing
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
-from fastapi.openapi.utils import get_openapi
from fastapi.openapi.models import AdditionalResponse, AdditionalResponseDescription
+from fastapi.openapi.utils import get_openapi
from pydantic import BaseModel
from starlette.applications import Starlette
from starlette.exceptions import ExceptionMiddleware, HTTPException
self.add_exception_handler(HTTPException, http_exception)
def add_api_route(
- self,
- path: str,
- endpoint: Callable,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- methods: List[str] = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ endpoint: Callable,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ methods: List[str] = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> None:
self.router.add_api_route(
path,
)
def api_route(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- methods: List[str] = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ methods: List[str] = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
def decorator(func: Callable) -> Callable:
self.router.add_api_route(
return decorator
def include_router(
- self,
- router: routing.APIRouter,
- *,
- prefix: str = "",
- tags: List[str] = None,
- additional_responses: List[AdditionalResponse] = [],
+ self,
+ router: routing.APIRouter,
+ *,
+ prefix: str = "",
+ tags: List[str] = None,
+ additional_responses: List[AdditionalResponse] = [],
) -> None:
- self.router.include_router(router, prefix=prefix, tags=tags, additional_responses=additional_responses,)
+ self.router.include_router(
+ router, prefix=prefix, tags=tags, additional_responses=additional_responses
+ )
def get(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
return self.router.get(
path,
)
def put(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
return self.router.put(
path,
)
def post(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
return self.router.post(
path,
)
def delete(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
return self.router.delete(
path,
)
def options(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
return self.router.options(
path,
)
def head(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
return self.router.head(
path,
)
def patch(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
return self.router.patch(
path,
)
def trace(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
return self.router.trace(
path,
import logging
from enum import Enum
-from typing import Any, Dict, List, Optional, Union, Type, ClassVar, Callable
+from typing import Any, Callable, ClassVar, Dict, List, Optional, Type, Union
from pydantic import BaseModel, Schema as PSchema
-from pydantic.types import UrlStr
from pydantic.fields import Field
+from pydantic.types import UrlStr
try:
import email_validator
class AdditionalResponse(BaseAdditionalResponse):
status_code: int = PSchema(
- ...,
- ge=100,
- le=540,
- title='Status Code',
- description='HTTP status code',
+ ..., ge=100, le=540, title="Status Code", description="HTTP status code"
)
# 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: Optional[List[Any]] = PSchema([], title="Additional Response Models")
class AdditionalResponseDescription(BaseAdditionalResponse):
}
for add_response_code, add_response in route.additional_responses.items():
add_response_schema = {}
- if (add_response.content_type or route.content_type.media_type
- ) == 'application/json' and add_response.schema_field is not None:
+ if (
+ add_response.content_type or route.content_type.media_type
+ ) == "application/json" and add_response.schema_field is not None:
add_response_schema, _ = field_schema(
add_response.schema_field,
model_name_map=model_name_map,
ref_prefix=REF_PREFIX,
)
add_content = {
- add_response.content_type or
- route.content_type.media_type: {
- "schema": add_response_schema,
- },
+ add_response.content_type
+ or route.content_type.media_type: {"schema": add_response_schema}
+ }
+ operation["responses"][str(add_response_code)] = {
+ "description": add_response.description,
+ "content": add_content,
}
- operation["responses"][str(add_response_code)] = \
- {
- "description": add_response.description,
- "content": add_content,
- }
path[method.lower()] = operation
return path, security_schemes, definitions
import asyncio
import inspect
import logging
-from typing import Any, Callable, List, Optional, Type, Dict, Union
+from typing import Any, Callable, Dict, List, Optional, Type, Union
from fastapi import params
from fastapi.dependencies.models import Dependant
from fastapi.dependencies.utils import get_body_field, get_dependant, solve_dependencies
from fastapi.encoders import jsonable_encoder
-from fastapi.utils import UnconstrainedConfig
from fastapi.openapi.models import AdditionalResponse, AdditionalResponseDescription
+from fastapi.utils import UnconstrainedConfig
from pydantic import BaseModel, Schema
from pydantic.error_wrappers import ErrorWrapper, ValidationError
from pydantic.fields import Field
for add_response in additional_responses:
if isinstance(add_response, int):
continue
- assert add_response.status_code not in existed_codes, f"(Duplicated Status Code): Response with status code [{add_response.status_code}] already defined!"
+ 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
- ]
+ 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
- ])
+ valid_response_models = all(
+ [issubclass(m, BaseModel) for m in response_models]
+ )
except TypeError as te:
valid_response_models = False
if not valid_response_models:
raise ValueError(
"All response models must be "
"a subclass of `pydantic.BaseModel` "
- "model.",
+ "model."
)
- if (add_response.content_type == 'application/json' or lenient_issubclass(
- content_type, JSONResponse)):
+ if add_response.content_type == "application/json" or lenient_issubclass(
+ content_type, JSONResponse
+ ):
if len(response_models):
schema_field = Field(
- name=f'Additional_response_{add_response.status_code}',
+ name=f"Additional_response_{add_response.status_code}",
type_=Union[tuple(response_models)],
class_validators=[],
default=None,
description=add_response.description,
content_type=add_response.content_type,
schema_field=schema_field,
- )
- self.additional_responses[add_response.status_code] = \
- add_resp_description
+ )
+ self.additional_responses[add_response.status_code] = add_resp_description
self.deprecated = deprecated
if methods is None:
methods = ["GET"]
class APIRouter(routing.Router):
def add_api_route(
- self,
- path: str,
- endpoint: Callable,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- methods: List[str] = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ endpoint: Callable,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ methods: List[str] = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> None:
route = APIRoute(
path,
self.routes.append(route)
def api_route(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- methods: List[str] = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ methods: List[str] = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
def decorator(func: Callable) -> Callable:
self.add_api_route(
return decorator
def include_router(
- self,
- router: "APIRouter",
- *,
- prefix: str = "",
- tags: List[str] = None,
- additional_responses: List[AdditionalResponse] = [],
+ self,
+ router: "APIRouter",
+ *,
+ prefix: str = "",
+ tags: List[str] = None,
+ additional_responses: List[AdditionalResponse] = [],
) -> None:
if prefix:
assert prefix.startswith("/"), "A path prefix must start with '/'"
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()]
+ 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!"
+ 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
- ]
+ 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
- ])
+ 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:
"a subclass of `pydantic.BaseModel`"
"model."
)
- if (add_response.content_type == 'application/json' or lenient_issubclass(
- route.content_type, JSONResponse)):
+ 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}',
+ name=f"Additional_response_{add_response.status_code}",
type_=Union[tuple(response_models)],
class_validators=[],
default=None,
description=add_response.description,
content_type=add_response.content_type,
schema_field=schema_field,
- )
- route.additional_responses[add_response.status_code] = \
- add_resp_description
+ )
+ route.additional_responses[
+ add_response.status_code
+ ] = add_resp_description
self.add_api_route(
prefix + route.path,
route.endpoint,
)
def get(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
return self.api_route(
path=path,
)
def put(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
return self.api_route(
path=path,
)
def post(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
return self.api_route(
path=path,
)
def delete(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
return self.api_route(
path=path,
)
def options(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
return self.api_route(
path=path,
)
def head(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
return self.api_route(
path=path,
)
def patch(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
return self.api_route(
path=path,
)
def trace(
- self,
- path: str,
- *,
- response_model: Type[BaseModel] = None,
- status_code: int = 200,
- tags: List[str] = None,
- summary: str = None,
- description: str = None,
- response_description: str = "Successful Response",
- additional_responses: List[AdditionalResponse] = [],
- deprecated: bool = None,
- operation_id: str = None,
- include_in_schema: bool = True,
- content_type: Type[Response] = JSONResponse,
- name: str = None,
+ self,
+ path: str,
+ *,
+ response_model: Type[BaseModel] = None,
+ status_code: int = 200,
+ tags: List[str] = None,
+ summary: str = None,
+ description: str = None,
+ response_description: str = "Successful Response",
+ additional_responses: List[AdditionalResponse] = [],
+ deprecated: bool = None,
+ operation_id: str = None,
+ include_in_schema: bool = True,
+ content_type: Type[Response] = JSONResponse,
+ name: str = None,
) -> Callable:
return self.api_route(
path=path,
if route.additional_responses:
for _, add_response in route.additional_responses.items():
if add_response.schema_field is not None:
- responses_from_routes.append(
- add_response.schema_field,
- )
+ responses_from_routes.append(add_response.schema_field)
flat_models = get_flat_models_from_fields(
body_fields_from_routes + responses_from_routes
)
class Response400(BaseModel):
- '''HTTP 4xx Response Schema'''
+ """HTTP 4xx Response Schema"""
+
title: str
detail: str
- error_code: int # functional error ref
+ error_code: int # functional error ref
response_403 = AdditionalResponse(
- status_code = 403,
- description = 'Forbidden',
- models = [
- Response400,
- ],
+ status_code=403, description="Forbidden", models=[Response400]
)
-additional_responses = [
- response_403,
-]
+additional_responses = [response_403]
+
@app.api_route(
- "/items/{item_id}",
- methods=["GET"],
- additional_responses=additional_responses,
+ "/items/{item_id}", methods=["GET"], additional_responses=additional_responses
)
def get_items(item_id: str):
return {"item_id": item_id}
)
-@app.delete(
- "/items/{item_id}",
- additional_responses=additional_responses,
-)
+@app.delete("/items/{item_id}", additional_responses=additional_responses)
def delete_item(item_id: str, item: Item):
return {"item_id": item_id, "item": item}
-@app.head(
- "/items/{item_id}",
- additional_responses=additional_responses,
-)
+@app.head("/items/{item_id}", additional_responses=additional_responses)
def head_item(item_id: str):
return JSONResponse(headers={"x-fastapi-item-id": item_id})
-@app.options(
- "/items/{item_id}",
- additional_responses=additional_responses,
-)
+@app.options("/items/{item_id}", additional_responses=additional_responses)
def options_item(item_id: str):
return JSONResponse(headers={"x-fastapi-item-id": item_id})
-@app.patch(
- "/items/{item_id}",
- additional_responses=additional_responses,
-)
+@app.patch("/items/{item_id}", additional_responses=additional_responses)
def patch_item(item_id: str, item: Item):
return {"item_id": item_id, "item": item}
-@app.trace(
- "/items/{item_id}",
- additional_responses=additional_responses,
-)
+@app.trace("/items/{item_id}", additional_responses=additional_responses)
def trace_item(item_id: str):
return JSONResponse(media_type="message/http")
openapi_schema = {
"openapi": "3.0.2",
- "info": {
- "title": "Fast API",
- "version": "0.1.0"
- },
+ "info": {"title": "Fast API", "version": "0.1.0"},
"paths": {
"/items/{item_id}": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {}
- }
- },
+ "content": {"application/json": {"schema": {}}},
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Response400"
- }
+ "schema": {"$ref": "#/components/schemas/Response400"}
}
},
},
"content": {
"application/json": {
"schema": {
- "$ref":
- "#/components/schemas/HTTPValidationError"
+ "$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
- "summary":
- "Get Items Get",
- "operationId":
- "get_items_items__item_id__get",
- "parameters": [{
- "required": True,
- "schema": {
- "title": "Item_Id",
- "type": "string"
- },
- "name": "item_id",
- "in": "path",
- }],
+ "summary": "Get Items Get",
+ "operationId": "get_items_items__item_id__get",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Item_Id", "type": "string"},
+ "name": "item_id",
+ "in": "path",
+ }
+ ],
},
"delete": {
"responses": {
"200": {
"description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {}
- }
- },
+ "content": {"application/json": {"schema": {}}},
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Response400"
- }
+ "schema": {"$ref": "#/components/schemas/Response400"}
}
},
},
"content": {
"application/json": {
"schema": {
- "$ref":
- "#/components/schemas/HTTPValidationError"
+ "$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
- "summary":
- "Delete Item Delete",
- "operationId":
- "delete_item_items__item_id__delete",
- "parameters": [{
- "required": True,
- "schema": {
- "title": "Item_Id",
- "type": "string"
- },
- "name": "item_id",
- "in": "path",
- }],
+ "summary": "Delete Item Delete",
+ "operationId": "delete_item_items__item_id__delete",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Item_Id", "type": "string"},
+ "name": "item_id",
+ "in": "path",
+ }
+ ],
"requestBody": {
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Item"
- }
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
"required": True,
"responses": {
"200": {
"description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {}
- }
- },
+ "content": {"application/json": {"schema": {}}},
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Response400"
- }
+ "schema": {"$ref": "#/components/schemas/Response400"}
}
},
},
"description": "Forbidden",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Response400"
- }
+ "schema": {"$ref": "#/components/schemas/Response400"}
}
},
},
"content": {
"application/json": {
"schema": {
- "$ref":
- "#/components/schemas/HTTPValidationError"
+ "$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
- "summary":
- "Options Item Options",
- "operationId":
- "options_item_items__item_id__options",
- "parameters": [{
- "required": True,
- "schema": {
- "title": "Item_Id",
- "type": "string"
- },
- "name": "item_id",
- "in": "path",
- }],
+ "summary": "Options Item Options",
+ "operationId": "options_item_items__item_id__options",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Item_Id", "type": "string"},
+ "name": "item_id",
+ "in": "path",
+ }
+ ],
},
"head": {
"responses": {
"200": {
"description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {}
- }
- },
+ "content": {"application/json": {"schema": {}}},
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Response400"
- }
+ "schema": {"$ref": "#/components/schemas/Response400"}
}
},
},
"content": {
"application/json": {
"schema": {
- "$ref":
- "#/components/schemas/HTTPValidationError"
+ "$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
- "summary":
- "Head Item Head",
- "operationId":
- "head_item_items__item_id__head",
- "parameters": [{
- "required": True,
- "schema": {
- "title": "Item_Id",
- "type": "string"
- },
- "name": "item_id",
- "in": "path",
- }],
+ "summary": "Head Item Head",
+ "operationId": "head_item_items__item_id__head",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Item_Id", "type": "string"},
+ "name": "item_id",
+ "in": "path",
+ }
+ ],
},
"patch": {
"responses": {
"200": {
"description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {}
- }
- },
+ "content": {"application/json": {"schema": {}}},
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Response400"
- }
+ "schema": {"$ref": "#/components/schemas/Response400"}
}
},
},
"content": {
"application/json": {
"schema": {
- "$ref":
- "#/components/schemas/HTTPValidationError"
+ "$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
- "summary":
- "Patch Item Patch",
- "operationId":
- "patch_item_items__item_id__patch",
- "parameters": [{
- "required": True,
- "schema": {
- "title": "Item_Id",
- "type": "string"
- },
- "name": "item_id",
- "in": "path",
- }],
+ "summary": "Patch Item Patch",
+ "operationId": "patch_item_items__item_id__patch",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Item_Id", "type": "string"},
+ "name": "item_id",
+ "in": "path",
+ }
+ ],
"requestBody": {
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Item"
- }
+ "schema": {"$ref": "#/components/schemas/Item"}
}
},
"required": True,
"responses": {
"200": {
"description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {}
- }
- },
+ "content": {"application/json": {"schema": {}}},
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Response400"
- }
+ "schema": {"$ref": "#/components/schemas/Response400"}
}
},
},
"content": {
"application/json": {
"schema": {
- "$ref":
- "#/components/schemas/HTTPValidationError"
+ "$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
- "summary":
- "Trace Item Trace",
- "operationId":
- "trace_item_items__item_id__trace",
- "parameters": [{
- "required": True,
- "schema": {
- "title": "Item_Id",
- "type": "string"
- },
- "name": "item_id",
- "in": "path",
- }],
+ "summary": "Trace Item Trace",
+ "operationId": "trace_item_items__item_id__trace",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Item_Id", "type": "string"},
+ "name": "item_id",
+ "in": "path",
+ }
+ ],
},
},
"/items-not-decorated/{item_id}": {
"responses": {
"200": {
"description": "Successful Response",
- "content": {
- "application/json": {
- "schema": {}
- }
- },
+ "content": {"application/json": {"schema": {}}},
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
- "schema": {
- "$ref": "#/components/schemas/Response400"
- }
+ "schema": {"$ref": "#/components/schemas/Response400"}
}
},
},
"content": {
"application/json": {
"schema": {
- "$ref":
- "#/components/schemas/HTTPValidationError"
+ "$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
- "summary":
- "Get Not Decorated Get",
- "operationId":
- "get_not_decorated_items-not-decorated__item_id__get",
- "parameters": [{
- "required": True,
- "schema": {
- "title": "Item_Id",
- "type": "string"
- },
- "name": "item_id",
- "in": "path",
- }],
+ "summary": "Get Not Decorated Get",
+ "operationId": "get_not_decorated_items-not-decorated__item_id__get",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Item_Id", "type": "string"},
+ "name": "item_id",
+ "in": "path",
+ }
+ ],
}
},
},
"required": ["name"],
"type": "object",
"properties": {
- "name": {
- "title": "Name",
- "type": "string"
- },
- "price": {
- "title": "Price",
- "type": "number"
- },
+ "name": {"title": "Name", "type": "string"},
+ "price": {"title": "Price", "type": "number"},
},
},
"Response400": {
"required": ["title", "detail", "error_code"],
"type": "object",
"properties": {
- "title": {
- "title": "Title",
- "type": "string"
- },
- "detail": {
- "title": "Detail",
- "type": "string"
- },
- "error_code": {
- "title": "Error_Code",
- "type": "integer"
- },
+ "title": {"title": "Title", "type": "string"},
+ "detail": {"title": "Detail", "type": "string"},
+ "error_code": {"title": "Error_Code", "type": "integer"},
},
},
"ValidationError": {
"loc": {
"title": "Location",
"type": "array",
- "items": {
- "type": "string"
- },
- },
- "msg": {
- "title": "Message",
- "type": "string"
- },
- "type": {
- "title": "Error Type",
- "type": "string"
+ "items": {"type": "string"},
},
+ "msg": {"title": "Message", "type": "string"},
+ "type": {"title": "Error Type", "type": "string"},
},
},
"HTTPValidationError": {
"detail": {
"title": "Detail",
"type": "array",
- "items": {
- "$ref": "#/components/schemas/ValidationError"
- },
+ "items": {"$ref": "#/components/schemas/ValidationError"},
}
},
},
def test_delete():
response = client.delete("/items/foo", json={"name": "Foo"})
assert response.status_code == 200
- assert response.json() == {
- "item_id": "foo",
- "item": {
- "name": "Foo",
- "price": None
- }
- }
+ assert response.json() == {"item_id": "foo", "item": {"name": "Foo", "price": None}}
def test_head():
def test_patch():
response = client.patch("/items/foo", json={"name": "Foo"})
assert response.status_code == 200
- assert response.json() == {
- "item_id": "foo",
- "item": {
- "name": "Foo",
- "price": None
- }
- }
+ assert response.json() == {"item_id": "foo", "item": {"name": "Foo", "price": None}}
def test_trace():