I try to get a List from a config.ini file using JSON in python but when I use " ' " for the string value in my list I get an error. Surprisingly I don't have it when I use " " ".
Python Code :
from configparser import ConfigParser
import json
#set and read the config file
config = ConfigParser()
config.read('config.ini')
#get the list with : ""
thisworks = json.loads(config.get('VALUES','value1'))
#get the list with : ''
thisnotwork = json.loads(config.get('VALUES','value2'))
config.ini file :
[VALUES]
value1 = ["tes1", "test2", "test3"]
value2 = ['tes1', 'test2', 'test3']
The variable "thisnotwork" return this error:
Traceback (most recent call last):
File "U:\Desktop\Nouveau dossier (2)\test.py", line 11, in <module>
thisnotwork = json.loads(config.get('VALUES','value2'))
File "C:\Python37\lib\json\__init__.py", line 348, in loads
return _default_decoder.decode(s)
File "C:\Python37\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Python37\lib\json\decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 2 (char 1)
[Finished in 0.258s]
This can be annoying because json.dumps() return 'string' and not "string". If someone has a solution for this it can be really helpful.
JSON Specification requires double quotes to be used for string values.
I tried json.dumps(['foo', 'bar']) and it outputs double quotes as expected.
maybe you can change the single quotations in config.ini list to double quotations like below:
value2= ['test1', 'test2', 'test3']
f'''"value2" : {str(value2).replace("'", '"')},\n'''
with the output of
value2= ["test1", "test2", "test3"]
Related
I have the following code snippet:
input = "You can check it out here. https://www.youtube.com/watch?v=Ay1gCPAUnxo&t=83s I'll send $20 in bitclout to the first 50 people that follow instructions at end of the video. This is revolutionary. Let's hope it works! <3Building it. What's up y'all"
def createJsonText(input):
input = r'{}'.format(input)
x = r'{ "text":"' + input + r'"}'
print(x)
# parse x as json
y = json.loads(x)
f = open("tone.json", "a")
f.write(str(y))
f.close()
When I execute the aforementioned code I get the following error:
File "hashtag-analyzer.py", line X, in readJson
createJsonText(input) File "hashtag-analyzer.py", line Y, in createJsonText
y = json.loads(x) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/init.py",
line 354, in loads
return _default_decoder.decode(s) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/decoder.py",
line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/decoder.py",
line 355, in raw_decode
obj, end = self.scan_once(s, idx) json.decoder.JSONDecodeError: Expecting ',' delimiter: line 1 column 4194 (char 4193)
How to resolve this?
Expected output is a json file with name, "tone.json" and the following data inside:
{
"text": "You can check it out here. https://www.youtube.com/watch?v=Ay1gCPAUnxo&t=83s I'll send $20 in bitclout to the first 50 people that follow instructions at end of the video. This is revolutionary. Let's hope it works! <3Building it. What's up y'all"
}
You're going the wrong direction here, if you want to create JSON. You want dumps, not loads':
def createJsonText(txt):
x = {'text': txt}
y = json.dumps(x)
open('tone.json','w').write(y)
Your code had mode='a' for append, but a set of separate JSON lines is NOT a valid JSON file. If you want it to be a valid JSON file, you need the whole file to be one document.
Update
Alternatively:
def createJsonText(txt):
json.dump({'text':txt}, open('tone.json','w'))
def state_manager(self, action):
# Define initialized state, default values.
initialized_state = {'access_token': None,
'refresh_token': None,
'token_expires_at': 0,
'authorization_url': None,
'redirect_code': None,
'token_scope': '',
'loggedin': False}
dir_path = r"C:\Users\kevin\Desktop\TDClient"
filename = 'TDAmeritradeState.json'
file_path = os.path.join(dir_path, filename)
# if the state is initialized
if action == 'init':
self.state = initialized_state
# if allowed cache load the file
if self.config['cache_state'] and os.path.isfile(file_path):
with open(file_path, 'r') as fileHandle:
self.state.update(json.load(fileHandle))
# If not allowed cache delete file
elif not self.config['cache_state'] and os.path.isfile(file_path):
os.remove(file_path)
# save and cache allowed load file
elif action == 'save' and self.config['cache_state']:
with open(file_path, 'w') as fileHandle:
# Build JSON string using dictionary comprehension.
json_string = {key:self.state[key] for key in initialized_state}
json.dump(json_string, fileHandle)
Full Trace Back:
> File "C:\Users\kevin\Desktop\TDClient\TDApi.py", line 47, in __init__
> self.state_manager('init') File
> "C:\Users\kevin\Desktop\TDClient\TDApi.py", line 101, in state_manager
> self.state.update(json.load(fileHandle)) File
> "C:\Users\kevin\AppData\Local\Programs\Python\Python38-32\lib\json\__init__.py",
> line 293, in load return loads(fp.read(), File
> "C:\Users\kevin\AppData\Local\Programs\Python\Python38-32\lib\json\__init__.py",
> line 357, in loads return _default_decoder.decode(s) File
> "C:\Users\kevin\AppData\Local\Programs\Python\Python38-32\lib\json\decoder.py",
> line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end())
> File
> "C:\Users\kevin\AppData\Local\Programs\Python\Python38-32\lib\json\decoder.py",
> line 355, in raw_decode raise JSONDecodeError("Expecting value", s,
> err.value) from None json.decoder.JSONDecodeError: Expecting value:
> line 1 column 1 (char 0) Expecting value: line 1 column 1 (char 0)
Hello, I am receiving this error, when I place the file_path into my code. When I put anything else into the os.path.isfile(), no error occurs. But when I reference my directory to the json file I want to save it to, it returns this error.
The information I am receiving is from TDameritrade, and it is in json format I believe, I do not know what am I doing wrong, and im referencing the directory incorrectly?
Expecting value: line 1 column 1 (char 0) Expecting value: line 1 column 1 (char 0)
Seems it fails while trying to parse empty JSON
If you’ve pulled JSON data in from another program or have otherwise obtained a string of JSON formatted data in Python, deserialize that with loads() instead of load()
I am fetching from database a text that is in a json format. Basically dumping an api content from a website to a db with TEXT field.
I can see the json content has no issues/errors, but when I do ..
try:
get_all = db.query("SELECT id, name, api_content FROM _books")
_result = get_all.fetchall()
except Exception as e:
print("[e::line-163] ", e)
try:
for r in _result:
api_content = r[2]
j = json.loads(api_content)
print('names, ', j['names'])
I get this error .
Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
The api_content has no issues, it is a well-formed json content.
I don't think you have a valid JSON in api_content. Judging by what the error is about, your properties (keys) are enclosed in single quotes but need to be enclosed in double quotes to be a valid JSON.
Here is what is happening:
>>> import json
>>> json.loads('{"key": "value"}') # <- VALID JSON
{'key': 'value'}
>>> json.loads("{'key': 'value'}") # <- INVALID JSON
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/__init__.py", line 319, in loads
return _default_decoder.decode(s)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/json/decoder.py", line 355, in raw_decode
obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
In other words, you should revise the way you dump the API contents into the database. It looks like you are just writing string representations of Python dictionary objects instead of using json.dumps().
If you cannot change that, try using ast.literal_eval() to safely eval the api content:
from ast import literal_eval
for r in _result:
api_content = r[2]
j = literal_eval(api_content)
print('names, ', j['names'])
I'm trying to parse a XML file using xml ElementTree and json
from xml.etree import ElementTree as et
import json
def parse_file(file_name):
tree = et.ElementTree()
npcs = {}
for npc in tree.parse(file_name):
quests = []
for quest in npc:
quest_name = quest.attrib['name']
stages = []
for i, stage in enumerate(quest):
next_stage, choice, npc_condition = None, None, None
for key, val in stage.attrib.items():
val = json.loads(val)
if key == 'choices':
choice = val
elif key == 'next_stage':
next_stage = val
elif key == 'ncp_condition':
npc_condition = {stage.attrib['npc_name']: val}
stages.append([i, next_stage, choice, npc_condition])
quests.append( {quest_name:stages})
npcs[npc.attrib['name']] = quests
return npcs
The XML file:
<?xml version="1.0" encoding="utf-8"?>
<npcs>
<npc name="NPC NAME">
<quest0 name="Quest Name here">
<stage0 choices='{"Option1":1, "Option1":2}'>
<text>text1</text>
</stage0>
<stage1 next_stage="[3,4]">
<text>text2</text>
</stage1>
<stage3 npc_name="other_npc_name" ncp_condition='{"some_condition":false}' next_stage="[3, 4]">
<text>text3</text>
</stage3>
</quest0>
</npc>
</npcs>
But I'm having trouble with this bit:
<stage3 npc_name="other_npc_name" ncp_condition='{"some_condition":false}' next_stage="[3, 4]">
Traceback:
Traceback (most recent call last):
File "C:/.../test2.py", line 28, in <module>
parse_file('quests.xml')
File "C:/.../test2.py", line 15, in parse_file
val = json.loads(val)
File "C:\Python27\lib\json\__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "C:\Python27\lib\json\decoder.py", line 366, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Python27\lib\json\decoder.py", line 384, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
It raises this error in the line val = json.loads(val) when key="npc_name" and val="other_npc_name".
What's wrong with that? It didn't raise any error when name="some string", but it does when npc_name="some string".
I noticed that if I change "other_npc_name" to '"other_npc_name"' it doesn't complain, but this seem a bit hackish to me
JSON is a way to store data structures - thus it can only decode said data structures.
When you try to get JSON to decode something like this:
other_npc_name
JSON can't match this to any valid data type. However, if this is wrapped in quotation marks:
"other_npc_name"
JSON recognizes this as a String (as per the JSON spec, that is how a string is defined).
And this is what is happening in your script:
import json
print json.loads("other_npc_name") #throws error
print json.loads('"other_npc_name"') #returns "other_npc_name" as a Unicode string
Thus, it may seem 'hackish' to wrap the string this way, however, this is really the only way for JSON to decode it.
One potential suggestion is that if the npc_name attribute in XML is always a string, then pull it out as a string instead of trying to decode it as a JSON object.
I'm trying to parse a json result from the next google Query:
http://www.google.com/ig/calculator?hl=en&q=1USD=?MXN
The result is this:
{lhs: "1 U.S. dollar",rhs: "13.3317335 Mexican pesos",error: "",icc: true}
So i'm just trying to decode with this:
import json, urllib2
j=urllib2.urlopen("http://www.google.com/ig/calculator?hl=en&q=1USD=?MXN")
print json.load(j)
But i'm having this error (Traceback):
Traceback (most recent call last):
File "/home/rafael/gitSources/PythonConcept/Monpy/negApi.py", line 4, in <module>
print json.load(j)
File "/usr/lib/python2.7/json/__init__.py", line 278, in load
**kw)
File "/usr/lib/python2.7/json/__init__.py", line 326, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/json/decoder.py", line 366, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Expecting property name: line 1 column 1 (char 1)
[Finished in 0.6s with exit code 1]
I don't know what i'm doing wrong, I just read many tutorials :/
Thanks :)!
This is not JSON but you can still parse it yourself - like this:
import ast
resp = '{lhs: "1 U.S. dollar",rhs: "13.3317335 Mexican pesos",error: "",icc: true}'
d = {}
for pair in resp[1:-1].split(','):
(k,v) = pair.split(':')
v = v.strip()
if v == "true":
v = "True"
try:
v = ast.literal_eval(v)
except:
print "Couldn't eval " + v
d[k] = v
print d
You could also fix up the formatting to be json and then use the json parser like this:
import json
resp = '{lhs: "1 U.S. dollar",rhs: "13.3317335 Mexican pesos",error: "",icc: true}'
s = "{"
for pair in resp[1:-1].split(','):
(k,v) = pair.split(':')
s += '"%s" : %s,' % (k,v)
s = s[:-1] + "}"
print json.loads(s)
You can use rate-exchange.appspot.com, which uses the Google API but returns valid json:
http://rate-exchange.appspot.com/currency?from=USD&to=MXN&q=1
{"to": "MXN", "rate": 12.7523369, "from": "USD", "v": 12.7523369}
Here's how to use it with requests:
>>> import requests
>>> r = requests.get('http://rate-exchange.appspot.com/currency?from=USD&to=MXN&q=1')
>>> r.json['v']
12.7523369
Here is what you should do:
import re
s = '{lhs: "1 U.S. dollar",rhs: "13.3317335 Mexican pesos",error: "",icc: true}'
only_numbers=re.sub(r'[^0-9,.]+', '', s)
m = re.match(r"(\d+..),(\d+.\d+),,", only_numbers)
currency=m.group(2)
output: 13.3317335