Updating already existing json file python
<p>I have a json file and I want to update 'filename' field with the filenames I scp from a remote server. I am pretty new to python but learning as I go. </p>

<p>JSON file:</p>

<pre><code>{"path":"/home/Document/Python", 
"md5s":[{"filename":"",
    "md5":"",
    "timestamp":""},
   {"filename":"",
    "md5":"",
    "timestamp":""},
   {"filename":"",
    "md5":"",
    "timestamp":""}
]}
</code></pre>

<p>My python code so far: </p>

<pre><code>  def filemd5():
   try:
    config = json.load(open(config_file))
    #print(str(json.dumps(config, indent=4)))
    for server in config['servers']:
            ssh = SSHClient() 
            ssh.load_system_host_keys()

            ssh.connect(server['ip'], username=server['username'], 
                        password=server['password'])
        #print(str(server)) 
        print('Connecting to servers')
        ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('ls /tmp/')
        error = str(ssh_stderr.read())
        if len(error) ==0:
            for files in config['servers']: 
                filename = file_location + server['file']
                scp = SCPClient(ssh.get_transport())
                scp.get(filename)
            if os.path.isfile(server['file']):
                updateJsonFile(filename)
                print(filename)
            else:
                print('KO')

def updateJsonFile(filename):
        with open('md5.json', 'r') as f:
           data = json.load(f)

       subdata = data['md5s']
       for check in subdata:
           check["filename"] = filename

       with open('md5.json', 'w') as f:
           f.write(json.dumps(data))

filemd5()
</code></pre>

<p>Formatting has not really came out well here but I am nearly sure it is good in my python script. 
What is happening now is that it populates all fields 'filename' with the same file when I am SCP three files from different servers. </p>

<p>Any help would be great. Thanks.</p>

<p>EDIT(updated question as adding to file works but it fills all values with same filename.</p>

<p>Expected result:</p>

<pre><code>{"path":"/home/Document/Python", 
 "md5s":[{"filename":"text1.txt",
"md5":"",
"timestamp":""},
{"filename":"text2.txt",
"md5":"",
"timestamp":""},
{"filename":"text3.txt",
"md5":"",
"timestamp":""}
 ]}
</code></pre>

<p>Actual:</p>

<pre><code> {"path":"/home/Document/Python", 
 "md5s":[{"filename":"text1.txt",
"md5":"",
"timestamp":""},
{"filename":"text1.txt",
"md5":"",
"timestamp":""},
{"filename":"text1.txt",
"md5":"",
"timestamp":""}
 ]}}
</code></pre>

<p>This is as close as I can come to sorting the code for you. I don't know why you get <code>KeyError</code> but you didn't implement a counter as suggested in the comments. Since I don't have access to <code>config['servers']</code>, the counter might be in the wrong place, in which case put it in the inner <code>for</code> loop. I tested this on your json string and it does work as you intended so the principle is correct, you just have to make sure you pass the desired values for <code>counter</code>.</p>

<pre><code>def filemd5():
    try:
        config = json.load(open(config_file))

        counter = 0 # Add a counter here
        for server in config['servers']:
            ssh = SSHClient() 
            ssh.load_system_host_keys()

            ssh.connect(server['ip'], username=server['username'], 
                            password=server['password'])

            print('Connecting to servers')
            ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('ls /tmp/')
            error = str(ssh_stderr.read())
            if not error: 
                for files in config['servers']: 
                    filename = file_location + server['file']
                    scp = SCPClient(ssh.get_transport())
                    scp.get(filename)
                if os.path.isfile(server['file']):
                    updateJsonFile(filename, counter)
                    counter += 1 # increment the counter
                    print(filename)
                else:
                    print('KO')
    except:
        # I don't understand why you don't get an error for missing except?
        pass  

def updateJsonFile(filename, counter):
    with open('md5.json', 'r') as f:
        data = json.load(f)

    subdata = data['md5s']
    # The code below would update every value since you loop through whole list
    #for check in subdata:
    #   check["filename"] = filename
    subdata[counter]['filename'] = filename

    with open('md5.json', 'w') as f:
        f.write(json.dumps(data))
</code></pre>

python json