I want to refresh the access token for the Netatmo API. I tried different things but I get every time the same error. I use MicroPython and the urequests lib for the requests.
The error is:
Status Code: 400
{"error":"invalid_request","error_description":"Invalid grant_type parameter or parameter missing"}
At first I tried, as it works for me in normal Python, to make a request post.
payload = {
'grant_type': 'refresh_token',
'refresh_token': 'XXXXXXXXXXXXXXXXXXXXXXXXXXX',
'client_id': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'client_secret': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
}
response = requests.post("https://api.netatmo.com/oauth2/token",
data=payload)
The result was:
TypeError: object with buffer protocol required
I found out that urequests can not handle it, because it does not know which protocol it has to use.
Next I converted it to a bytearry. Then I don't get the type error, but I get the error invalid_request
{"error":"invalid_request","error_description":"Invalid grant_type parameter or parameter missing"}
After that, I tried to set the headers, but I got the same error as without headers.
payload = {
'grant_type': 'refresh_token',
'refresh_token': 'XXXXXXXXXXXXXXXXXXXXXXXXXXX',
'client_id': 'XXXXXXXXXXXXXXXXXXXXXXXXXXX',
'client_secret': 'XXXXXXXXXXXXXXXXXXXXXXXXXXX',
}
headers = {'Content-Type': 'application/x-www-form-urlencoded',}
payload_json = json.dumps(payload)
payload_bytes = bytearray(payload_json, 'utf-8')
response = requests.post('https://api.netatmo.com/oauth2/token', data=payload_bytes, headers=headers)
At the end I even tried to build the URL by hand, but I still get the invalid request error. This is the URL I tried to build:
https://api.netatmo.com/oauth2/token?&grant_type=refresh_token&refresh_token=XXXXXXXXXXXXXXXXXXXXXXXXXX&client_id=XXXXXXXXXXXXXXXXXXXXXXXXXX&client_secret=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Can please somebody help me?
As assumed is the problem, that the format is wrong and the urequests can not read the format. After a long conversation with ChatGPT is the solution to encode the URL. The method ChatGPT gave me was:
def urlencode(params):
encoded_str = ''
for key, value in params.items():
encoded_str += '{}={}&'.format(key, value)
return encoded_str[:-1]
It works for me perfectly. So here is the complete code how it works for me:
import urequests as requests
def urlencode(params):
encoded_str = ''
for key, value in params.items():
encoded_str += '{}={}&'.format(key, value)
return encoded_str[:-1]
payload = {
'grant_type': 'refresh_token',
'refresh_token': 'XXXXXXXXXXXXXXXXXXXXXXXX',
'client_id': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'client_secret': 'XXXXXXXXXXXXXXXXXXXXXXXXXX',
}
payload_encoded = urlencode(payload)
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
response = requests.post('https://api.netatmo.com/oauth2/token', data=payload_encoded, headers=headers)
print(response.status_code)
print(response.text)