B4J Question [Banano] API Fetch login to FastAPI Error [SOLVED]

MichalK73

Well-Known Member
Licensed User
Longtime User
Hello.

I have a small problem and I don't know why it's not working. I have written a RestAPI server in FastAPI (python). It handles login and the result is an access token.
When the login function is written in FastAPI standard 'OAuth2PasswordRequestForm'. At Swagger or Postman, there are no problems with logging in and obtaining a token. The problem is when I want to connect via Banano.

Function Login FASTAPI:
@router.post('/login')
def login(request : OAuth2PasswordRequestForm = Depends(), db : Session = Depends(database.get_db)):
    room = db.query(models.Room).filter(models.Room.name == request.username).first()
    print(request.username)
    if not room:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=f'Not found: {request.username}')
    if not hashing.Hash.verify(room.password, request.password):
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,
                            detail=f'Password id bed :(')
    #generujemy token i zwracamy
    # access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(data={"sub": room.name})

   return {"access_token": access_token, "token_type": "bearer", "id_room":room.id}

Login in Swagger UI

swwager.jpg


CURL URL
B4X:
curl -X 'POST' \
  'http://localhost:8000/login' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=&username=aaa&password=12345&scope=&client_id=&client_secret='

Login in Postman

1687255893728.png

As you can see, the login parameters are only available via POST in the BODY.

Login function from Banano.
B4X:
    Dim response As BANanoFetchResponse
    Dim error As BANanoObject
    Dim data As BANanoJSONParser
    
    ' insert with a POST
    Dim fetch2Options As BANanoFetchOptions
    fetch2Options.Initialize
    fetch2Options.Method = "POST"
    fetch2Options.Body = BANano.ToJson(CreateMap("username": "aaa", "password": "12345"))
    fetch2Options.Headers = CreateMap("Content-type": "application/json; charset=UTF-8", "Content-Type": "application/x-www-form-urlencoded")

  
    Dim fetch2 As BANanoFetch
    fetch2.Initialize("http://localhost:8000/login/", fetch2Options)
    fetch2.Then(response)
    fetch2.Return(response.Json)
    fetch2.Then(data)
    Log(data)
    fetch2.End

I get an error. "INFO: 127.0.0.1:62754 - "POST /login HTTP/1.1" 422 Unprocessable Entity" in server FASTAPI.
In browser:
1687256321081.png

What else is wrong with the code that does not allow me to pass Banana data?
I would like to mention that when I added a login function in FastAPI where username and password are to be passed via Headres, it works correctly in Banano.

Login2 to FASTAPI Headers:
    Dim response As BANanoFetchResponse
    Dim error As BANanoObject
    Dim data As BANanoJSONParser
    
    ' insert with a POST
    Dim fetch2Options As BANanoFetchOptions
    fetch2Options.Initialize
    fetch2Options.Method = "GET"
    fetch2Options.Headers = CreateMap("Content-type": "application/json; charset=UTF-8", "username":"aaa", "password":"12345")
  
    Dim fetch2 As BANanoFetch
    fetch2.Initialize("http://localhost:8000/login2/", fetch2Options)
    fetch2.Then(response)
    fetch2.Return(response.Json)
    fetch2.Then(data)
    Log(data)
    fetch2.End

In response in browser:
1687256370665.png



The problem as you can see occurs in the POST in the BODY for BANANO.
All hints of a solution welcome.
 
Solution
@MichalK73 Sorry, I did miss this post (it was in my summer holiday :cool: )

In BANano you are posting Json, while in postman application/x-www-form-urlencoded as the body. Actually, you were trying to do both:

B4X:
fetch2Options.Headers = CreateMap("Content-type": "application/json; charset=UTF-8", "Content-Type": "application/x-www-form-urlencoded")

Hard to test now but the body would've probably have been something like:

B4X:
Dim fetch2Options As BANanoFetchOptions
fetch2Options.Initialize
fetch2Options.Method = "POST"
    
' create a new URLSearchParams object
Dim data As BANanoObject
data.Initialize2("URLSearchParams", CreateMap("username": "aaa", "password": "12345"))
' set it to body
fetch2Options.Body =...

alwaysbusy

Expert
Licensed User
Longtime User
@MichalK73 Sorry, I did miss this post (it was in my summer holiday :cool: )

In BANano you are posting Json, while in postman application/x-www-form-urlencoded as the body. Actually, you were trying to do both:

B4X:
fetch2Options.Headers = CreateMap("Content-type": "application/json; charset=UTF-8", "Content-Type": "application/x-www-form-urlencoded")

Hard to test now but the body would've probably have been something like:

B4X:
Dim fetch2Options As BANanoFetchOptions
fetch2Options.Initialize
fetch2Options.Method = "POST"
    
' create a new URLSearchParams object
Dim data As BANanoObject
data.Initialize2("URLSearchParams", CreateMap("username": "aaa", "password": "12345"))
' set it to body
fetch2Options.Body = data.RunMethod("toString", Null)
    
fetch2Options.Headers = CreateMap("Content-Type": "application/x-www-form-urlencoded")

Alwaysbusy
 
Upvote 0
Solution

MichalK73

Well-Known Member
Licensed User
Longtime User
@MichalK73 Sorry, I did miss this post (it was in my summer holiday :cool: )

B4X:
Dim fetch2Options As BANanoFetchOptions
fetch2Options.Initialize
fetch2Options.Method = "POST"
   
' create a new URLSearchParams object
Dim data As BANanoObject
data.Initialize2("URLSearchParams", CreateMap("username": "aaa", "password": "12345"))
' set it to body
fetch2Options.Body = data.RunMethod("toString", Null)
   
fetch2Options.Headers = CreateMap("Content-Type": "application/x-www-form-urlencoded")

Alwaysbusy

1697964017075.png


Now I was only able to check if it works. I had a bit of a cold.
The code works correctly, FastApi now authorizes and gives the token correctly.
Many thanks for your help.
 
Upvote 0
Top