Python dpath.util.get Empty string keys Error - python

I read in a simple JSON text file and it parses to a dict just fine.
>>> data.keys()
dict_keys(['metadata', 'value'])
I want to get specific elements and I typically use the dpath package. However, in this case i get an error which seems to imply that I
dpath.util.get(data, 'metadata', separator='..')
InvalidKeyName: Empty string keys not allowed without dpath.options.ALLOW_EMPTY_STRING_KEYS=True
I don't see any empty string keys, only the two above. I can reproduce with some other seemingly random JSON text files but for others it works just fine. Any idea what is going on here?

Searching this error message in the library's codebase finds dpath/path.py:88:
for (k, v) in iteritems:
if issubclass(k.__class__, (string_class)):
if (not k) and (not dpath.options.ALLOW_EMPTY_STRING_KEYS):
raise dpath.exceptions.InvalidKeyName("Empty string keys not allowed without "
"dpath.options.ALLOW_EMPTY_STRING_KEYS=True")
So, this error is raised when your data structure has empty keys.

Related

Key 'boot_num' is not recognized when being interpreted from a .JSON file

Currently, I am working on a Boot Sequence in Python for a larger project. For this specific part of the sequence, I need to access a .JSON file (specs.json), establish it as a dictionary in the main program. I then need to take a value from the .JSON file, and add 1 to it, using it's key to find the value. Once that's done, I need to push the changes to the .JSON file. Yet, every time I run the code below, I get the error:
bootNum = spcInfDat['boot_num']
KeyError: 'boot_num'`
Here's the code I currently have:
(Note: I'm using the Python json library, and have imported dumps, dump, and load.)
# Opening of the JSON files
spcInf = open('mki/data/json/specs.json',) # .JSON file that contains the current system's specifications. Not quite needed, but it may make a nice reference?
spcInfDat = load(spcInf)
This code is later followed by this, where I attempt to assign the value to a variable by using it's dictionary key (The for statement was a debug statement, so I could visibly see the Key):
for i in spcInfDat['spec']:
print(CBL + str(i) + CEN)
# Loacting and increasing the value of bootNum.
bootNum = spcInfDat['boot_num']
print(str(bootNum))
bootNum = bootNum + 1
(Another Note: CBL and CEN are just variables I use to colour text I send to the terminal.)
This is the interior of specs.json:
{
"spec": [
{
"os":"name",
"os_type":"getwindowsversion",
"lang":"en",
"cpu_amt":"cpu_count",
"storage_amt":"unk",
"boot_num":1
}
]
}
I'm relatively new with .JSON files, as well as using the Python json library; I only have experience with them through some GeeksforGeeks tutorials I found. There is a rather good chance that I just don't know how .JSON files work in conjunction with the library, but I figure that it would still be worth a shot to check here. The GeeksForGeeks tutorial had no documentation about this, as well as there being minimal I know about how this works, so I'm lost. I've tried searching here, and have found nothing.
Issue Number 2
Now, the prior part works. But, when I attempt to run the code on the following lines:
# Changing the values of specDict.
print(CBL + "Changing values of specDict... 50%" + CEN)
specDict ={
"os":name,
"os_type":ost,
"lang":"en",
"cpu_amt":cr,
"storage_amt":"unk",
"boot_num":bootNum
}
# Writing the product of makeSpec to `specs.json`.
print(CBL + "Writing makeSpec() result to `specs.json`... 75%" + CEN)
jsonobj = dumps(specDict, indent = 4)
with open('mki/data/json/specs.json', "w") as outfile:
dump(jsonobj, outfile)
I get the error:
TypeError: Object of type builtin_function_or_method is not JSON serializable.
Is there a chance that I set up my dictionary incorrectly, or am I using the dump function incorrectly?
You can show the data using:
print(spcInfData)
This shows it to be a dictionary, whose single entry 'spec' has an array, whose zero'th element is a sub-dictionary, whose 'boot_num' entry is an integer.
{'spec': [{'os': 'name', 'os_type': 'getwindowsversion', 'lang': 'en', 'cpu_amt': 'cpu_count', 'storage_amt': 'unk', 'boot_num': 1}]}
So what you are looking for is
boot_num = spcInfData['spec'][0]['boot_num']
and note that the value obtained this way is already an integer. str() is not necessary.
It's also good practice to guard against file format errors so the program handles them gracefully.
try:
boot_num = spcInfData['spec'][0]['boot_num']
except (KeyError, IndexError):
print('Database is corrupt')
Issue Number 2
"Not serializable" means there is something somewhere in your data structure that is not an accepted type and can't be converted to a JSON string.
json.dump() only processes certain types such as strings, dictionaries, and integers. That includes all of the objects that are nested within sub-dictionaries, sub-arrays, etc. See documentation for json.JSONEncoder for a complete list of allowable types.

Getting exception "openpyxl.utils.exceptions.IllegalCharacterError"

I am extracting data from an Oracle 11g Database using python and writing it to an Excel file. During extraction, I'm using a python list of tuples (each tuple indicates each row in dataset) and the openpyxl module to write the data into Excel. It's working fine for some datasets but for some, it's throwing the exception:
openpyxl.utils.exceptions.IllegalCharacterError
This is the solution I've already tried:
Openpyxl.utils.exceptions.IllegalcharacterError
Here is my Code:
for i in range(0,len(list)):
for j in range(0,len(header)):
worksheet_ntn.cell(row = i+2, column = j+1).value = list[i][j]
Here is the error message:
raise IllegalCharacterError
openpyxl.utils.exceptions.IllegalCharacterError
I did get this error because of some hex charactres in some of my strings.
'Suport\x1f_01'
The encode\decode solutions mess with the accente words too
So...
i resolve this with repr()
value = repr(value)
That give a safe representation, with quotation marks
And then i remove the first and last charactres
value = repr(value)[1:-1]
Now you can safe insert value on your cell
The exception tells you everything you need to know: you must replace the characters that cause the exception. This can be done using re.sub() but, seeing as only you can decide what you want to replace them with — spaces, empty strings, etc. — only you can do this.

Python 2.7 replace all instances of NULL / NONE in complex JSON object

I have the following code..
.... rest api call >> response
rsp = response.json()
print json2html.convert(rsp)
which results in the following
error: Can't convert NULL!
I therefore started looking into schemes to replace all None / Null's in my JSON response, but I'm having an issue since the JSON returned from the api is complex and nested many levels and I don't know where the NULL will actually appear.
From what I can tell I need to iterate over the dictionary objects recursively and check for any values that are NONE and actually rebuild the object with the values replaced, but I don't really know where to start since dictionary objects are immutable..
If you look at json2html's source it seems like you have a different problem - and the error message is not helping.
Try to use it like this:
print json2html.convert(json=rsp)
btw. because I've already contributed to that project a bit I've opened up the following PR due to this question: https://github.com/softvar/json2html/pull/20

How to Access a List through a key?

I have a program that has a save file full of lists. It Loads up the Items by making lists. It gets the Names from the file too. Since I couldn't "unstring" a string so I put the names as keys. My problem is re-saving the lists when you are done using the program. I cant seem to access the contents inside the list to write them to a file. I have another List with keys so I can access the Names.
ListKey = {1:'Food', 2:'Veggie'}
List={'Food':['apple','pear','grape'], 'Veggies':['carrot','Spinach','Potato']}
file.write(ListKey[1]) #works fine
currentList=ListKey[1]
file.write(List[currentList[1]]) #Doesn't Work
When I try to do the code above, I get a Key Error, I know it is trying to write the 'o' in food. Is there anyway to get around this?
It looks like you are trying to access a value inside your key pairs. Try:
List[currentList][0] to access 'apple'
List[currentList][1] to access 'pear'
etc...
alternatively if you want all the values, it would look like
List[currentList] or
List['Food']
Hope this helps, just your syntax of how to access the list inside.
edit:
https://docs.python.org/2/tutorial/datastructures.html#nested-list-comprehensions
(added link to data structure docs)
currentList[1] is just the value o, use:
file.write(List[currentList])
ListKey = {1:'Food', 2:'Veggie'}
List={'Food':['apple','pear','grape'], 'Veggies': ['carrot','Spinach','Potato']}
currentList = ListKey[1] #'Food'
currentList[1] # 'o'
You are actually indexing into the string "Food". Hence currentList[1] is 'o'. Since List has no key 'o' you get at key error.

Key error in dictionary - python

I have two dictionaries:
One is :
data_obt={'Sim_1':{'sig1':[1,2,3],'sig2':[4,5,6]},'Sim_2':{'sig3':[7,8,9],'sig4':[10,11,12]},'Com_1':{'sig5':[13,14,15],'sig6':[16,17,18]},'Com_2':{'sig7':[19,20,21],'sig9':[128,23,24]}}
Other one is:
simdict={'sig1':'Bit 1','sig2':'Bit 2','sig3':'Bit 3','sig4':'Bit 4','sig5':'Bit 5','sig6':'Bit 6','sig7':'Bit 7','sig9':''}
Now I have to do return_data[fpath].append(data_obt[key][item]), where fpath = 'sig9',key='Com_2' and item = 'sig9'
But when I tried to execute this it is throwing error like : KeyError: 'sig9'
My expected return_data is {'sig9':[128,23,24]}
Can anyone please help me out?
As I understand, return_data is another dict. If so, it doesn't (as of yet) have a key named fpath (which is 'sig9'). Hence, the error.
To avoid it, you should either use defaultdict, or initialize this element as an empty list every time you come across a new key.

Categories