How to pare JSON file starts with b'" - json

I am getting this string when we read s3 object as JSON
json_object = s3_client.get_object(Bucket=bucket,Key=json_file_name)
print(json_object)
jsonFileReader = json_object['Body'].read()
jsonDict = json.loads(jsonFileReader)
The data looks like this when i printed
raw = b'"[{\\"timestamp\\": \\"2022-07-27T12:34:52.304000+00:00\\", \\"type\\": \\"ExecutionSucceeded\\", \\"id\\": 9, \\"previousEventId\\": 8, \\"executionSucceededEventDetails\\": {\\"output\\": \\"{\\\\\\"statusCode\\\\\\":200,\\\\\\"body\\\\\\":\\\\\\"\\\\\\\\\\\\\\"Hello from Lambda!\\\\\\\\\\\\\\"\\\\\\"}\\", \\"outputDetails\\": {\\"truncated\\": false}}}]"'
I want to extract type out of it .
But when i do it i get error
status=data[0]['type']
TypeError: string indices must be integers
My code
raw = b'"[{\\"timestamp\\": \\"2022-07-27T12:34:52.304000+00:00\\", \\"type\\": \\"ExecutionSucceeded\\", \\"id\\": 9, \\"previousEventId\\": 8, \\"executionSucceededEventDetails\\": {\\"output\\": \\"{\\\\\\"statusCode\\\\\\":200,\\\\\\"body\\\\\\":\\\\\\"\\\\\\\\\\\\\\"Hello from Lambda!\\\\\\\\\\\\\\"\\\\\\"}\\", \\"outputDetails\\": {\\"truncated\\": false}}}]"'
data = json.loads(raw.decode('utf-8'))
print(data)
print(data[0])
status=data[0]['type']
print(status)

Your decoded raw represents a string, not a json object (notice that the first and last characters of raw are quotes ").
When you do data = json.loads(raw.decode('utf-8')), you have type(data) == str, i.e. data is the string "[{\\"timestamp\\": \\"2022-...", which happens to itself be a json string.
To deserialize this string, json.loads it again:
data = json.loads(data)
And now use it:
print(data[0]['type'])
# prints ExecutionSucceeded

Related

Flutter - Convert "\x" encoded utf-8 characters to readable String from http.get response

I'm parsing a html page in my flutter app, and somewhere in the middle of that html source has a json string in utf-8 format ( "\x" format).
I'm able to get the html content and then parse to it extract that json object in "\x" utf-8 format to a String var, but I'm not able to convert it to a json to decode it.
I tried printing the ranes of that first 4 letters in that parsed output "\x5B" it printing as 4 separate ints, while the same "\x5B" I statically assigned to a String var and printed the ranes , it only shows one digit. So just wondering how can I decode that extracted String in "\x" format ?
An extract of the code as below:
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
var res = utf8.decode(response.bodyBytes);
//gives the starting index of json object in html source
int startIndex = res.indexOf('var statData');
// start and end index of json object in "\x" format
int start = res.indexOf("(", startIndex) + 2;
int end = res.indexOf(");", start) - 1;
//extract the json in \x encoded
String dataJson = res.substring(start,end);
//now sample code to compare the string, one statically assigned,
//another extracted from the html source, to describe the issue I'm having now.
String sample1 = dataJson.substring(0,4)); //extracts "\x5B" from the string
String sample2 = "\x5B";
print(sample2.runes); // prints (91)
print(sample1.ranes); // prints (92, 120, 53, 66), expectation is to get (91)
}
Output :
I/flutter ( 3437): (91)
I/flutter ( 3437): (92, 120, 53, 66)
While sample2.runes prints the single character (91)( equivalent ascii is '{' - start of the json)),
The same "\x5B" I extracted from the string not getting decoded as (91), instead it is treated as 4 separate characters, so looks like '\x' extracted string is not treated as utf-8 encode indicator.
I want the sample1.runes also to be {91}, how to approach this ?, where am I going wrong?
I don't know whether this is the correct way to handle it, but thanks to this post https://stackoverflow.com/a/64699290/17301137
, I was able to resolve it.
Basically It does a regex match of all Hex values after '\x' then replace it to corresponding string return.
final Pattern unicodePattern = new RegExp(r'\\x([0-9A-Fa-f]{2})');
final String newStr = sample1.replaceAllMapped(unicodePattern, (Match unicodeMatch) {
final int hexCode = int.parse(unicodeMatch.group(1)!, radix: 16);
final unicode = String.fromCharCode(hexCode);
return unicode;
});
this is the way I resolved it.
But not sure, whether there any better way to resolve it.

How to convert following string to JSON in python

