WeInThis
WeInThis

Reputation: 547

Config Parser Python - How to read from json file?

I have created a profile.json file in the same folder as my script/.py is. It looks something like:

{
    "name": "",
    "lastname": "",
    "age": "",
    "city": "",
}

I'm looking to insert it into my script that got headers of:

"info": {
    "given_name": "",
    "given_Lastname": "",
    "given_age": "",
    "given_city": ""
}

I'm wondering how can I make it possible to read from my profile.json into my script? This is my first time using this and I'm also new into Python. I feel like this could be an easy way to modify information WITHOUT having to change the code every time.

EDIT:

Tried to do this:

with open('profile.json', encoding='UTF-8') as json_data: config = json.load(json_data) print(config)

then:

"info": 
       {
         "given_name": config.given_name
       }

the print is saying good information but when it comes to "given_name": config.given_name then im getting a error saying

AttributeError: 'dict' object has no attribute 'given_name'

Upvotes: 5

Views: 29583

Answers (2)

Kyle
Kyle

Reputation: 1066

There are some good suggestions from the comments on your original question. If you want to pull in configurable data from another file you can do two options from looking at your original question.

1. Use a json file

It looks like this is the first suggested answer and you can configure variables that you can use in your program from this JSON file. Assuming, the config.json file is in the current directory of your program you can do the following:

import json

with open('config.json', 'r') as config_file:
    config_data = json.load(config_file)

2. Use a python file

This is another option that you have just in case you don't want to deserialize the json when you load the configuration. You can keep everything as python datatypes so you just need to import it. In this example CONFIG_INFO is simply a dictionary that you can import into other scripts that require it. I usually use this for username/password/general configuration stuff at work.

config.py

CONFIG_INFO = {
    "given_name": "test name",
    "given_lastname": "test lastname",
    "given_age": 12,
    "given_city": "Seattle"
}

my_script.py

from config import CONFIG_INFO

print("Config City: {0}".format(CONFIG_INFO["given_city"]))
print("Config Name: {0}".format(CONFIG_INFO["given_name"]))
print("Config Lastname: {0}".format(CONFIG_INFO["given_lastname"]))
print("Config Age: {0}".format(CONFIG_INFO["given_age"]))

Upvotes: 4

Charles
Charles

Reputation: 4362

The problem is that you're trying to access a dictionary key as an attribute (ie: config["given_name"] vs config.given_name. You've also changed your question multiple times, but what you are trying to do (I think) is simple. For the trivial example you've given, where you have a json file with only one json object in it, this may be closer to what you're trying to do:

*Note: Your json syntax is wrong, it should be { "info": { ... } }

#!/usr/bin/env python3
'''profile.json:
{
    "name": "steve",
    "lastname": "jobs",
    "age": "70",
    "city": "heaven"
}
'''
import json
import io


# Open the JSON File and create a StringIO buffer to hold data
with open('profile.json', 'r') as datafile, io.StringIO() as data:
    # Load data into json file
    config = json.load(datafile)
    # Build json strong
    data.write(f'''{{
            \r\t"info": {{
            \r\t\t"given_name": "{config['name']}",
            \r\t\t"given_Lastname": "{config['lastname']}",
            \r\t\t"given_age": "{config['age']}",
            \r\t\t"given_city": "{config['city']}"
            \r\t}}\n}}''')
    print(data.getvalue())
    # open a new file to save the data (overwrite if it exists)
    with open('newfile.json', 'w') as outfile:
        # load the json string and dump to outfile
        deserialized = json.loads(data.getvalue())
        json.dump(deserialized, outfile)
        # newfile.json:
        #{
        #        "info": {
        #                "given_name": "steve",
        #                "given_Lastname": "jobs",
        #                "given_age": "70",
        #                "given_city": "heaven"
        #        }
        #}

That is just a trivial example with the data you gave me, so I made another example that works with a json list rather than a json dict:

[{
    "name": "steve",
    "lastname": "jobs",
    "age": "70",
    "city": "heaven"
},
{
    "name": "steve1",
    "lastname": "jobs1",
    "age": "71",
    "city": "heaven1"
},
{
    "name": "steve2",
    "lastname": "jobs2",
    "age": "72",
    "city": "heaven2"
},
{
    "name": "steve3",
    "lastname": "jobs3",
    "age": "73",
    "city": "heaven3"
},
{
    "name": "steve4",
    "lastname": "jobs4",
    "age": "74",
    "city": "heaven4"
}]

And a similar script:

#!/usr/bin/env python3
'''profile.json:
'''
import json
import io


# Open the JSON File and create a StringIO buffer to hold data
# Note: StringIO provides a file-like interface over a string
with open('profile.json', 'r') as datafile, io.StringIO() as data:
    # Load data into json file
    config = json.load(datafile)
    # Build json strong
    data.write('{\n\t"info": [\n')
    #data.write('\t{')
    for jsonobj in config:
        data.write(f'''\t    {{
                \r\t\t"given_name": "{jsonobj['name']}",
                \r\t\t"given_Lastname": "{jsonobj['lastname']}",
                \r\t\t"given_age": "{jsonobj['age']}",
                \r\t\t"given_city": "{jsonobj['city']}"
                \r\t    }}''')

        # Note: There is a bug here.
        # This will not be able to handle duplicate objects in
        # the json list. For a trivial example like this, it works.
        if jsonobj == config[-1]:
            data.write('\n\t]\n}')
        else:
            data.write(',\n')
    # open a new file to save the data (overwrite if it exists)
    with open('newfile.json', 'w') as outfile:
        # We need to serialize the json data if we want to write to file
        deserialized = json.loads(data.getvalue())
        outfile.write(json.dumps(serialized))
        # or we can just print it
        print(serialized)

Upvotes: 2

Related Questions