'How to replace image attribute in one JSON from another JSON?

I am attempting to copy the image field from one group of json files and replace the image field in another group of JSON files.

JSON file structure that I am pulling from:

[
    {
        "\ufeffFile Name": "16.png",
        "image": "https://arweave.net/v8OOGgKmlAZF56bpGQRv1nM691gu2FMlrNK3KY-3HZk"
    }
]

JSON file structure that I need to replace:

{
  "name": "name",
  "symbol": "KK",
  "description": "description",
  "seller_fee_basis_points": 1000,
  "image": "image.png",
  "external_url": "https://www.image.net",
  "edition": 16,
}

Code:

import json
import os



def getFileImage(fp):
    with open(fp, 'r') as ff:
        try:
            return json.load(ff)['image']
        except:
            return None



def ReadAndReplace(filename, image):
    with open(filename, 'r') as ff:
        try:
            data = json.load(ff)
            data['image'] = image
            return json.dumps(data, indent = 4)
        except:
            print(f'Could not process file {filename}')
            return None



def Save(filename, data):
    with open(filename, 'w') as ff:
        ff.write(data)



def EnsureOutput():
    if not os.path.exists('output'):
        os.mkdir('output')

    if not os.path.exists('input') or not os.path.exists('toReplace'):
        print('Please create "input" and "toReplace" folders')
        exit()


def main():
    EnsureOutput()

    for i in os.listdir('toReplace'):
        filepath1 = os.path.join('input', i)
        filepath2 = os.path.join('toReplace', i)
        outpath = os.path.join('output', i)

    if os.path.exists(filepath1):
        image = getFileImage(filepath1)
        data = ReadAndReplace(filepath2, image)
        Save(outpath, data)
    else:
        print(f'No input file for toReplace "{i}" was found')



main()

When I run this code the image field updates to NULL instead of the link I need.



Solution 1:[1]

The input you are loading is a JSON array and hence parsed as a python list, which you can obviously not access by keys as you are trying to do. You first need to access the object within the array and then you may access this object with keys.

See the following:

input = """
[
    {
        "\ufeffFile Name": "16.png",
        "image": "https://arweave.net/v8OOGgKmlAZF56bpGQRv1nM691gu2FMlrNK3KY-3HZk"
    }
]
"""

input_parsed = json.loads(input)
print(type(input_parsed))
print(input_parsed[0]["image"])

Expected output:

<class 'list'>
https://arweave.net/v8OOGgKmlAZF56bpGQRv1nM691gu2FMlrNK3KY-3HZk

For your ReadAndReplace() function this would look like this:

def read_and_replace(filename, image):
    with open(filename, 'r') as ff:
        try:
            # data is a list
            data = json.load(ff)
            # be sure the list has actually one value exactly
            if len(data) == 1:
                data[0]['image'] = image
            return json.dumps(data, indent=4)
        except (json.JSONDecodeError, KeyError):
            print(f'Could not process file {filename}')
            return None

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1