Encounter: json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

25,083

The problem is this piece of code:

with open(new_path) as data_file:
  data = data_file.read()
  print(data) 
  data_content = json.load(data_file)

You are reading the contents of the file into data, printing it, and then asking json.load() to read from the filehandle again. However at that point, the file pointer is already at the end of the file, so there's no more data, hence the json error: Expecting value

Do this instead:

with open(new_path) as data_file:
  data = data_file.read()
  print(data) 
  data_content = json.loads(data)

You already have your data read into data, so you can just feed that string into json.loads()

Share:
25,083

Related videos on Youtube

ACuriousCat
Author by

ACuriousCat

Updated on July 06, 2021

Comments

  • ACuriousCat
    ACuriousCat almost 3 years

    I got the json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) when I tried to access to the values from a json file I created. I ran the runfile below, and it seems that there was this decoder issue, however, when the json file was created, I made the encrypted content, which is supposed to be added to the json file's dictionary, as string. Could someone help me to spot where the problem is?

    Error is:

    {
        "youtube": {
            "key": "D5IPLv06NGXut4kKdScNAP47AieP8wqeUINr6EFLXFs=",
            "content": "gAAAAABclST8_XmHrAAfEbgrX-r6wwrJf7IAtDoLSkahXAraPjvoXeLl3HLkuHbW0uj5XpR4_jmkgk0ICmT8ZKP267-nnjnCpw=="
        },
        "facebook": {
            "key": "YexP5dpgxwKhD8Flr6hbJhMiAB1nmzZXi2IMMO3agXg=",
            "content": "gAAAAABclST8zSRen_0sur79NQk9Pin16PZcg95kEHnFt5vjKENMPckpnK9JQctayouQ8tHHeRNu--s58Jj3IPsPbrLoeOwr-mwdU5KvvaXLY-g6bUwnIp4="
        },
        "instagram": {
            "key": "ew2bl0tKdlgwiWfhB0jjSrOZDb41F88HULCQ_21EDGU=",
            "content": "gAAAAABclST8FKcZqasiXfARRfbGPqb3pdDj4aKuxeJoRvgIPbVIOZEa5s34f0c_H3_itv5iG1O7u8vvlT8lAPTgAp3ez8OBh4T2OfBG-ObljYmIt7exi0Q="
        }
    }
    Traceback (most recent call last):
      File "C:\Users\YOURNAME\Desktop\randomprojects\content_key_writer.py", line 65, in <module>
        main()
      File "C:\Users\YOURNAME\Desktop\randomprojects\content_key_writer.py", line 60, in main
        data_content = json.load(data_file)
      File "C:\Users\YOURNAME\AppData\Local\Programs\Python\Python37\lib\json\__init__.py", line 296, in load
        parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
      File "C:\Users\YOURNAME\AppData\Local\Programs\Python\Python37\lib\json\__init__.py", line 348, in loads
        return _default_decoder.decode(s)
      File "C:\Users\YOURNAME\AppData\Local\Programs\Python\Python37\lib\json\decoder.py", line 337, in decode
        obj, end = self.raw_decode(s, idx=_w(s, 0).end())
      File "C:\Users\YOURNAME\AppData\Local\Programs\Python\Python37\lib\json\decoder.py", line 355, in raw_decode
        raise JSONDecodeError("Expecting value", s, err.value) from None
    json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
    

    The original codes are pasted here, name this as the runfile:

    import sys
    import os
    from cryptography.fernet import Fernet
    import json
    import pathlib
    from encipher_decipher import encrypt, decrypt, bytes_to_str, str_to_bytes 
    
    def content_key_writer(path, filename, account, content):
        """Generate key corresponding to an account, save in json"""
        # make the path a Path object
        path = pathlib.Path(path)
        file_path = os.path.join(path, filename)
    
        # generate a key using Fernet
        key = Fernet.generate_key()
        # json doesn't support bytes, so convert to string
        key = bytes_to_str(key)
    
        # with file_path, see if the file exists
        if not os.path.exists(file_path):
            # build the dictionary to hold key and content
            data = {}
            data[account] = {}
            data[account]['key'] = key
            data[account]['content'] = encrypt(content, key)
    
    
            # if the file doesn't exist, build the new json file
            with open(file_path, 'w') as f:
                json.dump(data, f)
        else:
            # if the file does exist
            with open(file_path, 'r') as f:
                data = json.load(f)
                data[account] = {} # <--- add the account 
                data[account]['key'] = key
                data[account]['content'] = encrypt(content, key)
    
            os.remove(file_path) # <--- remove the file and rewrite it
            with open(file_path, 'w') as f:
                json.dump(data, f, indent=4)
    
    def main():
        path = "C:/Users/YOURNAME/Desktop/randomprojects"
        name = 'content.json'
        account = 'youtube'
        content = 'youtubepassword'
        account2 = 'facebook'
        content2 = 'facebookpassword'
        account3 = 'instagram'
        content3 = 'instagrampassword'
    
        content_key_writer(path, name, account, content)
        content_key_writer(path, name, account2, content2)
        content_key_writer(path, name, account3, content3)
        new_path = os.path.join(pathlib.Path(path),name)
        with open(new_path) as data_file:
            data = data_file.read()
            print(data) 
            data_content = json.load(data_file)
        value = data_content['youtube']['content']
        print(value)
    
    if __name__ == '__main__':
        main()
    

    The module imported in the codes above is encipher_decipher:

    """
    Given an information, encrypt and decrypt using the given key
    """
    
    from cryptography.fernet import Fernet
    import os
    
    def encrypt(information, key):
        """encrypt information and return as string"""
        f = Fernet(key)
        information_bytes = str_to_bytes(information) 
        encrypted_info = f.encrypt(information_bytes) #<--- returns bytes
        encrypted_info = bytes_to_str(encrypted_info) #<--- to save in json requires str not bytes
        return encrypted_info
    
    def decrypt(information, key):
        """decrypt information and return as string"""
        f = Fernet(key)
        information_bytes = str_to_bytes(information)
        decrypted_info = f.decrypt(information_bytes) #<--- returns bytes
        decrypted_info = bytes_to_str(decrypted_info) #<--- converts to string
        return decrypted_info
    
    def bytes_to_str(byte_stuff):
        """Convert bytes to string"""
        return byte_stuff.decode('utf-8')
    
    def str_to_bytes(str_stuff):
        """Converts string to bytes"""
        return bytes(str_stuff, 'utf-8') # or str_stuff.encode('utf-8')
    
    • ACuriousCat
      ACuriousCat about 5 years
      I tried in the file, using json.loads() returns error, while using json.load() there was no issue. But after using json.load(), I still have problem accessing the values.
    • martineau
      martineau about 5 years
      Try to create a minimal reproducible example for folks to use to reproduce (and possibly fix) the problem.
    • FastGTR
      FastGTR almost 3 years
      Try this stackoverflow.com/questions/5406172/utf-8-without-bom. The json file I was using had BOM information at the header i.e the characters  before the json data started. Had to use an editor to remove BOM then it worked.
  • ACuriousCat
    ACuriousCat about 5 years
    Yes, that's true, I also did the same by loads(data_file.read()) and it turns out fine. Thanks a lot.
  • martineau
    martineau about 5 years
    Very nice catch!