Skip to content

Instantly share code, notes, and snippets.

@bzupnick
Created April 20, 2026 14:48
Show Gist options
  • Select an option

  • Save bzupnick/17c80d0b14ef6ac59bccaad81c5f81c8 to your computer and use it in GitHub Desktop.

Select an option

Save bzupnick/17c80d0b14ef6ac59bccaad81c5f81c8 to your computer and use it in GitHub Desktop.
Wells Fargo CSV output --> YNAB importable CSV
#!/usr/bin/env python3
"""Convert given Wells Fargo exported CSV to YNAB import-compatible CSV format.
Usage:`python3 wells_fargo_to_ynab_import.py <input.csv> [output.csv]`
# outputs: input_ynab.csv
Or specify a custom output path:
python3 wells_fargo_to_ynab_import.py "CreditCard.csv" my_output.csv
# outputs: my_output.csv
The script maps: Date → Date (already MM/DD/YYYY), Description → Payee, Amount (negative = outflow) → Amount, and leaves Memo blank.
"""
import csv
import sys
from pathlib import Path
def convert(input_path: str, output_path: str | None = None) -> None:
input_file = Path(input_path)
if output_path is None:
output_path = str(input_file.parent / (input_file.stem + "_ynab.csv"))
rows_written = 0
with open(input_file, newline="", encoding="utf-8-sig") as infile, \
open(output_path, "w", newline="", encoding="utf-8") as outfile:
reader = csv.reader(infile)
writer = csv.writer(outfile)
writer.writerow(["Date", "Payee", "Memo", "Amount"])
for row in reader:
if not row or len(row) < 5:
continue
date = row[0].strip()
amount = row[1].strip()
payee = row[4].strip()
writer.writerow([date, payee, "", amount])
rows_written += 1
print(f"Wrote {rows_written} transactions → {Path(output_path).name}")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python3 wells_fargo_to_ynab_import.py <input.csv> [output.csv]")
sys.exit(1)
convert(sys.argv[1], sys.argv[2] if len(sys.argv) > 2 else None)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment