;bin: helpers for downloading from simplefin.org, a bank aggregator
This commit is contained in:
parent
bdf5e7d06e
commit
54e711936f
28
bin/simplefinjson
Executable file
28
bin/simplefinjson
Executable file
@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# simplefinjson 1.0 - (c) Simon Michael 2025
|
||||||
|
# Download accounts and recent transactions history from SimpleFIN, as JSON.
|
||||||
|
#
|
||||||
|
# Requirements:
|
||||||
|
# a SimpleFIN account with financial institution(s) and app connection configured
|
||||||
|
# GNU date
|
||||||
|
# jq to prettify
|
||||||
|
|
||||||
|
# Insert an access token here, acquired with simplefinsetup.
|
||||||
|
# (Or use a secrets manager, like https://bitwarden.com/help/secrets-manager-quick-start.)
|
||||||
|
SIMPLEFIN_ACCESS_URL=''
|
||||||
|
|
||||||
|
# Run GNU date, which is gdate on mac.
|
||||||
|
date() { if hash gdate 2>/dev/null; then gdate "$@"; else date "$@"; fi }
|
||||||
|
|
||||||
|
START=`date +%s -d '-30 days'`
|
||||||
|
|
||||||
|
curl -sL "$SIMPLEFIN_ACCESS_URL/accounts?start-date=$START" | jq
|
||||||
|
|
||||||
|
# https://www.simplefin.org/protocol.html#http-endpoints
|
||||||
|
# https://www.simplefin.org/protocol.html#get-accounts
|
||||||
|
# Parameter Required Description
|
||||||
|
# start-date optional If given, transactions will be restricted to those on or after this Unix epoch timestamp.
|
||||||
|
# end-date optional If given, transactions will be restricted to those before (but not on) this Unix epoch timestamp.
|
||||||
|
# pending optional If pending=1 is provided, pending transactions will be included (if supported). By default, pending transaction are NOT included.
|
||||||
|
# account optional If given, only return information related to the given account id. May be specified multiple times.
|
||||||
|
# balances-only optional If balances-only=1 is provided, no transaction data is returned.
|
||||||
77
bin/simplefinjson2csv
Executable file
77
bin/simplefinjson2csv
Executable file
@ -0,0 +1,77 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# simplefinjson2csv 1.0 - (c) Simon Michael 2025
|
||||||
|
|
||||||
|
__version__ = "1.0"
|
||||||
|
__author__ = "Simon Michael"
|
||||||
|
versionmsg = f"%prog {__version__}, by {__author__} 2025; part of the hledger project."
|
||||||
|
usagemsg = """%prog [options] [JSONFILE|-] [-]
|
||||||
|
|
||||||
|
Read SimpleFIN /accounts JSON from a JSONFILE or stdin;
|
||||||
|
write each account's transactions as date-ordered CSV,
|
||||||
|
to separate CSV files or to stdout.
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
python 3
|
||||||
|
a SimpleFIN account with financial institution(s) and app connection configured.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
$ simplefinjson | simplefinjson2csv
|
||||||
|
$ simplefinjson >sf.json; simplefinjson2csv sf.json -
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pprint import pprint as pp
|
||||||
|
import csv
|
||||||
|
import datetime
|
||||||
|
import decimal
|
||||||
|
import json
|
||||||
|
import optparse
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def parse_options():
|
||||||
|
parser = optparse.OptionParser(usage=usagemsg, version=versionmsg)
|
||||||
|
opts, args = parser.parse_args()
|
||||||
|
if len(args) > 2:
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit()
|
||||||
|
return opts, args
|
||||||
|
|
||||||
|
def main():
|
||||||
|
opts, args = parse_options()
|
||||||
|
with open(args[0],'r') if len(args) > 0 and not args[0]=='-' else sys.stdin as inp:
|
||||||
|
|
||||||
|
i = json.load(inp)
|
||||||
|
for a in i['accounts']: #[0:1]:
|
||||||
|
aid = a['id']
|
||||||
|
aname = a['name']
|
||||||
|
oname = a['org']['name']
|
||||||
|
ts = a['transactions']
|
||||||
|
if len(args) < 2:
|
||||||
|
fname = f'sf-{aid}.csv'
|
||||||
|
out = open(fname,'w')
|
||||||
|
print(f"writing {len(ts)} transactions to {fname}")
|
||||||
|
else:
|
||||||
|
out = sys.stdout
|
||||||
|
w = csv.writer(out, quoting=csv.QUOTE_ALL)
|
||||||
|
w.writerow([
|
||||||
|
"date",
|
||||||
|
"id",
|
||||||
|
"amount",
|
||||||
|
"description",
|
||||||
|
"payee",
|
||||||
|
"memo"
|
||||||
|
])
|
||||||
|
|
||||||
|
for t in reversed(a['transactions']):
|
||||||
|
dt = datetime.datetime.fromtimestamp(t['posted'])
|
||||||
|
# dtl = dt.astimezone()
|
||||||
|
w.writerow([
|
||||||
|
dt.strftime('%Y-%m-%d'), # %H:%M:%S %Z'),
|
||||||
|
t['id'],
|
||||||
|
t['amount'],
|
||||||
|
t['description'],
|
||||||
|
t['payee'],
|
||||||
|
t['memo']
|
||||||
|
])
|
||||||
|
|
||||||
|
if __name__ == "__main__": main()
|
||||||
9
bin/simplefinsetup
Executable file
9
bin/simplefinsetup
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
# Acquire an access url for SimpleFIN.
|
||||||
|
|
||||||
|
# Insert a setup token here, acquired from the website, then run this script once.
|
||||||
|
SETUP_TOKEN='' # demo: aHR0cHM6Ly9iZXRhLWJyaWRnZS5zaW1wbGVmaW4ub3JnL3NpbXBsZWZpbi9jbGFpbS9ERU1PLXYyLTM5RTFGQThFM0Y5NjUxNTQ3REZB
|
||||||
|
|
||||||
|
CLAIM_URL="$(echo "$SETUP_TOKEN" | base64 --decode)"
|
||||||
|
export SIMPLEFIN_ACCESS_URL=$(curl -s -H "Content-Length: 0" -X POST "$CLAIM_URL")
|
||||||
|
echo $SIMPLEFIN_ACCESS_URL
|
||||||
Loading…
Reference in New Issue
Block a user