Home > Enterprise >  Struggling to convert string to Dict in python
Struggling to convert string to Dict in python

Time:05-05

I am using boto3 to make a ssm call. I make a call like this.

import boto3
import json
ssm = boto3.client("ssm")
ssm.get_parameter(Name="slack_webhook")["Parameter"]["Value"]

The response i get is a string text that looks like this.

'Value\n{\n"progress-updates":  "https://hooks.slack.com/services/T0JExxxU6A6Q/xxxxxxxxx/pS7FvL1bIGZggKhLQvWsLAcV",\n"test-channel": "https://hooks.slack.com/services/xxxxxx/xxxxxxxx/IXnWw4sLN5GjI324glzfUIdM",\n"prod": "https://hooks.slack.com/services/xxxx/xxxxx/xgtsgdgsdgsdgdsgs"\n}'

So when i do the following

json.loads(ssm.get_parameter(Name="slack_webhook")["Parameter"]["Value"])

I get the following error

JSONDecodeError Traceback (most recent call last) in ----> 1 json.loads(ssm.get_parameter(Name="slack_webhook")["Parameter"]["Value"])

/usr/local/Caskroom/miniconda/base/envs/pipeline/lib/python3.7/json/init.py in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw) 346 parse_int is None and parse_float is None and 347 parse_constant is None and object_pairs_hook is None and not kw): --> 348 return _default_decoder.decode(s) 349 if cls is None: 350 cls = JSONDecoder

/usr/local/Caskroom/miniconda/base/envs/pipeline/lib/python3.7/json/decoder.py in decode(self, s, _w) 335 336 """ --> 337 obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 338 end = _w(s, end).end() 339 if end != len(s):

/usr/local/Caskroom/miniconda/base/envs/pipeline/lib/python3.7/json/decoder.py in raw_decode(self, s, idx) 353 obj, end = self.scan_once(s, idx) 354 except StopIteration as err: --> 355 raise JSONDecodeError("Expecting value", s, err.value) from None 356 return obj, end

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

I would highly appreciate help in this matter? Do i need to clean up the string further by removing all the \n because i tried that and did not work also.

CodePudding user response:

It's failing because of the leading Value. Assuming the Value string is part of the response, you can write a simple function to trim off leading keys:

def parse_json(x):
    first_brace = x.find("{")
    if first_brace == -1:
        raise ValueError(f"Does not look like a JSON: {x}")
    x = x[first_brace:]
    return json.loads(x)


>>> parse_json(x)
{'progress-updates': 'https://hooks.slack.com/services/T0JExxxU6A6Q/xxxxxxxxx/pS7FvL1bIGZggKhLQvWsLAcV',
 'test-channel': 'https://hooks.slack.com/services/xxxxxx/xxxxxxxx/IXnWw4sLN5GjI324glzfUIdM',
 'prod': 'https://hooks.slack.com/services/xxxx/xxxxx/xgtsgdgsdgsdgdsgs'}

CodePudding user response:

This is a valid JSON string contained in the response.

'{
"progress-updates":"https://hooks.slack.com/services/T0JExxxU6A6Q/xxxxxxxxx/pS7FvL1bIGZggKhLQvWsLAcV",
"test-channel":"https://hooks.slack.com/services/xxxxxx/xxxxxxxx/IXnWw4sLN5GjI324glzfUIdM",
"prod": "https://hooks.slack.com/services/xxxx/xxxxx/xgtsgdgsdgsdgdsgs"
}'
  • Related