JSON posts



  • I use this code 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 prints

    {"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 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?



  • @kjm Line 52 doesn't seem to be related to datapayload, so i suppose that data = ujson.dumps({"post_wrapper":payload})) do the work.

    I don't know what OSError 128 mean but the line seem to be related to networking. Does your software have do correctly the connect with your wifi hotspot before trying to send your request ?



  • It doesn't like ujson.dumps either

    Traceback (most recent call last):
      File "<stdin>", line 11, in <module>
      File "/flash/lib/urequests.py", line 115, in post
      File "/flash/lib/urequests.py", line 52, in request
    OSError: 128
    

    int(port) in the library seems harmless enough?

    49   if ":" in host:
    50       host, port = host.split(":", 1)
    51       port = int(port)
    52    ai = usocket.getaddrinfo(host, port)
    53    #ai = usocket.getaddrinfo(host, port, 0, usocket.SOCK_STREAM)
    

    I'm using the library you linked to (albeit with line 53 changed to stop it crashing) but it won't do json = {"post_wrapper":payload}) either, says TypeError: 'module' object is not callable



  • @kjm Have you try something like this ?

    import urequests as requests
    import ujson
    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 = ujson.dumps({"post_wrapper":payload}))
    print(r.text)
    r.close()
    

    Micro python is a small python sub part, so it have smaller library than python but ujson must do the job you request. (where urequests come from it's not a pycom library isn't it ?)
    If it come from https://github.com/micropython/micropython-lib/blob/master/urequests/urequests.py
    then you can just do
    r = requests.post('https://my.website/api/observations', json = {"post_wrapper":payload})



Pycom on Twitter