The t4json module was created to make working with JSON data in python easier. It provides a bunch of tools to seamlessly open, edit and save JSON data. The JSON data is first deserialized and stored in an attribute of the T4Json class… this way you can work with the deserialized data directly… just as you would with the standard json module. The tools provided by t4json have tons of features so that you can do really specific things… if you only want to read a few values from some simple json data, then you might as well use the standard json module.
This module should work on any installation of python 3.6 or later on any OS right out of the box.
Outline:
- Open up json data from a file, URL/Endpoint, or string with the T4Json class.
- Use methods to make some changes.
- Save changes.
- That’s it. Your done..
Features
- Use paths to navigate the json data just like in the file system. Also includes relative/absolute path navigating.
- Easily make changes like changing the name of a key, changing a value, adding new items, moving/copying items to new locations, deleting items, flattening, and more. All with easy to use and intuitive methods.
- Easily open up json data - simply pass a File Path, URL, or Json String when creating the T4Json object, and it will automatically figure out what is what and give you the data you need to work with.
- And more.
T4json is designed to simply and easily work with json data without any hassle. It can be used to make simple quick changes, more complex changes, or to just retrieve data. All with only a few lines of code that are easy to understand and read.
Installation
Using pip:
pip install t4json
Or just download the code from GitHub and use as a local module within your project… which may be more useful if you want to make changes to it.
Try to keep this package up to date… this project is under active development and with every update there can be much more improvement on the previous version.
Notes
- Since v1.4.0, slicing operations are supported on T4Json instances. They can be used to delete, change and read values. Paths may also be used in the first slice to walk up a level. Also, inplace/non-inplace adding and subtracting are supported for adding new items/pairs or removing items/pairs in bunches. Iterating through T4Json instances is also now supported.
- All methods (where applicable) within the T4Json class will return un-copied mutable data. This is so that you can access the data and manipulate it just as you would if you were using the json module. You can use the built in
copy()
method of the returned mutable data to make a shallow copy… or you can use the copy module to make a deep copy. You can access the deserialized data through thedata
property of the T4Json class. - Many of the methods and functions in t4json have a lot of arguments… So key-word arguments may have to be used a lot of the time depending on what you are trying to do.
- Feel free to open it up and change some default arguments of the methods. If an argument looks like
<parameter name>: <expected value> = None
then that default argument needs to be changed with the attributes in the__init__()
method of the T4Json class. If the expected value/s hasNone
in it like<parameter name>:<some expected value> | None = None
. In that case just change the default value of that parameter fromNone
to something else if the arguments expected values allow it. Any ‘flagged’ T4Json methods or variables that look like__<name of method or var>__
are not safe to tamper with as they are used by the T4Json class for processing the json data…
Definitions/Terms
- Anything that holds data is called a container. Such as a dictionary or list
- A pair is short for a key/value pair or json object.
- A value is anything that has a corresponding key or index.
- A key is a string that is used to gain access to a value within a pair container.
- An index is an integer that is used to gain access to a value within a list container.
- An item is a non-pair value.
- A pair container is a dictionary.
- A list container is simply a list.
- If a path is an empty string ““… it is accessing the base container.
JSON Conversion Table
Once you are done making changes/creating your json file… it needs to be serialized / saved so that it can then be understood by other programs. For python to understand the JSON data it needs to be deserialized/loaded into a python data structure like a dictionary or list. Below are the tables used for that conversion process.
Converting/Encoding to JSON:
Python | t4json | JSON |
---|---|---|
dict | pair container | object |
list/tuple | list container | array |
str | <————–> | string |
int, float, int- & float-derived Enums | <————–> | number |
True | <————–> | true |
False | <————–> | false |
None | <————–> | null |
Converting/Decoding from JSON to Python data structures:
JSON | t4json | Python |
---|---|---|
object | pair container | dict |
array | list container | list/tuple |
string | <————–> | str |
number (int) | <————–> | int |
number (real) | <————–> | float |
true | <————–> | True |
false | <————–> | False |
null | <————–> | None |
Overview of Global Functions
multi_iter()
is_valid_json_data()
convert_to_valid_json_ready_data()
serialize_to_string()
deserialize_from_string
Overview of T4Json Class Methods
The parameters are not shown in the methods listed below.
Editing Methods
add()
chage_value()
change_key()
move_from_to()
copy_from_to()
delete()
delete_empty_containers()
convert_singular_lists()
new()
clear()
/wipe()
format()
flatten()
Reading Methods
read()
multi_iter()
pair()
pairs()
key()
keys()
values()
all_pairs()
all_values()
all_keys()
search()
json_string()
Settings Methods
set_working_level()
set_indentation()
set_sort_keys()
set_only_ascii()
set_ignore_errors()
set_path_separator_properties()
set_json_separators()
set_path_separator_properties()
is_sorting_keys()
is_only_ascii()
is_ignoring_errors()
get_working_level()
get_indentation()
get_path_separator_properties()
get_known_objects_for_path()
reset_settings()
I/O Methods
load()
load_file()
load_from_string()
load_from_url()
load_object()
save()
save_as()
json_string()
close()
Other/Misc Methods
types()
pprint()
is_path_existent()
is_path_relative()
is_path()
T4Json Methods
The self
parameter is omitted in the proceeding documentation.
Also, a parameter within most of the methods named ignore_errors
has been omitted. What ignore_errors
does is ignore non-critical errors such as the key
/path
to a value being incorrect.
Editing Methods:
T4Json. add(value, path='', existing_keys='pass', create=False, index=None, integrate_list_with_list=False)
This method can be used to add new data anywhere in the json data.
value This can be a dictionary of new pairs/s that you want to add to the current data, or it can be a string, integer, float, boolean, none, string, or list.
path leads to the location where the data will be added.
existing_keys - This parameter specifies what to do with keys that already exist on the current level. If set to “pass” then any key/s that already exists on the current level will be ignored. If set to “replace” then any key/s that already exist on the current level will have its value be replaced by the value of the new key/s. If set to “combine” then any key/s that already exist on the current level will have its value be combined with the value of the new key/s in a list. If set to “integrate” then any key/s that already exist on the current level will have its value be integrated as best as possible with the value of the new key/s. If both the new and existing key/s have values that are containers… they will be integrated into one container.
create when set to True
a list will be created if path
leads to a non-container item. This list will include the non-container item along with the new value
. Otherwise, if it is False
it will raise an AddError
.
index when path
leads to a list and this argument is passed and integer… value
will be inserted at the specified index. A string can also be passed to indicate where to place value
. It can be “center” (or “half”), “4q”, “3q”, “2q”, “1q” or “0q” (The “q” stands for quarters)… or it can be a positive integer in a string that represents a proportional percentage/scale of where to place value
… with “0” being at the start and “100” being the end. When None
is passed, value
will be placed at the end of the list.
integrate_list_with_list - If path
leads to a list and value
is a list then both lists will be integrated into one list.
T4Json. change_value(path, new_value)
This method can be used to change the value of a key anywhere in the json data.
path leads to the key which holds the value you want to change.
new_value is what you want to replace the old value with… It can be a string, integer, float, boolean, none, dictionary, or list.
T4Json. change_key(path, new_key, existing_key='error')
This method can be used to change the name of a key anywhere in the json data.
path leads to the key that you want to change.
new_key this is the new key… A string, integer, float, boolean or none will be accepted but they of course will be converted to a string.
existing_key - This parameter specifies what to do if a key already exists on the current level.
If set to “pass” then the key that already exists on the current level it will be ignored and nothing will change.
If set to “replace” then the key that already exist on the current level will have its value be replaced by the value of the old key being changed.
If set to “combine” then the key that already exist on the current level will have its value be combined with the value of the old key in a list.
If set to “integrate” then the key that already exist on the current level will have its value be integrated as best as possible with the value of the old key. If both the existing and old keys have values that are containers… they will be integrated into one container.
If set to “error” an ArgumentError
will be raised if a key already exists on the current level.
T4Json. move_from_to(from_path, to_path, only_contents=False, existing_key='pass', create=False, index=None, integrate_list_with_list=False)
This method can be used to move the specified data around inside the json data. If you try to move data further into itself an InvalidStructurePathError
will be raised.
from_path should lead to the key/json object of the data you want to move.
to_path should lead to the location where the data will be moved.
only_contents when set to True
only the contents/value of the key/json object will be moved. Otherwise, if False
the json object/key - value pair itself will be moved.
existing_keys - This parameter specifies what to do with keys that already exist on the current level. If set to “pass” then any key/s that already exists on the target level will be ignored. If set to “replace” then any key/s that already exist on the target level will have its value be replaced by the value of the new key/s. If set to “combine” then any key/s that already exist on the target level will have its value be combined with the value of the new key/s in a list. If set to “integrate” then any key/s that already exist on the target level will have its value be integrated as best as possible with the value of the new key/s. If both the new and existing key/s have values that are containers… they will be integrated into one container.
create when set to True
a list will be created if path
leads to a non-container item. This list will include the non-container item along with the moved value
. Otherwise, if it is False
it will raise an AddError
.
index when to_path
leads to a list and this argument is passed and integer… the value from from_path
will be inserted at the specified index. A string can also be passed to indicate where to place the value. It can be “center” (or “half”), “4q”, “3q”, “2q”, “1q” or “0q” (The “q” stands for quarters)… or it can be a positive integer in a string that represents a proportional percentage/scale of where to place the value… with “0” being at the start and “100” being the end. When None
is passed, the value will be placed at the end of the list.
integrate_list_with_list - If to_path
leads to a list and the value from from_path
is a list then both lists will be integrated into one list.
T4Json. copy_from_to(from_path, to_path, only_contents=False, overwrite_existing=False, create=False, index=None, integrate_list_with_list=False)
This method can be used to copy the specified data to another location inside the json data.
from_path should lead to the key/json object of the data you want to move.
to_path should lead to the location where the data will be moved.
All the other arguments are the same as in move_from_to()
.
T4Json. delete(path)
This method can be used to delete the specified data.
path should lead to the pair/item you want to delete.
T4Json. convert_singular_lists(path)
Converts all values on the current level that are lists containing only one item to the item that is inside that list.
path should lead to the level in which you want to convert any singular lists to their one value.
T4Json. delete_empty_containers(path)
This method can be used to delete any keys with empty containers as values.
path should lead to the level in which you want to remove any keys that have an empty container as values.
T4Json. new(start)
This method can be used to start fresh. The difference between this method and load_object
is that it replaces the data of the currently “opened” file… so that when you call save()
the new data will be saved to the currently “opened” file.
start can be a dictionary, list, tuple (which will be converted to a list), string, integer, float, boolean, or none. All current data will be overwritten/replaced with start
.
T4Json. clear()
or wipe()
Simply deletes everything and leaves you with an empty dictionary.
T4Json. format(indentation=4, sort_keys=True, only_ascii=False)
This method formats the json file to make it look nice.
indentation Sets the indentation amount of the json file.
sort_keys Will sort all the keys in the json file in alphabetical and numerical order.
only_ascii will escape any non-ASCII characters.
T4Json. flatten(path='', chain_keys=False, chain_key_separator='_', flatten_opposite_container_type=True, pull_pairs_from_lists=True, pull_lists_from_pairs=False, existing_keys='integrate', list_index=None, convert_singular_lists=True, delete_empty_containers=True)
This method flattens nested data.
path can be used to select which level you want to flatten.
chain_keys when set to True
the data will be flattened with all the keys being renamed to include there previous parents names.
chain_key_separator - This is used as the separator between the keys as they are being renamed to include their previous parents names. chain_keys
must be set to True
for this argument to apply.
flatten_opposite_container_type when set to True
the opposite container type of the target one being flattened will also be flattened. For example: If you are flattening a pair container then all the list containers inside the pair container will also be flattened. Or if you are flattening a list container then all the pair containers within that list container will be flattened.
pull_pairs_from_lists - If flatting a pair container… then any pair/s contained in lists will be pulled out and flattened. This will only work if flatten_opposite_container_type
has been set to True
.
pull_list_from_pairs - If flatting a list container… then any pair/s within that data that contain lists as values will be pulled out and flattened. This will only work if flatten_opposite_container_type
has been set to True
.
existing_keys - This parameter specifies what to do with keys that already exist on the base level. If set to “pass” then any key/s that already exists on the base level will be ignored. If set to “replace” then any key/s that already exist on the base level will have its value be replaced by the value of the new key/s. If set to “combine” then any key/s that already exist on the base level will have its value be combined with the value of the new key/s in a list. If set to “integrate” then any key/s that already exist on the base level will have its value be integrated as best as possible with the value of the new key/s. If both the new and existing key/s have values that are containers… they will be integrated into one container.
list_index when a list is being flattened any nested contents will be pulled to the specified index. A string can also be passed to indicate where to place the value. It can be “center” (or “half”), “4q”, “3q”, “2q”, “1q” or “0q” (The “q” stands for quarters)… or it can be a positive integer in a string that represents a proportional percentage/scale of where to place the value… with “0” being at the start and “100” being the end. When None
is passed, the value will be placed at the end of the list. If a nested list is being flattened, and you want the contents to keep their positions than pass “hold”.
convert_singular_lists - When the flatting has finished, if this is set to True
, then any values that are lists and only contain one item will be converted to the item that is contained within themselves. This does the same thing as the convert_singular_lists()
method.
delete_empty_containers - Once the flatting is all done and dusted and if this is set to True
then any keys with empty containers as values will be deleted.
___
Reading Methods:
T4Json. read(path='')
Returns the value of wherever path
leads.
path Leads to the key that will have its value be returned.
T4Json. multi_iter(var_count=2, step=None, start_index=0, stop_index=None, include_uneven=False, uneven_placeholder=None, path: str = '', read_values_from_keys=False)
This method makes it possible to loop multiple variables through the data in a for
loop.
var_count is the number of variables that will be in the for
loop.
step is the number of items you want to skip over when iterating. Which by default is None
and is equivalent to being the same number that var_count is in order to sequentially iterate the variables through the data.
start_index is the beginning index which is where the variables start iterating.
start_index is the ending index which is where the variables stop iterating.
include_uneven when set to True
will add in filler values for the remaining items in the data if the data is unevenly divided by the number of variables (var_count) being iterated through it. The default filler value is None
.
uneven_placeholder is the filler value when for when the data is not evenly divided by the number variables (var_count) being iterated through it.
path Leads to the data that will be iterated through.
read_values_from_keys when set to True
the values instead of the keys of mapping data will be iterated through.
Example:
data = T4Json([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
for x, y, z in data.multi_iter(var_count=3):
print(x, y, z)
Output:
1 2 3
4 5 6
7 8 9
10 11 12
T4Json. json_string(path='', indent=None, sort_keys=None, only_ascii=None, separators=None)
Returns a json formatted string. This string can then… for example be saved to a file.
path Leads to the key that will have its value be returned as a json formatted string.
indent Can be an Integer, String, or None. If an Integer is passed then the json will have its indentation set to the specified amount of whitespaces. If a string is passed then it will be used as the indentation space. If None is passed then there will be no indentation.
sort_keys When True
is passed the key will be sorted in alphabetical/numerical order.
only_ascii When set to True
any non-ascii characters will be escaped/encoded.
separators Must be a tuple with two items. The fist is used to separate pairs or items. It is “, “ by default. The second is used to separate key and values. It is “: “ by default.
T4Json. pair(path, as_dictionary=False)
Returns a pair in the form of a tuple (key
, value
) or dictionary pair {key
: value
} from wherever path
leads.
path Leads to the value that will be put in a tuple along with its key.
as_dictionary When True
the target pair will be returned as dictionary - {key
: value
}, otherwise it will be returned as a tuple - (key
, value
).
T4Json. pairs(path='', as_dictionaries=False)
Returns a list of tuples of (key, value) pairs - [(key, value), (key, value)..] of the selected level. This method is very similar to the items()
method of dict
.
path Leads to the key that will have its contents be returned in this format.
as_dictionaries When set to False
it will return all the pairs like so - (key
, value
). If set to True
they will be returned as - {key
: value
}
T4Json. key(path)
Returns the key of the value that path
leads to. If the value is in a list the values index will be returned as an integer.
path Leads to the value that will have its key be returned.
T4Json. keys(path='')
Returns a list of all the of keys in the location that is specified by path
. If path
leads to a non-container value than it will return the key of that value.
path Leads to the container where the keys are.
T4Json. values(path='')
Returns a list of all the of values in the location that is specified by path
. If path
leads to a non-container value than that value will simply be returned.
path Leads to the key that will have its value be returned.
T4Json. all_pairs(path='', search_lists=True, as_dictionaries=False)
Returns a list of tuples of all (key, value) pairs as - [(key, value), (key, value)..] past a point specified by path
.
path Leads to the key that will have its contents be returned in this format.
return_as_dictionaries When set to True
will return all the pairs like so - {key
: value
}. If set to False
they will be returned as - (key
, value
)
search_lists When set to True
will also search through lists for pairs.
T4Json. all_keys(path='', search_lists=True, as_paths: bool = False)
Returns a list of all the keys past a certain point which is specified by path
. This method only returns keys that have a non-container value
path Leads to the container where all keys past itself will be returned.
search_lists When set to True
will also search through lists for keys.
as_paths If set to True
will return all the keys as paths to where they are in within the data.
T4Json. all_values(path='', search_lists=True)
Returns a list of all the of values in the location that is specified by path
. If path
leads to a non-container value than that value will simply be returned.
path Leads to the key that will have its value be returned.
search_lists When set to True
will also search through lists for values that have a corresponding key.
T4Json. search(key, path='', search_list=True)
Searches through all the json data or (past a certain point specified by path
) for key
. If there are multiple keys with the same name spread throughout the data, a list of their all there values will be returned.
path Leads to the key that will have its value be returned.
search_lists When set to True
will also search through lists for values that have a corresponding key.
___
Settings Methods:
T4Json. set_working_level(path='')
Sets the working level within a nested data structure.
path Leads to the level that will be set as the current working level. If path leads to a non-container value than its parent container will be selected as the current working level.
T4Json. set_indentation(indentation)
Sets the indentation of the json file which will be applied when it is saved/serialized.
indentation Can be an Integer, String, or None. If an Integer is passed then the json will have its indentation set to the specified amount of whitespaces. If a string is passed then it will be used as the indentation space. If None is passed then there will be no indentation.
T4Json. set_sort_keys(boolean)
boolean When True
is passed the key will be sorted in alphabetical/numerical order. This will be applied when the file is saved/serialized.
T4Json. set_only_ascii(boolean)
boolean When set to True
any non-ascii characters will be escaped/encoded. This will be applied when the file is saved/serialized.
T4Json. set_ignore_errors(boolean)
boolean If True
is passed then any non-critical errors (such as the path being incorrect) will be ignored.
T4Json. set_path_separator_properties(separator, relative, relative_back)
Sets the path separator and relative path navigation properties.
separator is the character/s used to separate the keys. It is “\\” by default.
relative is the character/s used at the start of the path to signify that it is starting at the current working level. It is “.” by default.
relative_back is the character/s used at the start of the path to signify that it is starting at the current working level and going back up one level. There can be multiple relative back commands to go back up multiple levels before continuing with a normal path. relative_back is “. .” by default.
T4Json. set_json_separators(item_separator, key_value_separator)
Sets the pair and item separator properties for the json data when it is saved/serialized. The most compact arguments would be (“,” and “:”) instead of the default (“, “ and “: “).
item_separator is used to separate pairs or items. It is “, “ by default.
pair_separator is used to separate key and values. It is “: “ by default.
T4Json. set_known_objects_for_path(objects=None)
Sets the objects that will be recognized as keys within paths.
objects must be provided a list of objects to add to the known objects collection. If nothing is passed, and it is None
, then the known object collection will be reset to the default set of known objects.
T4Json. is_sorting_keys()
Returns True
if the keys are being sorted in alphabetical/numerical order. Otherwise, it returns False
.
T4Json. is_only_ascii()
Returns True
if all non-ascii characters are being escaped/encoded. Otherwise, it returns False
.
T4Json. is_ignoring_errors()
Returns True
if non-critical errors are being ignored. Otherwise, False
is returned.
T4Json. get_working_level()
Returns the current working level as a path.
T4Json. get_indentation()
Returns the indentation property. An Integer, String or None can be expected.
T4Json. get_path_separator_properties()
Returns the path separator properties in a tuple - (path separator, relative command, relative_back command)
T4Json. get_known_objects_for_path()
Returns a list of the known objects that are recognized as keys within paths.
T4Json. reset_settings()
Resets any settings that have been changed… back to their original default values.
___
I/O Methods:
Note - ( A few parameters have been left out in the documentation below. The first is encoding
and encoding_errors
/errors
. These parameters are part of the built-in open() function. Check out the open() functions docs for more information. In addition decode_html_entities
has also been left out. decode_html_entities
just decodes any HTML entities… by default it is set to False
.)
Note - ( The __init__()
for the T4Json class uses the same parameters as the load()
method because it calls load()
. If you decide to not pass any data when initiating the T4Json class then you can call load()
and it will do the same thing. )
T4Json. load(source, url_parameters=None, url_headers=None, url_body=None, url_user_auth=None, url_request_method='GET', url_raise_for_status=False, create=False)
This method loads the json data. It can receive a File Path, URL, JSON String, dict, or list.
source must be passed a string - File Path, URL/Endpoint, JSON String, Dict, or List.
url_parameters must be passed a dict, list, or bytes that contains the parameters that will be combined with the URL. Check out this guide
url_headers must be passed a dict containing the HTTP headers. Check out this guide.
url_body must be passed a JSON serializable object (usually a dict) containing the HTTP body that will be sent when the request is made.
url_user_auth must be passed a tuple/auth object used to authenticate a user using HTTP Basic/Digest/Custom Authentication or methods like OAuth. Check out the docs here.
url_request_method must be passed a string such as “GET”, “POST”, “PUT” or “DELETE”.
url_raise_for_status when set to True
it will raise an error if response/status code is anything other than 200.
create If you are attempting to load a file that does not exist and this parameter is set to True
then the non-existent file will be created.
T4Json. load_file(file_path, create=False)
Loads the Json data from a specified file.
file_path must be passed a path that leads to the file you want to open.
create If you are attempting to load a file that does not exist and this parameter is set to True
then the non-existent file will be created.
T4Json. load_from_string(string)
Loads Json data from a string.
string must be passed a String of serialized json data.
T4Json. load_from_url(url, parameters=None, headers=None, body=None, user_auth=None, request_method='GET', raise_for_status=False)
Loads json data from the specified URL/Endpoint.
url must be passed a URL/Endpoint that leads to the Json data you want to load.
parameters must be passed a dict, list, or bytes that contains the parameters that will be combined with the URL. Check out this guide
headers must be passed a dict containing the HTTP headers. Check out this guide.
body must be passed a JSON serializable object (usually a dict) containing the HTTP body that will be sent when the request is made.
user_auth must be passed a tuple/auth object used to authenticate a user using HTTP Basic/Digest/Custom Authentication or methods like OAuth. Check out the docs here.
request_method must be passed a string such as “GET”, “POST”, “PUT” or “DELETE”.
raise_for_status when set to True
it will raise an error if response/status code is anything other than 200.
This functionality comes from the “requests” package. If you are not familiar with the request package you may want to look into it before using these features. Here is a good guide on working with APIs using the requests module.
T4Json. load_object()
Receives a dict or list and loads it. This way you could load a dictionary work with it… and then save it.
T4Json. save(indent=None, sort_keys=None, only_ascii=None, separators=None)
Saves the currently opened file if a file has already been opened.
indent Can be an Integer, String, or None. If an Integer is passed then the json will have its indentation set to the specified amount of whitespaces. If a string is passed then it will be used as the indentation space. If None is passed then there will be no indentation.
sort_keys When True
is passed the key will be sorted in alphabetical/numerical order.
only_ascii When set to True
any non-ascii characters will be escaped/encoded.
separators Must be a tuple with two items. The fist is used to separate pairs or items. It is “, “ by default. The second is used to separate key and values. It is “: “ by default.
T4Json. save_as(file_path, overwrite=False, indent=None, sort_keys=None, only_ascii=None, separators=None)
Save the JSON data as a new file.
file_path Is the new file name which can include a path to wherever you want to place it.
overwrite When set to True
and file_path
already exist then the already existing file will have its contents overwritten.
indent Can be an Integer, String, or None. If an Integer is passed then the json will have its indentation set to the specified amount of whitespaces. If a string is passed then it will be used as the indentation space. If None is passed then there will be no indentation.
sort_keys When True
is passed the key will be sorted in alphabetical/numerical order.
only_ascii When set to True
any non-ascii characters will be escaped/encoded.
separators Must be a tuple with two items. The fist is used to separate pairs or items. It is “, “ by default. The second is used to separate key and values. It is “: “ by default.
T4Json. json_string(path='', indent=None, sort_keys=None, only_ascii=None, separators=None)
Returns a json formatted string. This string can then.. for example be saved to a file.
path Leads to the key that will have its value be returned as a json formatted string.
indent Can be an Integer, String, or None. If an Integer is passed then the json will have its indentation set to the specified amount of whitespaces. If a string is passed then it will be used as the indentation space. If None is passed then there will be no indentation.
sort_keys When True
is passed the key will be sorted in alphabetical/numerical order.
only_ascii When set to True
any non-ascii characters will be escaped/encoded.
separators Must be a tuple with two items. The fist is used to separate pairs or items. It is “, “ by default. The second is used to separate key and values. It is “: “ by default.
T4Json. close()
Simply closes the data that’s already open and leaves you with an empty dictionary.
___
Other/Misc Methods:
T4Json. types(path='')
Returns a set of all the types on the current level (as defined by path). If the current level is a dictionary than the types of all the values will be in the returned set.
It can be used to check if a specific data type is on the current level. For example:
>>> instance = T4Json([16, 'abc', 3.14])
>>> int in instance
True
>>> str in instance
True
>>> tuple in instance
False
T4Json. pprint(path='', indent=1, print_to_console=True)
Note - it is not necessary to call this method if you just want to only view the data. You can simply print the instance of the T4Json class you would like to view.
path can lead to the level that you want to print.
indent must be passed an integer. This specifies the amount of indentation you would like.
print_to_console when set to True
will print it to the console. If set to False
, this method will only return the string that was going to be printed.
T4Json. is_path_existent(path)
Checks to see if path exist in the currently opened data structure. True
is return if it does exist… and False
otherwise.
T4Json. is_path_relative(path)
Checks to see if path is a relative path. True
is returned if it is… and False
otherwise.
T4Json. is_path(path)
Checks to see if path is considered a path in the current T4Json instance.
___
Global Functions
T4Json. multi_iter(data, var_count=2, step=None, start_index=0, stop_index=None, include_uneven=False, uneven_placeholder=None, path: str = '', read_values_from_keys=False)
This function makes it possible to loop multiple variables through data in a for
loop.
data is the data that you want to loop through. You can pass a list, tuple, str, T4Json, dict, set, or frozenset.
var_count is the number of variables that will be in the for
loop.
step is the number of items you want to skip over when iterating. Which by default is None
and is equivalent to being the same number that var_count is in order to sequentially iterate the variables through the data.
start_index is the beginning index which is where the variables start iterating.
start_index is the ending index which is where the variables stop iterating.
include_uneven when set to True
will add in filler values for the remaining items in the data if the data is unevenly divided by the number of variables (var_count) being iterated through it. The default filler value is None
.
uneven_placeholder is the filler value when for when the data is not evenly divided by the number variables (var_count) being iterated through it.
read_values_from_keys when set to True
the values instead of the keys of mapping data will be iterated through.
Example:
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
for x, y, z in multi_iter(data, var_count=3):
print(x, y, z)
Output:
1 2 3
4 5 6
7 8 9
10 11 12
is_valid_json_data(source)
This function returns True
if the JSON data is valid. Otherwise, it returns False
.
source must be passed a string - File Path, URL, or JSON String.
convert_to_valid_json_ready_data(value)
Converts value into json ready data. It will remove any unsupported keys and convert the keys that are not string into strings.
value must be passed a dictionary, list, tuple or any other basic type of python data.
serialize_to_string(value, indent=None, sort_keys=None, only_ascii=None, separators=None)
Returns a json formatted string from value. This string can then.. for example be saved to a file.
value must be passed a dictionary, list, tuple or any other basic type of python data.
indent Can be an Integer, String, or None. If an Integer is passed then the json will have its indentation set to the specified amount of whitespaces. If a string is passed then it will be used as the indentation space. If None is passed then there will be no indentation.
sort_keys When True
is passed the key will be sorted in alphabetical/numerical order.
only_ascii When set to True
any non-ascii characters will be escaped/encoded.
separators Must be a tuple with two items. The fist is used to separate pairs or items. It is “, “ by default. The second is used to separate key and values. It is “: “ by default.
deserialize_from_string(string)
Loads Json data from a string and returns the python data structure.
string must be passed a String of serialized json data.
___
Slicing Operations
Data in T4Json instances can be edited using slicing operations. This can be really useful if you don’t want to use the T4Json.methods().
Reading:
>>> data = T4Json({'phone': {'area': 503, 'middle': 464, 'last': 9787}})
>>> data['phone']['area']
501
Adding / Changing:
>>> data = T4Json({'phone': {'area': 503, 'middle': 464, 'last': 9787}})
>>> data['phone']['area'] = [5, 0, 3]
>>> data
{'phone': {'area': [5, 0, 3], 'middle': 464, 'last': 9787}}
Deleting:
>>> data = T4Json({'phone': {'area': 503, 'middle': 464, 'last': 9787}})
>>> del data['phone']['area']
>>> data
{'phone': {'middle': 464, 'last': 9787}}
We can also use paths within our slices (if it is the first slice) to easily access deep levels (using relative paths, if needed). For example:
>>> starting_data = {
... "internet": {
... "airplane mode": False,
... "wifi": [True, {"known": ["home", "office"]}],
... "wifi calling": False,
... "mobile hotspot": False}
... }
>>>
>>> data = T4Json(starting_data)
>>> data.set_working_level(r'internet\\wifi\\1')
>>> data[r'..\\..']['wifi'] = 404
>>> data
{
"internet": {
"airplane mode": False,
"wifi": 404,
"wifi calling": False,
"mobile hotspot": False
}
}
___
Examples
Loading the Data
To load json data simply pass the data in when initializing the t4json object.
Loading a File:
data = T4Json('example.json')
Loading from a URL/Endpoint:
data = T4Json('https://api.github.com/users?since=100')
Loading from a string:
json_data = """{
"name": "John"
"age": 67
"wealth": "above average"
"family": null
}"""
data = T4Json(json_data)
Loading from a dict/list:
dictionary = {'new_data': 512}
data = T4Json(dictionary)
If you want to load new data into the same T4Json instance after you have already loaded data - data.load("new_example.json")
.
If you want to start with a clean slate and create json data from scratch then:
data = T4Json()
# start adding items here
Using Paths to Navigate the Data
Note - ( This section assumes familiarity with absolute/relative paths within the file system. )
Once the data is loaded you can navigate it using paths - similar to a file/directory path. If you are working in some nested part of the data then you can set that as the current working level to make it easier to read/edit the data in there. For example:
Here is the json data in a file we will call settings.json
:
{
"internet": {
"airplane mode": false,
"wifi": [true, {"known": ["home", "office"]}],
"wifi calling": false,
"mobile hotspot": false,
"mobile data": false
},
"bluetooth": [true, {"paired": ["headphones", "laptop"]}],
"sound": {
"volume": 65, "vibration": true,
"ringtone": "guitar", "notification": "ping"
},
"display": {
"brightness": {"auto": true, "level": 80},
"wallpaper": "trees",
"navigation bar": "gesture",
"font": 70,
"timeout time": 30
}
}
Note - ( The default path separator is ‘\’ - two back slashes - make sure that the fist backslash is not escaped by the second backslash. This can be done by prefixing the string with an ‘r’ or by using ‘\\’ as the seperator. You can change the path separator properties using the set_path_separator_properties()
method. )
Here is some code being run in the terminal using paths to navigate the data. It shows the difference between absolute vs relative paths.
Absolute:
>>> data = T4Json('hero_file.json')
>>> data.read(r'display\\brightness\\auto')
True
>>> data.read(r'internet\\wifi\\1\\known')
['home', 'office']
>>> data.read(r'display\\brightness\\level')
80
>>> data.read('sound')
{'volume': 65, 'vibration': True, 'ringtone': 'guitar', 'notification': 'ping'}
Relative:
>>> data.set_working_level(r'internet\\wifi\\1')
>>> data.read(r'.\\known\\0')
home
>>> data.read(r'.\\known')
['home', 'office']
>>> data.read(r'..\\0')
True
>>> data.read(r'..\\..\\..\\bluetooth\\1\\paired')
['headphones', 'laptop']
>>> data.read(r'..\\..\\..\\sound\\volume')
65
>>> data.read(r'..\\..\\..\\display\\brightness')
{'auto': True, 'level': 80}
Note - (There can be a separator at the beginning of the path if you want it. Sometimes it may be necessary to do that if there is a key that is an empty string “”. This is because an empty string “” is used to access the base level. So both \\formed
and formed
would be the same thing.)
Using these relative paths we not only can read but can do all sorts of edits easily and without the hassle of always having to walk down the path of nested data.
Searching the Data
You can search the data for a specific key if the keys value is not a pair container. We will use this URL as an example:
>>> data = T4Json('https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json')
>>> data.search('powers')
Look at the json data from the URL and see how it looks compared to the searched data below.
[
"Radiation resistance",
"Turning tiny",
"Radiation blast",
"Million tonne punch",
"Damage resistance",
"Superhuman reflexes",
"Immortality",
"Heat Immunity",
"Inferno",
"Teleportation",
"Interdimensional travel"
]
Flattening Nested Data
Flattening nested data is turning something like this [[1, 2, 3, [4, 5]], 6, 7, 8]
into this [1, 2, 3, 4, 5, 6, 7, 8]
. Nested data can be flattened using the T4Json.flatten()
method.
There are basically, two different ways that T4Json data can be flattened:
- Grounding: All the kay/value pairs (that do not contain containers as values) are moved to the base level. Any key/value pairs that have the same keys get their values combined or replaced.
- Chaining: All the keys get chained togather. The values (that are not containers) remain the same.
Grounding:
We will be using the data from this URL as example data.
>>> data = T4Json('https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json')
>>> data.flatten()
>>> data
Look at the original json data from the URL and compare it with the flattened data below.
{
"squadName": "Super Hero Squad",
"homeTown": "Metro City",
"formed": 2016,
"secretBase": "Super tower",
"active": true,
"name": [
"Molecule Man",
"Madame Uppercut",
"Eternal Flame"
],
"age": [
29,
39,
1000000
],
"secretIdentity": [
"Dan Jukes",
"Jane Wilson",
"Unknown"
],
"powers": [
"Radiation resistance",
"Turning tiny",
"Radiation blast",
"Million tonne punch",
"Damage resistance",
"Superhuman reflexes",
"Immortality",
"Heat Immunity",
"Inferno",
"Teleportation",
"Interdimensional travel"
]
}
Chaining:
We will be using this data as an example:
{
"internet": {
"airplane mode": false,
"wifi": [true, {"known": ["home", "office"]}],
"wifi calling": false,
"mobile hotspot": false
},
"bluetooth": [true, {"paired": ["headphones", "laptop"]}],
"sound": {
"volume": 65, "vibration": true,
"ringtone": "guitar", "notification": "ping"
},
"display": {
"brightness": {"auto": true, "level": 80},
"wallpaper": "trees",
"navigation bar": "gesture",
"font": 70,
"timeout time": 30
}
}
We will then run the fallowing code to flatten the data:
>>> data = T4Json('example.json')
>>> data.flatten(chain_keys=True)
>>> data
And here is the result:
{
"bluetooth": [true],
"internet_airplane mode": false,
"internet_wifi": [true],
"internet_wifi calling": false,
"internet_mobile hotspot": false,
"sound_volume": 65,
"sound_vibration": true,
"sound_ringtone": "guitar",
"sound_notification": "ping",
"display_wallpaper": "trees",
"display_navigation bar": "gesture",
"display_font": 70,
"display_timeout time": 30,
"bluetooth_paired": ["headphones", "laptop"],
"internet_wifi_known": ["home", "office"],
"display_brightness_auto": true,
"display_brightness_level": 80
}
Note - when there is only one item in a list such as {"bluetooth": [true]}
from above, you can set the parameter convert_singular_lists
of the flatten()
method to True
and the output will be {"bluetooth": true}
instead of {"bluetooth": [true]}
.
Dependencies
The only third party dependency is the “request” module.
Change Log - Latest Fixes & Improvements
v1.4.3
- Added
multi_iter()
method to T4Json instance so that multiple variables can be looped through the data at the same time. - Also added
multi_iter()
as a global function. - Cleaned up code and made it just a bit faster.
- The dunder methods of the T4Json class were improved.
v1.4.2
- Added
types()
method to T4Json instance. - Added
convert_singular_lists()
method. - Added convert_singular_lists parameter to
flatten()
method. - The
flatten()
method should generally be up to 15% faster. - The chain_key_include_index of the
flatten()
method was fixed/improved. - Cleaned up code in internal methods.
v1.4.1
- Added support for re-calling T4Json instances to load new data.
- Changed the
chain_key
parameter tochain_keys
within theflatten()
method.
v1.4.0
- Slicing Operations now supported on T4Json instances.
- Support for adding and subtracting items or pairs to/from T4Json instances.
- Support for iterating through a T4Json instance.
- Support for getting the length of a T4Json instance - (number of all the pairs/items on the first level).
- Support for checking equality (of data) between two T4Json instances.
- Support for checking in-equality (number of all the pairs/items on the first level) between two T4Json instances.
- Default support for printing a T4Json instance.
- Adding a pretty print method.
- Cleaned up code.
v1.3.3
- Greatly improved the error messages.
- Fixed t4json.
save()
method. - Improved t4json.
load()
&load_file()
&load_from_url()
&load_from_string()
- Added t4json.
load_object()
for loading python objects. - Added new parameters to t4json.
load_from_url()
for makingPOST
(and others) requests. Also added support for headers and body. - Improved walking up levels in nested data using paths.
- Improved support for key paths to work with non-string objects that are keys.
- Cleaned up code in general.
Roadmap
- Build better search algorithms.
- Improve Documentation & move it to a better/more-organized website.
- Make even more improvements on error messages.
- Improve the docstrings
License
MIT Copyright (c) 2022 Isaac Wolford
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Contact
Email: cybergeek.1943@gmail.com