add payload to POST request

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
Miliks
Posts: 2
Joined: Wed Jun 29, 2022 8:30 am
Contact:

add payload to POST request

Post by Miliks » Wed Jun 29, 2022 9:00 am

Hi guys,
i have a server with POST e REST services. Using micropython i need to perform POST request.
GET is performed and respond correctly using the following format:

s.send(b"GET /sensordata/premises HTTP/1.1\r\nHost:XX.XXX.XXX.XXX\r\n" + "Accept: application/json\r\n\r\n")

but for the POST looks like the request arrived at server, but the payload body is empty. For some reason, the JSON body of the request is not interpreted in the correct way.

Code: Select all

from network import WLAN
import socket
import machine
import time
import struct
import json
import pycom

wlan = WLAN(mode=WLAN.STA)
wlan.connect("*****", auth=(WLAN.WPA2, "*****"), timeout=5000)

while not wlan.isconnected():
    machine.idle()
print("Connected to WiFi\n")

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
url = 'XX.XXX.XXX.XXX'

sockaddr = socket.getaddrinfo(url, 80) [0][-1]
s.connect(sockaddr)

print('socket connected')

httpreq = b'POST /sensordata/insertrecords HTTP/1.1 \r\n Host:XX.XXX.XXX.XXX \r\n' + 'Accept: application/json \r\n' + 'Content-Type: application/json\r\n\r\n' + ' {\"node_id\":\"1\",\"value\":[{\"measure_time_stamp\":\"2020-10-06T09:25:43\",\"temp\":\"14\",\"humidity\":\"75\",\"ph1\":11,\"ph2\":12,\"ph3\":13}]}'
s.send(httpreq)
time.sleep(1)
rec_bytes = s.recv(4096)
print("RESPONSE = " + str(rec_bytes))
print('end')
s.close()

ChrisO
Posts: 48
Joined: Mon Apr 06, 2020 6:16 pm

Re: add payload to POST request

Post by ChrisO » Wed Jun 29, 2022 12:03 pm

I haven't done this before, but I'm guessing you need to add the Content-Length header is well.
Chris

ChrisO
Posts: 48
Joined: Mon Apr 06, 2020 6:16 pm

Re: add payload to POST request

Post by ChrisO » Wed Jun 29, 2022 12:07 pm

someone will come along with a full fledged example, I'm sure.
In the meantime, if you won't want to wait. I'd take a cpython example like the one discussed here:
https://stackoverflow.com/questions/286 ... parameters

besides Content-Length it seems like you have to byte encode the information as well.
Chris

p_j
Posts: 102
Joined: Mon Aug 23, 2021 1:08 pm
Location: Sydney

Re: add payload to POST request

Post by p_j » Wed Jun 29, 2022 1:29 pm

Have you considered using 'requests', it might be easier and less error prone?

Code: Select all

import urequests as requests

mydata = {'temp': 10, }

x = requests.post(url, json=mydata)
if x.status_code == 200:
    print("Done")
    

Miliks
Posts: 2
Joined: Wed Jun 29, 2022 8:30 am
Contact:

Re: add payload to POST request

Post by Miliks » Wed Jun 29, 2022 2:56 pm

ChrisO wrote:
Wed Jun 29, 2022 12:07 pm
someone will come along with a full fledged example, I'm sure.
In the meantime, if you won't want to wait. I'd take a cpython example like the one discussed here:
https://stackoverflow.com/questions/286 ... parameters

besides Content-Length it seems like you have to byte encode the information as well.
thanks, this was really helpful, it was really a matter of encoding and content-length parameters. the code below works perfectly:

Code: Select all

headers =  """\
POST /sensordata/insertrecords HTTP/1.1
Content-Type: {content_type}\r
Content-Length: {content_length}\r
Host: {host}\r
Connection: close\r
\r\n"""
                               
body_bytes = json_data.encode('ascii')
header_bytes = headers.format(
    content_type="application/json",
    content_length=len(body_bytes),
    host=str(host) + ":" + str(port)
).encode('iso-8859-1')

payload = header_bytes + body_bytes

s.sendall(payload)

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: add payload to POST request

Post by jimmo » Wed Jun 29, 2022 11:40 pm

Miliks wrote:
Wed Jun 29, 2022 2:56 pm
thanks, this was really helpful, it was really a matter of encoding and content-length parameters. the code below works perfectly:
Unless you're really optimising for every last byte of RAM and flash, then using urequests would be simpler -- see https://github.com/micropython/micropyt ... equests.py (it might already be installed on your device, e.g. ESP32!)

Post Reply