Python JSON encoding invalid json format - python

i've stucked, i have a json with symbols like ' in values and syntax with ' and "
Example mix double qoute and single qoutelink
json ={
'key': "val_'_ue",
'secondkey': 'value'
}
With json loads and json dumps i got a str type not a dict to iterate, any ideas how i get it fixed?
print(postParams)# = {'csrf-token': "TOKEN_INCLUDES_'_'_symbols", 'param2': 'params2value'}
jsn_dict2 = json.loads(json.dumps(postParams))
print(type(jsn_dict2)) # ERROR HERE why str and not dict
for key, val in jsn_dict2.items():
print("key="+str(key))

you dont need to dumps() an already string json data:
jsn_dict = json.loads(json.dumps(res))
should be :
jsn_dict = json.loads(res)
UPDATE
according to comments the data is looks like so:
postParams = "{'csrf-token': \"TOKEN_INCLUDES_'_'_symbols\", 'add-to-your-blog-submit-button': 'add-to-your-blog-submit-button'}"
so i found an library that can help damaged json string like this one:
first run :
pip install demjson
then this code can help you:
from demjson import decode
data = decode(postParams)
data
>>> {'csrf-token': "TOKEN_INCLUDES_'_'_symbols",
'add-to-your-blog-submit-button': 'add-to-your-blog-submit-button'}

In your json u have missed the "," comma separation between two keys. The actual structure of the JSON is
json_new ={
'key': "val_'_ue",
'secondkey': 'value'
}
use
json_actual=json.dumps(json_new)
to read,
json_read=json.loads(json_actual)

Related

How to add string in specific positions in geojson object

i have the below posted geojson mentioned in geojson_1 section below. i want to add to it "geometry":{ and }, so that to appear as follows
{"geometry":{"type":"Polygon","coordinates":[[[1216374.67364018,6563498.44078949],[1216387.86261675,6563523.87797899],[1216397.66970116,6563548.2905649],[1216424.17569103,6563588.32082324],[1216458.19258303,6563622.16452455],[1216498.32084288,6563648.42909789],[1216542.90943577,6563666.03380959],[1216590.12376481,6563674.25425166],[1216638.02117068,6563672.7521636],[1216684.63088244,6563661.58935797],[1216728.03512655,6563641.225175],[1216752.29181681,6563626.67066235],[1216787.17700448,6563601.12371718],[1216816.83970763,6563569.63465531],[1216831.39332728,6563551.03748989],[1216838.2508451,6563541.8226918],[1216897.47283376,6563458.0765492],[1216918.74007329,6563421.44644481],[1216933.156564,6563381.60258193],[1216940.26085904,6563339.82061228],[1216939.82562707,6563297.43819918],[1216931.86491641,6563255.81218836],[1216907.60647856,6563170.91644364],[1216887.20280767,6563121.46139137],[1216856.24799209,6563077.86160203],[1216821.48046704,6563039.0529759],[1216799.23490474,6563017.28929875],[1216753.95673639,6562978.48086898],[1216737.29066155,6562965.4435638],[1216673.22488836,6562919.79826372],[1216644.73178636,6562899.22061724],[1216601.13622245,6562874.31962206],[1216562.32695185,6562857.3410734],[1216556.56069412,6562854.90900462],[1216549.97837146,6562852.23502385],[1216545.77480552,6562849.58841453],[1216504.75306873,6562829.03095075],[1216487.0229317,6562822.21187019],[1216482.65368148,6562820.3796627],[1216478.79578194,6562814.49158384],[1216462.95127963,6562793.04723497],[1216450.44559886,6562777.97698661],[1216448.65520854,6562774.19751598],[1216429.39331353,6562740.84427663],[1216404.99213055,6562711.06486155],[1216382.3528849,6562687.61801865],[1216357.97638417,6562665.64947943],[1216339.38004804,6562651.09634054],[1216299.24217837,6562625.743469],[1216254.86196793,6562608.94292463],[1216208.02902037,6562601.37212065],[1216160.63182011,6562603.33631786],[1216114.58159971,6562614.75632195],[1216071.73529105,6562635.17167463],[1216033.82066317,6562663.75921023],[1216002.36666225,6562699.36623124],[1215978.64176027,6562740.55696848],[1215963.60279766,6562785.67045603],[1215957.85638339,6562832.88749107],[1215961.63441126,6562880.30398198],[1215963.25125904,6562889.19806131],[1215964.03213898,6562893.28933659],[1215968.1319511,6562913.79137984],[1215972.03222389,6562937.19708669],[1215977.28745991,6563016.79645952],[1215971.45390521,6563048.0427099],[1215969.39172682,6563061.09023781],[1215963.73069651,6563104.75131293],[1215962.06592533,6563123.22251112],[1215960.00953034,6563163.6421848],[1215954.35640427,6563213.80082903],[1215954.63230125,6563269.34572034],[1215960.29082704,6563315.43307246],[1215970.70253119,6563361.57391952],[1215982.82982632,6563397.95907391],[1216001.20120538,6563439.38870108],[1216027.10825421,6563476.54992802],[1216059.60193364,6563508.08124916],[1216097.4918555,6563532.82739871],[1216139.38989254,6563549.8816932],[1216183.76104002,6563558.61926572],[1216228.97966418,6563558.71997125],[1216273.38907516,6563550.18012236],[1216287.1346647,6563546.13717455],[1216332.92682121,6563527.24586381],[1216373.78586258,6563499.1986745],[1216374.67364018,6563498.44078949]]]}}
to simpify it even more, i want to add "geometry":{ right after the the first curly bracket, and the } at the very end
i attmepted the following:
asString = asString[:2] + "geometry:" + asString[2:]
asString = asString[:len(asString)] + "}" + asString[len(asString):]
but i am not getting the expected results
geojson_1:
{"type":"Polygon","coordinates":[[[1216374.67364018,6563498.44078949],[1216387.86261675,6563523.87797899],[1216397.66970116,6563548.2905649],[1216424.17569103,6563588.32082324],[1216458.19258303,6563622.16452455],[1216498.32084288,6563648.42909789],[1216542.90943577,6563666.03380959],[1216590.12376481,6563674.25425166],[1216638.02117068,6563672.7521636],[1216684.63088244,6563661.58935797],[1216728.03512655,6563641.225175],[1216752.29181681,6563626.67066235],[1216787.17700448,6563601.12371718],[1216816.83970763,6563569.63465531],[1216831.39332728,6563551.03748989],[1216838.2508451,6563541.8226918],[1216897.47283376,6563458.0765492],[1216918.74007329,6563421.44644481],[1216933.156564,6563381.60258193],[1216940.26085904,6563339.82061228],[1216939.82562707,6563297.43819918],[1216931.86491641,6563255.81218836],[1216907.60647856,6563170.91644364],[1216887.20280767,6563121.46139137],[1216856.24799209,6563077.86160203],[1216821.48046704,6563039.0529759],[1216799.23490474,6563017.28929875],[1216753.95673639,6562978.48086898],[1216737.29066155,6562965.4435638],[1216673.22488836,6562919.79826372],[1216644.73178636,6562899.22061724],[1216601.13622245,6562874.31962206],[1216562.32695185,6562857.3410734],[1216556.56069412,6562854.90900462],[1216549.97837146,6562852.23502385],[1216545.77480552,6562849.58841453],[1216504.75306873,6562829.03095075],[1216487.0229317,6562822.21187019],[1216482.65368148,6562820.3796627],[1216478.79578194,6562814.49158384],[1216462.95127963,6562793.04723497],[1216450.44559886,6562777.97698661],[1216448.65520854,6562774.19751598],[1216429.39331353,6562740.84427663],[1216404.99213055,6562711.06486155],[1216382.3528849,6562687.61801865],[1216357.97638417,6562665.64947943],[1216339.38004804,6562651.09634054],[1216299.24217837,6562625.743469],[1216254.86196793,6562608.94292463],[1216208.02902037,6562601.37212065],[1216160.63182011,6562603.33631786],[1216114.58159971,6562614.75632195],[1216071.73529105,6562635.17167463],[1216033.82066317,6562663.75921023],[1216002.36666225,6562699.36623124],[1215978.64176027,6562740.55696848],[1215963.60279766,6562785.67045603],[1215957.85638339,6562832.88749107],[1215961.63441126,6562880.30398198],[1215963.25125904,6562889.19806131],[1215964.03213898,6562893.28933659],[1215968.1319511,6562913.79137984],[1215972.03222389,6562937.19708669],[1215977.28745991,6563016.79645952],[1215971.45390521,6563048.0427099],[1215969.39172682,6563061.09023781],[1215963.73069651,6563104.75131293],[1215962.06592533,6563123.22251112],[1215960.00953034,6563163.6421848],[1215954.35640427,6563213.80082903],[1215954.63230125,6563269.34572034],[1215960.29082704,6563315.43307246],[1215970.70253119,6563361.57391952],[1215982.82982632,6563397.95907391],[1216001.20120538,6563439.38870108],[1216027.10825421,6563476.54992802],[1216059.60193364,6563508.08124916],[1216097.4918555,6563532.82739871],[1216139.38989254,6563549.8816932],[1216183.76104002,6563558.61926572],[1216228.97966418,6563558.71997125],[1216273.38907516,6563550.18012236],[1216287.1346647,6563546.13717455],[1216332.92682121,6563527.24586381],[1216373.78586258,6563499.1986745],[1216374.67364018,6563498.44078949]]]}
I'm going to assume that geojson_1 is available as a string in which case:
import json
output = {'geometry': json.loads(geojson_1)}
...will give you a dictionary with the structure you need.
It looks like plain json data, or a string representation of a dict (they wouldn't be any different in this case), did you consider wrapping the returned data in a new dict rather than manipulating it as a string?
import json
# Assume this returns the geojson as text
geojson = json.loads(get_geojson())
geojson = {"geometry": geojson}
print(json.dumps(geojson))
I get the expected result using the following:
'{"geometry":' + d + "}"
It adds the string {"geometry": to the string d and at the end }.
The variable dis:
d = '{"type":"Polygon","co (rest of json) ,6563498.44078949]]]}'
Or you can use the json library for this:
import json
data = json.loads(d) # note d is the same string as above, this can also be from a file or read file using json.load(FILE)
# Create your new object:
result = {'geometry': data}
# print you new json:
print( json.dumps(result, indent=2))
edit:
'"geometry":{' + d + "}"
Note that you get a string starting with geometry and a { and directly another { from you input json. This is not a correct dictionary nor a proper json format.
Result:
'"geometry":{{"type":"Polygon", ... ,6563498.44078949]]]}}'
(the dots are just the rest of your original json.

Sanitizing JSON Strings without \

Given successful query from SQL SELECT result, there are json output with \n and \ . That makes me confusions and obstacles to deserialise the json string into array of objects. Would you please tell me the way to replace all those json strings without newlines , spaces, and also blackslashes \ ?
dicts = [dict(row) for row in result]
j = json.dumps(dicts , sort_keys=True,
indent=None,
default=default , separators=(',', ':'))
return {
'result': j
}
Here is my output json with many back slashes \
{"result": "[{\"_access\":[{\"level\":\"read\",\"public\":true}],\"_created_at\":\"2019-05-26T09:57:10.494525\",\"_created_by\":\"473ee711-19a0-4309-8cb2-7f672fd93224\",\"_database_id\":\"\",\"_id\":\"3f674e29-29ba-4dcf-b9d9-f99a3c35866e\",\"_owner_id\":\"473ee711-19a0-4309-8cb2-7f672fd93224\",\"_updated_at\":\"2019-05-26T10:01:14.691527\",\"_updated_by\":\"473ee711-19a0-4309-8cb2-7f672fd93224\",\"book_label\":\"B198\",\"deleted_at\":null,\"deleted_by\":null,\"free_assign_date\":null,\"free_assign_end_date\":null,\"is_completed\":false,\"is_free_assigned\":true,\"progress_chapter\":1,\"total_chapters\":2,\"user_label\":\"user10\"}]"}
The ["result"] entry in the dict is a string. You just simply need to parse it. json.dumps does the opposite of what you are looking for - converts JSON to a string. You want json.loads, which converts a string to JSON data.
import json
result_str = "[{\"_access\":[{\"level\":\"read\",\"public\":true}],\"_created_at\":\"2019-05-26T09:57:10.494525\",\"_created_by\":\"473ee711-19a0-4309-8cb2-7f672fd93224\",\"_database_id\":\"\",\"_id\":\"3f674e29-29ba-4dcf-b9d9-f99a3c35866e\",\"_owner_id\":\"473ee711-19a0-4309-8cb2-7f672fd93224\",\"_updated_at\":\"2019-05-26T10:01:14.691527\",\"_updated_by\":\"473ee711-19a0-4309-8cb2-7f672fd93224\",\"book_label\":\"B198\",\"deleted_at\":null,\"deleted_by\":null,\"free_assign_date\":null,\"free_assign_end_date\":null,\"is_completed\":false,\"is_free_assigned\":true,\"progress_chapter\":1,\"total_chapters\":2,\"user_label\":\"user10\"}]"
js_obj = json.loads(result_str)
print json.dumps(js_obj)
have a try

Convert a python bytes to a dict or json, when bytes is not in object notation

How do you convert a bytes type to a dict, when the bytes aren’t in a json/object format?
example
request.body = b'Text=this&Voice=that' to something like
request.body => {'Text' : 'this', 'Voice' : 'that'}
Python 3.5 or 3.6?
Since = and & in names/values should be encoded, you can do something like:
r = b'Text=this&Voice=that'
postdata = dict(s.split(b"=") for s in r.split(b"&"))
print(postdata)
The above should output:
{b'Text': b'this', b'Voice': b'that'}
And in case you want to get rid of the bytes:
r = b'Text=this&Voice=that'
r = r.decode("utf-8") #here you should add your encoding, with utf-8 you are mostly covered for ascii as well
postdata = dict([s.split("=") for s in r.split("&")])
print(postdata)
which should print:
{'Text': 'this', 'Voice': 'that'}
Use the standard parse_qs:
from urllib.parse import parse_qs
from typing import List, Dict
s = request.body.decode(request.body, request.charset)
query:Dict[str,List[str]= parse_qs(s)
(It is unusual that this query-string is in the request.body, but if it is, this is how you do it.)

How to parameterize JSON object in a Python script

I am writing a test in Python where i am specifying the JSON sting in a parameter as follows :
json = '...[{"MemberOperand":{
"AttributeName":"TEST",
"Comparison":"=",
"Value":"Test"}
}]...'
In this example i have the value as "Test" however i want to run the test with several values. Could you guys tell me how can i parameterize The values of "Value"?
You can construct proper JSON:
import json
the_value = 'Test'
data = [{"MemberOperand": {
"AttributeName":"TEST",
"Comparison":"=",
"Value": the_value}
}]
json_text = json.dumps(data)
This is regular dictionary (nested) formatted as string -
def changer(x):
import json
d=json.loads(json.loads(json.dumps('[{"MemberOperand":{"AttributeName":"TEST","Comparison":"=","Value":"Test"}}]')))
d[0]['MemberOperand']['AttributeName']=x
return d
print changer('New_TEST')
Output-
[{'MemberOperand': {'Comparison': '=', 'AttributeName': 'New_TEST', 'Value': 'Test'}}]
Add function which return you different json string all the time by provided value as parameter:
def get_mock_json(value='Test'):
return '...[{"MemberOperand":{"AttributeName":"TEST","Comparison":"=","Value":%s}}]...'%value
print get_mock_json('test')
print get_mock_json('ttttttest')

Python: json.loads returns items prefixing with 'u'

I'll be receiving a JSON encoded string from Objective-C, and I am decoding a dummy string (for now) like the code below. My output comes out with character 'u' prefixing each item:
[{u'i': u'imap.gmail.com', u'p': u'aaaa'}, {u'i': u'333imap.com', u'p': u'bbbb'}...
How is JSON adding this Unicode character? What's the best way to remove it?
mail_accounts = []
da = {}
try:
s = '[{"i":"imap.gmail.com","p":"aaaa"},{"i":"imap.aol.com","p":"bbbb"},{"i":"333imap.com","p":"ccccc"},{"i":"444ap.gmail.com","p":"ddddd"},{"i":"555imap.gmail.com","p":"eee"}]'
jdata = json.loads(s)
for d in jdata:
for key, value in d.iteritems():
if key not in da:
da[key] = value
else:
da = {}
da[key] = value
mail_accounts.append(da)
except Exception, err:
sys.stderr.write('Exception Error: %s' % str(err))
print mail_accounts
The u- prefix just means that you have a Unicode string. When you really use the string, it won't appear in your data. Don't be thrown by the printed output.
For example, try this:
print mail_accounts[0]["i"]
You won't see a u.
Everything is cool, man. The 'u' is a good thing, it indicates that the string is of type Unicode in python 2.x.
http://docs.python.org/2/howto/unicode.html#the-unicode-type
The d3 print below is the one you are looking for (which is the combination of dumps and loads) :)
Having:
import json
d = """{"Aa": 1, "BB": "blabla", "cc": "False"}"""
d1 = json.loads(d) # Produces a dictionary out of the given string
d2 = json.dumps(d) # Produces a string out of a given dict or string
d3 = json.dumps(json.loads(d)) # 'dumps' gets the dict from 'loads' this time
print "d1: " + str(d1)
print "d2: " + d2
print "d3: " + d3
Prints:
d1: {u'Aa': 1, u'cc': u'False', u'BB': u'blabla'}
d2: "{\"Aa\": 1, \"BB\": \"blabla\", \"cc\": \"False\"}"
d3: {"Aa": 1, "cc": "False", "BB": "blabla"}
Those 'u' characters being appended to an object signifies that the object is encoded in Unicode.
If you want to remove those 'u' characters from your object, you can do this:
import json, ast
jdata = ast.literal_eval(json.dumps(jdata)) # Removing uni-code chars
Let's checkout from python shell
>>> import json, ast
>>> jdata = [{u'i': u'imap.gmail.com', u'p': u'aaaa'}, {u'i': u'333imap.com', u'p': u'bbbb'}]
>>> jdata = ast.literal_eval(json.dumps(jdata))
>>> jdata
[{'i': 'imap.gmail.com', 'p': 'aaaa'}, {'i': '333imap.com', 'p': 'bbbb'}]
Unicode is an appropriate type here. The JSONDecoder documentation describe the conversion table and state that JSON string objects are decoded into Unicode objects.
From 18.2.2. Encoders and Decoders:
JSON Python
==================================
object dict
array list
string unicode
number (int) int, long
number (real) float
true True
false False
null None
"encoding determines the encoding used to interpret any str objects decoded by this instance (UTF-8 by default)."
The u prefix means that those strings are unicode rather than 8-bit strings. The best way to not show the u prefix is to switch to Python 3, where strings are unicode by default. If that's not an option, the str constructor will convert from unicode to 8-bit, so simply loop recursively over the result and convert unicode to str. However, it is probably best just to leave the strings as unicode.
I kept running into this problem when trying to capture JSON data in the log with the Python logging library, for debugging and troubleshooting purposes. Getting the u character is a real nuisance when you want to copy the text and paste it into your code somewhere.
As everyone will tell you, this is because it is a Unicode representation, and it could come from the fact that you’ve used json.loads() to load in the data from a string in the first place.
If you want the JSON representation in the log, without the u prefix, the trick is to use json.dumps() before logging it out. For example:
import json
import logging
# Prepare the data
json_data = json.loads('{"key": "value"}')
# Log normally and get the Unicode indicator
logging.warning('data: {}'.format(json_data))
>>> WARNING:root:data: {u'key': u'value'}
# Dump to a string before logging and get clean output!
logging.warning('data: {}'.format(json.dumps(json_data)))
>>> WARNING:root:data: {'key': 'value'}
Try this:
mail_accounts[0].encode("ascii")
Just replace the u' with a single quote...
print (str.replace(mail_accounts,"u'","'"))

Categories

Resources