Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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')
like image 663
ACuriousCat Avatar asked Mar 22 '19 18:03

ACuriousCat


1 Answers

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()

like image 130
Danielle M. Avatar answered Sep 28 '22 18:09

Danielle M.