I want to read the json values from config json file. The json object path I use in my python code is like below:
jsonfile['Data'][0]['Tenants'][0]['TenPropertyGroup']
Now I want to pass this above path "['Data'][0]['Tenants'][0]['TenPropertyGroup']" from ini file to make sure I can make changes in ini file if the object path gets changed in json file.
My config.ini looks like:
[CONFIG]
TenPropertyGroup= ['Data'][0]['Tenants'][0]['TenPropertyGroups']
My python code after reading from ini file looks like
globalconfig = "config.ini"
config = configparser.ConfigParser()
config.read(globalconfig)
f = open(configfile, )
jsonfile = json.load(f)
TenPropertyGroup = config['CONFIG']['TenPropertyGroup']
TenPropertyGroups = (str(jsonfile ) + TenPropertyGroup)
But when I am reading in Python using configparser the above PropertyGroup is of string data type and I am not able to get the list from json file.
I am trying to read this ini properly from python code but not able to convert it to object.
I would suggest a different approach. You should avoid executing text read from a file for security reasons. If you use a different format for you ini file value, you could parse it and use the values to drill down into you json object. Here's a simple example:
path_from_ini = 'x/y/z'
json_dict = { 'x' : { 'y' : { 'z' : 42 } } }
parts = path_from_ini.split('/')
v = json_dict
# Drill down into the JSON dictonary
for p in parts:
v = v[p]
print(v)
Related
I have an empty json file which I'm trying to update based on user input.
Initially there is no content inside the json file.
I've created an endpoint to take input from the user in following format via Flask app :
{
"register_address_lower":40201,
"register_address_upper":40202,
"unit":"gal/min"
}
So after getting the input for first time the content of the json file looks like this :
{"40201": "gal/min", "40202": "gal/min"}
Now after getting new user inputs I just want to update the same object in the json file without creating a new object in it.
Suppose the new input is :
{
"register_address_lower":40801,
"register_address_upper":40803,
"unit":"gal/min"
}
The content inside my json file now should be : -
{"40201": "gal/min", "40202": "gal/min", "40801": "gal/min", "40802": "gal/min", "40803": "gal/min"}
This is the block of code I'm using :
#app.route("/config",methods=["Post"])
def update_json():
response = request.json
with open("config.json", 'r+') as file:
json_file = json.load(file)
for res_address in range(response['register_address_lower'],response['register_address_upper']+1):
new_reg = {str(res_address):response['unit']}
json_file.update(new_reg)
#json_file[res_address]=response['unit']
json.dump(json_file, file)
And the result I'm getting by passing the above given examples is : -
{"40201": "gal/min", "40202": "gal/min"}{"40201": "gal/min",
"40202": "gal/min", "40801": "gal/min", "40802": "gal/min", "40803": "gal/min"}
The file you are opening in is in 'r+' mode, so you are reading from it, but when you dump to it you start after the contents that are already there. The 2nd object in the file is the expected output as I understand it.
You need to overwrite the file outside the with you currently have.
The below is an untested rewrite:
#app.route("/config",methods=["Post"])
def update_json():
response = request.json
with open("config.json", 'r+') as file:
json_file = json.load(file)
for res_address in range(response['register_address_lower'],response['register_address_upper']+1):
new_reg = {str(res_address):response['unit']}
json_file.update(new_reg)
#json_file[res_address]=response['unit']
with open("config.json", 'w') as file:
json.dump(json_file, file)
Brand new to stack and python; hopefully someone wiser than myself can help. I have searched up and down and can't seem to find an actual answer to this, apologies if there is an exact answer and I've missed it :( (the few that I've found are either old or don't seem to work).
Closest I've found is
Best way to retrieve variable values from a text file?
Alas, imp seems to be depreciated and tried figuring out importlib but little above my current brain to figure out how to adapt it as errors throw up left and right on me.
This is very close to what I want and could potentially work if someone can help update with new methods, alas still doesn't have how to overwrite the old variable.
= - - Scenario - - =
I would like to create a preferences file (let's call it settings.txt or settings.py: doesn't need to be cross-compatible with other languages, but some reason I'd prefer txt - any preference/standards coders can impart would be appreciated?).
\\\ settings.txt\
water_type = "Fresh"\
measurement = "Metric"\
colour = "Blue"\
location = "Bottom"\
...
I am creating a script main_menu.py which will read variables in settings.txt and write to this file if changes are 'saved'
ie.
"select water type:"
Fresh
Salt
if water_type is the same as settings.txt, do nothing,
if water_type different, overwrite the variable in the settings.txt file
Other scripts down the line will also read and write to this settings file.
I've seen:
from settings import *
Which seems to work for reading the file if I go the settings.py path but still leaves me on how do I overwrite this.
also open to any better/standard/ideas you guys can think of.
Appreciate any help on this!
Here are some suggestions that may help you:
Use a json file:
settings.json
{
"water_type": "Fresh",
"measurement": "Metric",
"colour": "Blue",
"location": "Bottom",
...
}
then in python:
import json
# Load data from the json file
with open("settings.json", "r") as f:
x = json.load(f) # x is a python dictionary in this case
# Change water_type in x
x["water_type"] = "Salt"
# Save changes
with open("settings.json", "w") as f:
json.dump(x, f, indent=4)
Use a yaml file: (edit: you will need to install pyyaml)
settings.yaml
water_type: Fresh
measurement: Metric
colour: Blue
location: Bottom
...
then in python:
import yaml
# Load data from the yaml file
with open("settings.yaml", "r") as f:
x = yaml.load(f, Loader=yaml.FullLoader) # x is a python dictionary in this case
# Change water_type in x
x["water_type"] = "Salt"
# Save changes
with open("settings.yaml", "w") as f:
yaml.dump(x, f)
Use a INI file:
settings.ini
[Preferences]
water_type=Fresh
measurement=Metric
colour=Blue
location=Bottom
...
then in python:
import configparser
# Load data from the ini file
config = configparser.ConfigParser()
config.read('settings.ini')
# Change water_type in config
config["Preferences"]["water_type"] = "Salt"
# Save changes
with open("settings.ini", "w") as f:
config.write(f)
For .py config files, it's usually static options or settings.
Ex.
# config.py
STRINGTOWRITE01 = "Hello, "
STRINGTOWRITE02 = "World!"
LINEENDING = "\n"
It would be hard to save changes made to the settings in such a format.
I'd recommend a JSON file.
Ex. settings.json
{
"MainSettings": {
"StringToWrite": "Hello, World!"
}
}
To read the settings from this file into a Python Dictionary, you can use this bit of code.
import json # Import pythons JSON library
JSON_FILE = open('settings.json','r').read() # Open the file with read permissions, then read it.
JSON_DATA = json.loads(JSON_FILE) # load the raw text from the file into a json object or dictionary
print(JSON_DATA["MainSettings"]["StringToWrite"]) # Access the 'StringToWrite' variable, just as you would with a dictionary.
To write to the settings.json file you can use this bit of code
import json # import pythons json lib
JSON_FILE = open('settings.json','r').read() # Open the file with read permissions, then read it.
JSON_DATA = json.loads(JSON_FILE) # load the data into a json object or dictionary
print(JSON_DATA["MainSettings"]["StringToWrite"]) # Print out the StringToWrite "variable"
JSON_DATA["MainSettings"]["StringToWrite"] = "Goodnight!" # Change the StringToWrite
JSON_DUMP = json.dumps(JSON_DATA) # Turn the json object or dictionary back into a regular string
JSON_FILE = open('settings.json','w') # Reopen the file, this time with read and write permissions
JSON_FILE.write(JSON_DUMP) # Update our settings file, by overwriting our previous settings
Now, I've written this so that it is as easy as possible to understand what's going on. There are better ways to do this with Python Functions.
You guys are fast! I'm away from the computer for the weekend but had to log in just to say thanks.
I'll look into these more next week when I'm back at it and have some time to give it the attention needed. A quick glance could be a bit of fun to implement and learn a bit more.
Had to answer as adding comment only is on one of your guys solutions and wanted to give a blanket thanks to all!
Cheers
Here's a python library if you choose to do it this way.
If not this is also a good resource.
Creating a preferences file example
Writing preferences to file from python file
import json
# Data to be written
dictionary ={
"name" : "sathiyajith",
"rollno" : 56,
"cgpa" : 8.6,
"phonenumber" : "9976770500"
}
# Serializing json
json_object = json.dumps(dictionary, indent = 4)
# Writing to sample.json
with open("sample.json", "w") as outfile:
outfile.write(json_object)
Reading preferences from .json file in Python
import json
# open and read file content
with open('sample.json') as json_file:
data = json.load(json_file)
# print json file
print(data)
I have file where I have defined python dictionary:
dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First', 'Friends': {'Emil':1, 'Frank':0} };
I want to read this dictionary and use it's element in python code. I've end up with following code:
#!/usr/bin/python
import sys
import os
import ast
import re
from pprint import pprint as pp
def readObjFromFile(file):
with open (file, "r") as myfile:
data=myfile.read()
data = re.sub("^#.*", "", data)
data = data.replace('\n', '')
data = data.split("=", 1)[1].split(";", 1)[0].lstrip()
data = ast.literal_eval(data)
return data
if __name__ == "__main__":
if len(sys.argv[1:]) == 1:
dict = readObjFromFile(sys.argv[1])
print type(dict)
pp(dict)
else:
print "Pass file from which object will be read"
exit
This works also for this larger dictionary. I want to ask if there is better way to do it? I am aware of pickle module but this is not what I want because it stores data in it's own format. I was considering modules which are used for parsing json due to similarity with python dicts, but I do not know if this approach is safe.
I'm assuming that you don't have control over the file format and are being handed it from somewhere. It's close enough to json that I'd aim to make it json. I'd do something like the following:
lines = []
with open(file) as f:
for line in f:
if line[0] == "#":
continue
l = line.strip().split("=")[-1].strip(";")
lines.append(re.sub("'", "\"", l)
return json.loads("".join(lines))
The file you have really represents a human interpreted version of the dictionary. We can read it and see how there is a variable that we want to assign to a dictionary. What you really want to do is store the dict in a programatic friendly format. And JSON is a perfect use of this format. Other formats include XML and YAML, but Python natively and easily will read JSON input.
If you look closely at your example, you see that the sample data set has a dictionary with a nested dictionary. JSON is built for these kinds of use cases. So a JSON file with your data above would look like:
{
"Name": "Zara",
"Age": 7,
"Class": "First",
"Friends": {
"Emil":1,
"Frank":0
}
}
Note the sub-dictionary is part of the structure of the JSON file. Also note that double quotes are used.
Now you can easily have python do your work for you:
import json
from os import open
from pprint import pprint
data = open(filename).read()
d = json.loads(data)
pprint(d)
And you can access the submodules by using:
d['Friends]
I am trying to read a json file from python script using the json module. After some googling I found the following code:
with open(json_folder+json) as json_file:
json_data = json.loads(json_file)
print(json_data)
Where json_folder+json are the path and the name of the json file. I am getting the following error:
str object has no attribute loads.
The code is using json as a variable name. It will shadow the module reference you imported. Use different name for the variable.
Beside that, the code is passing file object, while json.loads accept a string.
Pass a file content:
json_data = json.loads(json_file.read())
or use json.load which accepts file-like object.
json_data = json.load(json_file)
import json
f = open( "fileToOpen.json" , "rb" )
jsonObject = json.load(f)
f.close()
it should seems you are doing in rather complicated way.
Try like this :-
json_data=open(json_file)
data = json.load(json_data)
json_data.close()
Considering the path to your json file is set to the variable json_file:
import json
with open(json_file, "rb") as f:
json_data = json.load(f)
print json_data
I Make This....
import urllib2
link_json = "\\link-were\\"
link_open = urllib2.urlopen(link_json) ## Open and Return page.
link_read = link_open.read() ## Read contains of page.
json = eval(link_read)[0] ## Transform the string of read in link_read and return the primary dictionary ex: [{dict} <- return this] <- remove this
print(json['helloKey'])
Hello World
I just started using/learning Python and have some questions.
I have a text file generated by the reporting tool.
The file contains some stuff like this. There are many stuff which basically follow the same format as the one written below.
Format=
{
Window_Type="Tabular",
Tabular=
{ Num_row_labels=5
}
}
There are named value attributes in this file.
For e.g., Window_Type is the name of the attribute having value Tabular.
Again for Tabular named attribute has a value 5 associated with it.
What I want to be able to do is Open up the file.
Check if Window_Type is Tabular
If yes, then check the Num_row_labels associated with Tabular.
If Num_row_lables has a value greater than or equal to 5, then print the name of the text file and the path of the folder, where that file exists.
I m using Python 3.2 in Eclipse 3.7.2 IDE.
For a testing part, I imported my text file in the IDE and used the code below to read the file. In future I should be able to traverse the folder/s where the files with extension mrk are located.(This will be a known directory because we keep those files in there.) Please kindly help me out. Thanks a bunch!
import os.path
fn = os.path.join(os.path.dirname(__file__), 'Multitab.mrk')
with open(fn, 'r') as file:
print(file.read())
Please note that this answer is a very dirty hack. That format is almost similar to JSON format, which prompted me to write an RE which will convert the string such that it can be cleanly parsed by json parser. This is what I did:
import re
import json
s = """Format= {
Window_Type="Tabular",
Tabular= { Num_row_labels=5 } }"""
s = "{" + re.sub(r'([a-zA-Z0-9_]+)=',r'"\1":', s) + "}"
obj = json.loads(s)
if obj['Format']['Window_Type'] == "Tabular":
print "Its tabular!"
numrows = obj['Format']['Tabular']['Num_row_labels']
print "Numrows:", numrows
if numrows >= 5:
print "Print this fileName"
OUTPUT:
Its tabular!
Numrows: 5
Print this fileName