1

I'm json encoding an attribute in POST data request (due to it being a list of Sending list of dicts as value of dict with requests.post going wrong ) but I'm having trouble reading it back.

In my endpoint when I receive the request the body looks like this:

The post request is done like this:

params = {
    "listofdicts": json.dumps([
         {"variable": "1"},
         {"variable": "2"},
         {"variable": "3"},
         {"variable": "4"},
     ]),
     "number": 5,
}

request.request("POST", ... , data=params)

I should be able to read the body to get the original params

params = {
    "listofdicts": json.dumps([
         {"variable": "1"},
         {"variable": "2"},
         {"variable": "3"},
         {"variable": "4"},
     ]),
     "number": 5,
}

After reading Trying to parse `request.body` from POST in Django I tried to do:

body = json.loads(event["body"])
listofdicts = json.loads(body["listofdicts"])
number = body["number"]

But it fails on the first line with

body = json.loads(event["body"])  
File "/var/lang/lib/python3.9/json/__init__.py", line 346, in loads     return _default_decoder.decode(s)   File "/var/lang/lib/python3.9/json/decoder.py", line 337, in decode     obj, end = self.raw_decode(s, idx=_w(s, 0).end())   File "/var/lang/lib/python3.9/json/decoder.py", line 355, in raw_decode     raise JSONDecodeError("Expecting value", s, err.value) from None

The event["body"] string looks like this:

{'body': 'listofdicts=%5B%7B%22variable%22%3A+%221%22%7D%2C+%7B%22variable%22%3A+%222%22%7D%2C+%7B%22variable%22%3A+%223%22%7D%2C+%7B%22variable%22%3A+%224%22%7D%5D&number=5'}

How can I decode this body?

eljiwo
  • 687
  • 1
  • 8
  • 29
  • when you do `request.request("POST", ... , data=params)` the request is sent as `application/x-www-form-urlencoded` rather than JSON i.e. only your `listofdicts` param is JSON encoded. Django should have already decoded the form encoded body so the json.loads is not needed here `body = json.loads(event["body"])` only here `json.loads(body["listofdicts"])` ... try just `json.loads(event["body"]["listofdicts"])` – Anentropic Oct 26 '22 at 12:24
  • Can you show the full code ? – Deepak Tripathi Oct 26 '22 at 12:28
  • @Anentropic if you see at the bottom of the question i show how the event["body"] looks like, is a str (or byte str) not an accessible dict im afraid :( – eljiwo Oct 26 '22 at 13:13
  • @DeepakTripathi Its impossible for me to show the full code of the endpoint, what do you want to know more about ? – eljiwo Oct 26 '22 at 13:14
  • @eljiwo where does `event` object come from? you need to show more of your code – Anentropic Oct 26 '22 at 15:06
  • event is the raw request received, i actually found the solution it was due to url encoding. Posting the answer know if you want to know why it was. – eljiwo Oct 26 '22 at 15:35

1 Answers1

1

Turns out the body content was URL-encoded and that would need to decode it as Url decode UTF-8 in Python says.

Other option to avoid request library url-encoding your data body is to use a full json as the data object. So doing:

params = {
    "listofdicts": [
         {"variable": "1"},
         {"variable": "2"},
         {"variable": "3"},
         {"variable": "4"},
     ],
     "number": 5,
}
params = json.dump(params)

Fixed it too as now the body became a str loadable from json.loads(): '{"listofdicts": [{"variable": "1"}, {"variable": "2"}, {"variable": "3"}, {"variable": "4"}], "number": 5}'

eljiwo
  • 687
  • 1
  • 8
  • 29