Skip to content

Instantly share code, notes, and snippets.

Created Apr 30, 2019
What would you like to do?
A highly-specific Python 3 script operating on YNAB API JSON
#!/usr/bin/env python3
# Invoke like this:
# $ ./ ./data.json
# -or-
# $ ./ ./data.json "fire" "just for fun" "true expenses"
# Where the quoted parameters are _category groups_ to ignore
import os
import sys
import json
import pprint
def get_budgeted_amt(d):
b = d["budgeted"]
if b <= 0:
return 0
# currency units are x1k, so div here to get real value out
return b / 1_000
def main(args):
json_file_path = args[0] if len(args) > 0 else None
if json_file_path:
print(f" info | reading `{json_file_path}`")
# shift the array to remove the json file path from the front of `args`
args = args[1:]
sys.exit("error | please provide a path to a JSON file containing data from the `/budgets/{budget_id}` endpoint")
json_d = None
with open(json_file_path, 'r') as fh:
json_d = json.load(fh)
if not json_d or json_d == {}:
sys.exit("error | failed to read JSON data")
json_d = json_d["data"]["budget"]
category_group_names_to_remove = [a.lower().strip() for a in args] if args else [ ]
category_group_ids_to_remove = [
for cg_d in json_d["category_groups"]
if cg_d["name"].lower().strip() in category_group_names_to_remove
print(f" info | ignored category group IDs = {category_group_ids_to_remove}")
for month_d in json_d["months"]:
month_d["budgeted"] = get_budgeted_amt(month_d)
for category_d in month_d["categories"]:
category_d["budgeted"] = get_budgeted_amt(category_d)
results = [
c_d["name"].encode('ascii', 'ignore').decode('ascii').strip()
) for c_d in d["categories"]
if c_d["category_group_id"] not in category_group_ids_to_remove and c_d["budgeted"] > 0]
) for d in json_d["months"]
# uncomment these 2 lines if you want to print JSON instead (be sure to comment out the `pprint` line)
#j = json.dumps(results)
if __name__ == '__main__':
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment