Issue
I am working on user login via jwt in fastapi, for login I get like this in swagger
I don't know why this local_kw form field is present,This is my endpoint code
from sqlalchemy.orm import sessionmaker
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
@router.post("/token", response_model=dict)
async def login_for_access_token(
login_data: LoginRequestBody,
session: Session = Depends(SessionLocal)
):
user = (
session.query(User)
.filter(
or_(
User.username == login_data.email_or_phone_number,
User.email == login_data.email_or_phone_number,
User.phone_number == login_data.email_or_phone_number,
)
)
.first()
)
if user and verify_password(login_data.password, user.hashed_password):
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = create_jwt_token(
data={"sub": user.username}, expires_delta=access_token_expires
)
refresh_token_expires = timedelta(days=1)
refresh_token = create_jwt_token(
data={"sub": user.username, "scope": "refresh"},
expires_delta=refresh_token_expires,
)
output_response = {
"detail": {
"status": "success",
"message": "Login successful",
"access_token": access_token,
"refresh_token": refresh_token,
}
}
return JSONResponse(status_code=200, content=output_response)
# Handle other error scenarios
error_response = {
"detail": {
"status": "fail",
"message": "The application has encountered an unknown error. It doesn't appear to have affected your data, but our technical staff have been automatically notified and will be looking into this with the utmost urgency.",
}
}
return JSONResponse(status_code=400, content=error_response)
I just want the local_kw field to be gone, I am using the these packages
- python==3.10.13
- fastapi==0.105.0
- SQLAlchemy==2.0.23
- uvicorn==0.24.0.post1
- certifi==2023.7.22
Solution
The problem is that your SessionLocal
class (or function) expects local_pw
as an optional parameter. And FastAPI is trying to get the value for this parameter from Query
parameters.
To avoid this, you can create get_session_local
function as shown below and use this new function as a dependency for your endpoint.
def get_session_local():
yield SessionLocal()
@router.post("/token", response_model=dict)
async def login_for_access_token(
login_data: LoginRequestBody,
session: Session = Depends(get_session_local)
):
user = (
session.query(User)
.filter(
or_(
User.username == login_data.email_or_phone_number,
User.email == login_data.email_or_phone_number,
User.phone_number == login_data.email_or_phone_number,
)
)
.first()
)
# Rest of the code
I would recommend you to use this approach instead of calling SessionLocal()
directly in your endpoint.
In this implementation you still have the possibility to override this dependency in the future.
Answered By - Yurii Motov
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.