The route implemented via FastAPI (code snippet below) is working fine.
@app.post(path='/user/create/')
async def create_user(response: Response,
email: str = Form(),
password: str = Form()) -> None:
"""
Create a new user with this route.
Possible responses:
201: New User Created
400: Bad email id supplied.
409: User already signed up, hence causing conflict with existing id.
"""
logging.info(msg=f'New user sign up request from {email}.')
try:
user: WebUser = WebUser(email=email, password=password)
# Either 409 or 201
response.status_code = [CONFLICT, CREATED][await user.create_new()]
except ValidationError:
logging.error(
msg=f'User creation for {email} failed because of bad request.')
response.status_code = BAD_REQUEST # 400
But the FastAPI swagger documentation is showing incorrect (actually totally random) responses. Here is the screenshot.
So, it is not showing 409, and 400, but somehow showing 422 as a possible response. Also, the successful response is actually 201.
So how does FastAPI form these documentations behind the scene and am I doing something wrong to mislead it? Or is it a bug within FastAPI?
This is documented in the Additional Status Codes and Additional Responses in OpenAPI sections of the documentation.
If we rewrite your code like this:
import random
import logging
import pydantic
from fastapi import FastAPI, Response, Form
from fastapi.responses import JSONResponse
app = FastAPI()
class BaseModel(pydantic.BaseModel):
pass
class Message(BaseModel):
message: str
class WebUser(BaseModel):
email: str
password: str
def user_create_new(user: WebUser):
if random.randint(0, 100) > 50:
pass
else:
raise ValueError()
@app.post(
path="/user/create",
responses={400: {"model": Message}, 409: {"model": Message}},
)
async def create_user(
response: Response, email: str = Form(), password: str = Form()
) -> None:
logging.info(msg=f"New user sign up request from {email}.")
user: WebUser = WebUser(email=email, password=password)
try:
user_create_new(user)
return Message(message=f"Created user {email}")
except ValueError:
return JSONResponse(
status_code=400, content=Message(message="Unable to create user").dict()
)
Then http://localhost/openapi gets us: