'FastAPI OAuth2PasswordRequestForm dependency causing request failure

I'm using the auth scheme detailed in FastAPI's user guide (JWT/Bearer token). When I try to get a token from the /token endpoint the request fails before the path operation function ever runs. Here's the function in question:

async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends(), session: SessionLocal = Depends(get_db)):
    user = authenticate_user(session, form_data.username, form_data.password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    access_token = create_access_token(data={"sub": user.id})
    return {"access_token": access_token, "token_type": "bearer"}

I normally use breakpoints to help figure out what's going wrong in these situations, but the call fails before any code in the function actually runs, leading me to believe the problem is with the OAuth2PasswordRequestForm dependency. I verified that this was the problem by disabling the form_data parameter and was able to execute the full request.

The errors I'm getting are pretty sparse on details. Here's what I'm getting in the console: INFO: 127.0.0.1:52261 - "POST /token HTTP/1.1" 400 Bad Request

And here's what I see in the Swagger UI:

enter image description here

This was working for me in the single-file format used in the tutorial, but I've since broken things out into different files to keep my larger project organized. I have a feeling that I just missed something somewhere along the line while reorganizing this code but can't seem to figure out what is causing this.



Solution 1:[1]

Of course the solution to this issue was in the docs. The problem was that I was missing the python-multipart dependency. I just ran pip install python-multipart and restarted my server and then I was able to authenticate.

Solution 2:[2]

You need to set response_model to token after you have created a token schema like this:

class Token(BaseModel):
    access_token: str
    token_type: str

so your code should look like this

@router.post('/token', response_body=Token)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Santosh Kumar
Solution 2 Tosin Iyiola