Skip to content

Instantly share code, notes, and snippets.

@bpeterso2000
Created December 20, 2016 16:14
Show Gist options
  • Save bpeterso2000/d37d40f27391754e63e45f9fc3b138f6 to your computer and use it in GitHub Desktop.
Save bpeterso2000/d37d40f27391754e63e45f9fc3b138f6 to your computer and use it in GitHub Desktop.
"""
JSON Keys.
A simple command-line utility that allows the user to quickly:
1. Set the root level of JSON data by using a JSON pointer.
2. Select items to pull from each object in a JSON array.
3. Drop items from objects in a JSON array.
It is not uncommon for an API to return a JSON array of objects containing
much more detail than is needed. This tools is designed to allow the user to
quickly filter, view and extract relevant information.
If values alone are sufficient and you don't care about preserving
key/value pairs then consider using JMESPath instead. http://jmespath.org
"""
import json
import sys
from collections import Mapping
from operator import contains
import click
import jsonpointer
from toolz import curry, dissoc, keyfilter
def exit_on_error(error_mesg):
"""Print error message and exit."""
print(str(error_mesg), file=sys.stderr)
sys.exit(1)
def parse_keys(keys):
"""Parse comma separated items."""
return [i.strip() for i in keys.split(',')]
@click.command()
@click.argument('jsonfile', type=click.File('r'))
@click.option('-r', '--rootkey', help='JSON pointer')
@click.option('-g', '--getkeys', help='comma separated property names')
@click.option('-d', '--dropkeys', help='comma separated property names')
def main(jsonfile, rootkey, getkeys, dropkeys):
"""Exectue on the command-line arguments & options."""
try:
obj = json.load(jsonfile)
except EnvironmentError as e:
print(str(e), file=sys.stderr)
sys.exit(1)
if rootkey:
try:
obj = jsonpointer.resolve_pointer(obj, rootkey)
except jsonpointer.JsonPointerException as e:
exit_on_error(e)
if getkeys:
keys = curry(contains)(parse_keys(getkeys))
try:
obj = (keyfilter(keys, obj) if isinstance(obj, Mapping)
else [keyfilter(keys, d) for d in obj])
except TypeError as e:
exit_on_error(e)
if dropkeys:
keys = parse_keys(dropkeys)
try:
obj = (dissoc(obj, *keys) if isinstance(obj, Mapping)
else [dissoc(d, *keys) for d in obj])
except TypeError as e:
exit_on_error(e)
print(json.dumps(obj, indent=2))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment