I have a FastAPI server running at localhost:8000 and a react dev server running at localhost:3000. I have an endpoint set up as follows:
@router.post(
name="Create User",
tags=[Tags.Authentication],
path='/create_user',
status_code=200,
response_model=SuccessfulUserAuthenticate
)
def create_user(
user: UserInCreate = Body(
title="User",
description="User that will be created",
default=Required,
embed=True
)
):
pwd_context = CryptContext(schemes=['bcrypt'], deprecated="auto")
new_user_object = User(
user.first_name,
user.last_name,
user.email,
pwd_context.hash(user.password),
user.dob)
with Session() as s:
user_already_exists = True if s.query(User).where(User.email == user.email).first() else False
if user_already_exists:
raise EmailAlreadyExistsException()
else:
new_user_object.datetime_joined = datetime.utcnow()
s.add(new_user_object)
s.commit()
return_user = SuccessfulUserAuthenticate(
user.email,
create_access_token(
data={
'user': user.email
}
)
)
return return_user
Long story short, this function simply checks whether the email exists on the database. If it does, it raises an error which is handled by an exception handler which looks as such:
@app.exception_handler(EmailAlreadyExistsException)
def email_exists_exception_handler(request: Request, exc: EmailAlreadyExistsException):
print('here')
return JSONResponse(
status_code=exc.status_code,
content=jsonable_encoder({'detail': exc.description})
)
If the email does not exist, it creates an account in the database. As you can see, I have a little debug statement which shows up in my terminal. The react frontend fetch function looks as such:
const createUserSignUpSubmit = async () => {
const response = await fetch('http://localhost:8000/authentication/create_user', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
"user": {
"email": "user@example.com",
"password": "string",
"first_name": "string",
"last_name": "string",
"dob": "2019-08-24"
}
})
})
console.log(response.status)
console.log(response.body)
setFirstName('')
setLastName('')
setEmail('')
setPassword('')
setDate(new Date())
}
When I submit this fetch request, I know that it reaches the endpoint because I can see the sql statements print out to the terminal and they look as follows:
2022-09-22 18:22:12,178 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-09-22 18:22:12,184 INFO sqlalchemy.engine.Engine SELECT user.id AS user_id, user.first_name AS user_first_name, user.last_name AS user_last_name, user.email AS user_email, user.password AS user_password, user.datetime_joined AS user_datetime_joined, user.date_of_birth AS user_date_of_birth
FROM user
WHERE user.email = %s
LIMIT %s
2022-09-22 18:22:12,184 INFO sqlalchemy.engine.Engine [generated in 0.00023s] ('user4@example.com', 1)
2022-09-22 18:22:12,191 INFO sqlalchemy.engine.Engine ROLLBACK
here
The "here" is printed from the exception handler. So everything flows as you would expect but it just wont return a response to my frontend. It does properly return a response to postman however. After much searching, I can't seem to figure out the issue. I've concluded that it isn't a CORS issue because I have the appropriate middleware set up as well as follows:
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
It seems as if the code is flowing just as I want it to, all the way until the final step where it actually has to send a response back to React. Any help would be greatly appreciated!