"TypeError: Object of type bytes is not JSON serializable"

12,630

The problem is that base64.b64encode(bytes(fk, 'utf-8')) in encrypt_dict returns a byte-string (b'NGtUbnNEc2hXZTlsOE1tcWVoVkNOUjMtWVIxcVZrWGV1WlBVcjJ2WkhHST0=') while encrypt_string returns a normal string (no leading b). The JSON format only supports unicode strings.

This can be fixed by replacing line 16 in encrypt_dict with

ed['fk'] = base64.b64encode(bytes(fk, 'utf-8')).decode("ascii")
Share:
12,630
Pero
Author by

Pero

Updated on June 04, 2022

Comments

  • Pero
    Pero almost 2 years

    Trying to dump a dictionary in a JSON file gives me the error "TypeError: a bytes-like object is required, not 'str'"

    I already tried to remove the bytes conversion part of the "encrypt_string" function but it gives me the error "TypeError: a bytes-like object is required, not 'str'"

    #!/usr/bin/python3
    
    # Imports
    import json
    import base64
    from cryptography.fernet import Fernet
    
    # Save
    def encrypt_string(string, f):
        return str(f.encrypt(base64.b64encode(bytes(string,'utf-8'))).decode('utf-8'))
    
    def encrypt_dict(dict):
        fk = Fernet.generate_key().decode('utf-8')
        f = Fernet(fk)
        ed = {}
        ed['fk'] = base64.b64encode(bytes(fk, 'utf-8'))
        for key, value in dict.items():
            ekey = encrypt_string(key, f)
            evalue = encrypt_string(value, f)
            ed[ekey[::-1]] = evalue[::-1]
        return ed
    
    def save_game(slot, savename):
        print("Saving file...")
        path = 'saves/savegame{0}.json'.format(slot)
        data = {
            'game': 'Game name here',
            'version': 'Version here',
            'author': 'Author here',
            'savename': str(savename),
        }
        data = encrypt_dict(data)
        with open(path, 'w') as f:
            json.dump(data, f)
            f.close()
        print('Data saved in', path)
    
    # Main
    import gamemodule as gm
    
    def main():
        print("Running...")
        gm.save_game(1, 'test')
        input("Press any button to continue...")
    

    I expected the file the program to save the game data but it just returns the "TypeError: a bytes-like object is required, not 'str'" error

    I think that it's related to me encoding the variables in the encrypt_dict function but I'm not sure, I've browsed other problems similar to this one but I didn't find anything that fixed my error