Skip to content

Instantly share code, notes, and snippets.

@lena
Last active March 22, 2020 02:22
Show Gist options
  • Save lena/347cfcf36ae2f6d472d373d71300fa5c to your computer and use it in GitHub Desktop.
Save lena/347cfcf36ae2f6d472d373d71300fa5c to your computer and use it in GitHub Desktop.
Solution to Onboarding Project #1
#! /usr/bin/env python
import csv
import fire
import json
import pyjq
"""CSV TO JSON CLI
Usage:
python csv_to_json.py convert --csv_file="file.csv" --json_file="file.json"
python csv_to_json.py convert --csv_file="file.csv" --json_file="file.json" --verbose=False --json_indent_spaces=2
python csv_to_json.py convert --csv_file="file.csv" --json_file="file.json" --jq_fn="first" --jq_str='.data[] | {"param_name": ."First Name"}'
Options:
<csv_file> (required) Location of existing input CSV file you want to convert to JSON.
<json_file> (required) Location of new JSON file (existing files will be overwritten!).
<verbose> (default: True) True if you want to print to stdout.
<json_indent_spaces> (default: 4) Number of spaces to indent json output (ignored if json_minified=True).
<json_minified> (default: False) True if you want to minify whitespace in the json output.
The following *optional* arguments are for running JQ queries against the new JSON object:
<jq_fn> JQ query method to run, must be one of: 'all' | 'first' | 'one' | 'compile'.
<jq_str> JQ query string, to be passed to the JQ query method.
<jq_default> JQ default value if nothing is found from the JQ query.
"""
JQ_FNS = ('all', 'first', 'one', 'compile')
def convert(csv_file, json_file, verbose=True, json_indent_spaces=4,
json_minified=False, jq_fn=None, jq_str=None, jq_default=None):
if verbose:
print('Reading file {}...'.format(csv_file))
with open(csv_file, 'r') as thefile:
json_data = list(csv.DictReader(thefile))
if jq_fn:
json_data = apply_jq_query(jq_fn, jq_str, jq_default, json_data)
if verbose:
print('Writing to file {}:'.format(json_file))
print(json_data)
with open(json_file, 'w') as output_file:
kwargs_dict = {
'obj': json_data,
}
if not json_minified:
kwargs_dict['indent'] = json_indent_spaces
json_output = json.dumps(**kwargs_dict)
output_file.write(json_output)
def apply_jq_query(jq_fn, jq_str, jq_default, data):
if not jq_str or jq_fn not in JQ_FNS:
raise Exception('Invalid JQ arguments')
pyjq_method = getattr(pyjq, jq_fn)
data = pyjq_method(jq_str, {'data': data}, jq_default)
return data
if __name__ == '__main__':
fire.Fire()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment