#!/usr/bin/env python
""" Module jsonutils: contains methods for reading/writing to JSON format. """
import json, logging
import traceback
import os
[docs]class JSONUtils(object):
"""
This class contains useful methods for working with serializing JSON data.
"""
@staticmethod
[docs] def read(path):
"""
Given a JSON-formatted file, reads the data from it.
Returns the equivalent Python object
:param path: ``str`` that determines where open() will attempt to read data from
:return: Depending on type of JSON object stored, returns Python equivalent.
Defaults to ``dict``.
:rtype: ``dict``
"""
logger = logging.getLogger(__name__)
try:
fileLocal = open( path, 'r' )
except IOError:
logger.error('### Unable to read file from: {0}\n{1}'
.format(path, traceback.print_exc()) )
raise IOError
# read in JSON data as raw string
try: data = fileLocal.read()
except IOError, e:
logger.error('### Failed to read JSON-formatted file at: {0}\n {1}'
.format(path, e))
raise IOError
# close file from memory
fileLocal.close()
# check in case of invalid JSON file
try:
j_data = json.loads( data )
return j_data
except:
logger.debug('Data attempted to be read from file: {0}'.format(data) )
logger.error('The JSON file {0} is invalid!'.format(path) )
raise TypeError
@staticmethod
[docs] def write(path, data, mode='w'):
"""
Writes data to a external JSON-formatted file.
:param path: ``str`` that determines where the data is written to
:param data: ``dict`` containing keys and values to be written in JSON format.
:param mode: ``str`` determining the mode which the file is written as.
Acceptable identifiers:
- 'w': write-only mode. Overwrites all existing data.
- 'a': append mode. Appends to existing data.
:return: ``None``
"""
logger = logging.getLogger(__name__)
# check for presence of existing file
if os.path.isfile( path ):
# check if in append mode
if 'a' in mode:
# first read all the existing data into new dict
currentData = JSONUtils.read(path)
dataToWrite = {}
# Add it to the data dict to be written so that additional keys/values
# are appended after
for key, value in currentData.items():
dataToWrite[key] = value
# set data to be written to disk
data = dataToWrite
fileLocal = open( path, 'w' )
# write JSON with pretty printing
fileLocal.write( json.dumps( data, sort_keys=True,
indent=4, separators=(',', ': ') ) )
logger.debug( ' Existing fileLocal changed: {0}'.format(path ) )
fileLocal.close()
else:
logger.debug('{0} not found, writing new fileLocal...'.format(path) )
fileLocal = open( path, 'w' )
# write JSON with pretty printing
fileLocal.write( json.dumps( data, sort_keys=True,
indent=4, separators=(',', ': ') ) )
logger.info('File written to: {0}'.format(path ) )
fileLocal.close()