How can i convert the below string to JSON using python?
str1 = "{'a':'1', 'b':'2'}"
The json library in python has a function loads which enables you to convert a string (in JSON format) into a JSON. Following code for your reference:
import json
str1 = '{"a":"1", "b":"2"}'
data = json.loads(str1)
print(data)
Note: You have to use ' for enclosing the string, whereas " for the objects and its values.
The string in OP's question is not JSON because the keys and values are enclosed by single-quotes. The function ast.literal_eval can be used to parse this string into a Python dictionary.
import ast
str1 = "{'a':'1', 'b':'2'}"
d = ast.literal_eval(str1)
d["a"] # output is "1"
Other answers like https://stackoverflow.com/a/58540688/5666087 and https://stackoverflow.com/a/58540879/5666087 were able to use the json library because they changed str1 from "{'a':'1', 'b':'2'}" to '{"a":"1", "b":"2"}'. The former is invalid JSON, whereas the latter is valid JSON.
import json
str1 = '{"a":"1", "b":"2"}'
jsonData = json.loads(str1)
print(jsonData["a"])
Reference : LINK

parsing a json file using play json

I am reading a HDFS sequence file and which is of [Long, String] lets call each record as message. message._2 is a json string and i am trying to parse it using play json library but i get the following error when i do it.
Error:
found : Seq[play.api.libs.json.JsValue]
required: String
Code:
val jsonString = message._2.toString();
val json = Json.parse(jsonString);
code = (json(0) \\ "code"); -- > Error is pointing to \\ on this line
The error message says that (json(0) \\ "code") returns Seq[play.api.libs.json.JsValue], and you're trying to assign this value to the variable code of type String.
So, you may want to do this:
code = (json(0) \\ "code").head.as[String]
which will get the first item of a list and convert JsValue to String.
Update
As #cchantep suggested, the use of head is not safe, so for better safety you can do it with headOption, but the result type will be Option[String]:
val code: Option[String] =
(json \\ "code").headOption.map(_.as[String])
and even more safe code will look like this:
val code: Option[String] =
(json \\ "code").headOption.flatMap(_.asOpt[String])

How to get list of json strings from sinlgle line multi json string in scala

I am trying to get list of json string from given string having multiple json strings separated by ",".
For example
val jsonString = "{\"a\":\"b\"},{\"c\":\"d\", \"e\":\"f\"}"
expected result , List[String] :
["{\"a\":\"b\"}", "{\"c\":\"d\", \"e\":\"f\"}"]
You should replace the json separator with a string or character that is not repeated in the whole string and use that special separator to be used with split method to get you your required output. Here I have used -
jsonString.replace("},{", "}-{").split("-")
You should have output as
res0: Array[String] = Array({"a":"b"}, {"c":"d", "e":"f"})
One step further, calling toList method would get you to the final dataType you require
jsonString.replace("},{", "}-{").split("-").toList //res0: List[String] = List({"a":"b"}, {"c":"d", "e":"f"})
Got solution for it.
val jsonString = "{\"a\":\"b\"},{\"c\":\"d\", \"e\":\"f\"}"
val jsonListString = "[" + jsonString + "]"
val jsonArray = new JSONArray(jsonListString)
This will create array of json.

Elm: decode local JSON file into dict

I'm working on my first Elm app.
I want to use a local JSON file as a lookup table. The file matches weather conditions (a string) to suggested clothing (a list).
EDIT (clarifying the question): Based on some earlier SO questions from 2015 I've tried using Http.get to get the contents and then Decode.dict to create the Dict. It seems strange to use an Http module to ingest a local file. Is this methodology, including the Http.send I use below correct in Elm?
I am also having a hard time finding an example of a decoder that would work for a JSON file like the one I have. Any pointers would be appreciated.
JSON
{
"male,10,overcast,light wind...": ["Winter Cap", "Light Jacket"...],
"female,30,partly cloudy...": ["Winter Cap", "Sunglasses", ...]
}
CODE
type alias ClothingDict =
Dict String List
clothingUrl: String
clothingUrl =
"./clothing.json"
getClothingDict : Cmd Msg
getClothingDict =
let
url = clothingUrl
in
Http.send SetClothing (Http.get url decodeClothingResponse)
type alias ClothingResponse =
{ clothingOptions: ClothingDict }
decodeClothingResponse : Decoder ClothingResponse
decodeClothingResponse =
Decode.dict ClothingResponse
Decode.dict or dict takes a Decoder in order to handle decoding the keys of the Dict. dict automatically extracts the keys as strings.
I converted the code to:
decodeClothingResponse : Decoder (Dict String (List String))
decodeClothingResponse =
dict (list string)
(list string) is a decoder that will decoder a list of string from json in to a List String