0

I use the code below in python on a rpi to do json posts

import requests
payload = '{"msg_type":"observation_payload","msg": 
{"serial":"FZtank","observations":{"8":{"d":0,"m":"JSON upload 
test","t":"1543540780"}}}}'
r = requests.post('https://my.website/api/observations', data = 
{'post_wrapper':payload})
print r.text

it produces

{"msg": {"remote_pi": "FZtank", "stored_ids": ["8"]}, "msg_type": "receipt"}

I figured it wouldn't be too hard to do the same thing in micropython on a pycom device

import urequests as requests
payload = '{"msg_type":"observation_payload","msg": 
{"serial":"FZtank","observations":{"8":{"d":0,"m":"JSON upload 
test","t":"1543540780"}}}}'
r = requests.post('https://my.website/api/observations', data = 
{"post_wrapper":payload})
print(r.text)
r.close()

but it gives

Traceback (most recent call last):
File "<stdin>", line 12, in <module>
File "/flash/lib/urequests.py", line 115, in post
File "/flash/lib/urequests.py", line 100, in request
File "/flash/lib/urequests.py", line 79, in request
TypeError: object with buffer protocol required

The TypeError msg means it wants a string instead of a dictionary for the data

so I tried

import urequests as requests
payload = '{"post_wrapper":{"msg_type":"observation_payload","msg": 
{"serial":"FZtank","observations":{"8":{"d":0,"m":"JSON upload 
test","t":"1543540780"}}}}}'
r = requests.post('https://my.website/api/observations', data =payload)
print(r.text)
r.close()

but that gives

{"msg": {"errorText": "Malformed POST - unable to decode JSON"}, "msg_type": 
"error"}

So now I'm confused. Is the problem that the website expects a dictionary & micropython can only send a string?

.

Some further detail: I'm using https://github.com/micropython/micropython-lib/blob/master/urequests/urequests.py but with line 52 changed from ai = usocket.getaddrinfo(host, port, 0, usocket.SOCK_STREAM) to ai = usocket.getaddrinfo(host, port) because it used to throw an error msg about 4 arguments Vs 2. If I run

import urequests as requests
payload = '{"post_wrapper":{"msg_type":"observation_payload","msg": 
{"serial":"FZtank","observations":{"8":{"d":0,"m":"JSON upload 
test","t":"1543540780"}}}}}'
r = requests.post('https://my.website/api/observations', data=payload)

or

import urequests as requests
payload = {"post_wrapper":{"msg_type":"observation_payload","msg": 
{"serial":"FZtank","observations":{"8":{"d":0,"m":"JSON upload 
test","t":"1543540780"}}}}}
r = requests.post('https://my.website/api/observations', json=payload)

or

import urequests as requests
payload = {"msg_type":"observation_payload","msg": 
{"serial":"FZtank","observations":{"8":{"d":0,"m":"JSON upload 
test","t":"1543540780"}}}}
r = requests.post('https://my.website/api/observations', json= 
{"post_wrapper":payload})

I get the same result

{"msg": {"errorText": "Malformed POST - unable to decode JSON"}, "msg_type": 
"error"}
4
  • The TypeError msg means it wants a string not so sure about that, it says it wants an object with a buffer protocol. That might be a string, but there are likely other objects supporting that as well. Looking at the source code at github.com/micropython/micropython-lib/blob/master/urequests/… seems to indicate you can just pass json={'post_wrapper': payload} though? Commented Nov 30, 2018 at 20:02
  • I tried that but it says TypeError: 'module' object is not callable. I feel I got close with ujson.dumps but it bleats about library line 51 port=int(port) saying OSError: 128 Commented Dec 1, 2018 at 0:21
  • I fail to see how changing any argument other than url can effect the port; are you sure that's not a seperate unrelated issue? Also maybe post full error messages including line numbers, that's much easier to get help for. Commented Dec 1, 2018 at 15:46
  • OK I expanded the original post some more Commented Dec 1, 2018 at 22:51

2 Answers 2

3

I was stuck with the same issue here while trying to send push notifications through pushed.co.

I was using data=payload on urequests and getting this TypeError: object with buffer protocol required error. All worked well when I changed to json=payload following @stijn suggestion on his answer.

Steps I did:

  1. on micropython REPL install urequests
import upip
upip.install('micropython-urequests')
  1. for my example the code is
import urequests as requests
payload = {
    "app_key": "your_app_key",
    "app_secret": "your_app_secret",
    "target_type": "your_target_type",
    "content": "Hello from micropython",
}
r = requests.post("https://api.pushed.co/1/push", json=payload)

Probably any other url will do fine too.

Sign up to request clarification or add additional context in comments.

Comments

0

I was able to make posts request on micropython dumping data into a json:

import json
import urequests
data = {"mykey": 'myvalue'}
urequests.post(url, data=json.dumps(data))

1 Comment

This didn't work for me, but changing the last line to urequests.post(url, json=data) did.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.