Download csv_import.py from smlflg/FireTracker: direct link, hf CLI and curl.
- Browser
- Download file 3.15 kB
-
https://huggingface.co/smlflg/FireTracker/resolve/main/csv_import.py
- Command line
-
hf download hf://smlflg/FireTracker/csv_import.py
-
curl -L -o csv_import.py https://huggingface.co/smlflg/FireTracker/resolve/main/csv_import.py
3.15 kB
| import csv | |
| import io | |
| from typing import Dict, Any | |
| def parse_bank_csv(content: bytes) -> Dict[str, Any]: | |
| """ | |
| Parse a bank CSV file and return categorized transactions with summary statistics. | |
| Args: | |
| content: Raw bytes of the CSV file | |
| Returns: | |
| Dict with keys: | |
| - transactions: List of transaction dicts with date, description, amount | |
| - total_income: Sum of positive amounts | |
| - total_expenses: Sum of absolute negative amounts | |
| - net: Total income minus total expenses | |
| - count: Number of transactions | |
| - monthly_estimate: Average monthly expenses based on unique months in data | |
| """ | |
| text = content.decode('utf-8', errors='replace') | |
| lines = text.strip().split('\n') | |
| transactions = [] | |
| total_income = 0 | |
| total_expenses = 0 | |
| # Try to detect format | |
| try: | |
| # Try semicolon first (German standard) | |
| if lines: | |
| dialect = csv.Sniffer().sniff(lines[0], delimiters=';,\t') | |
| reader = csv.DictReader(io.StringIO(text), delimiter=dialect.delimiter) | |
| else: | |
| reader = csv.DictReader(io.StringIO(text), delimiter=';') | |
| except csv.Error: | |
| reader = csv.DictReader(io.StringIO(text), delimiter=';') | |
| for row in reader: | |
| amount = None | |
| date_str = None | |
| description = "" | |
| for key, val in row.items(): | |
| if not key: | |
| continue | |
| key_lower = key.lower().strip() | |
| # Amount detection | |
| if key_lower in ('betrag', 'amount', 'umsatz', 'betrag (eur)', 'wert'): | |
| try: | |
| amount = float(val.replace('.', '').replace(',', '.').strip().strip('"')) | |
| except (ValueError, AttributeError): | |
| pass | |
| # Date detection | |
| if key_lower in ('buchungstag', 'datum', 'date', 'buchungsdatum', 'valuta'): | |
| date_str = val.strip().strip('"') | |
| # Description detection | |
| if key_lower in ('verwendungszweck', 'buchungstext', 'description', 'empfaenger', | |
| 'auftraggeber / beguenstigter', 'zahlungsempfaenger', 'beschreibung'): | |
| if val and val.strip(): | |
| description = val.strip().strip('"')[:100] | |
| if amount is not None: | |
| if amount > 0: | |
| total_income += amount | |
| else: | |
| total_expenses += abs(amount) | |
| transactions.append({ | |
| "date": date_str or "", | |
| "description": description, | |
| "amount": amount, | |
| }) | |
| # Calculate monthly estimate based on unique months in data | |
| unique_months = len(set(t['date'][:7] for t in transactions if t['date'])) | |
| monthly_estimate = total_expenses / max(1, unique_months) if transactions else 0 | |
| return { | |
| "transactions": transactions, | |
| "total_income": round(total_income, 2), | |
| "total_expenses": round(total_expenses, 2), | |
| "net": round(total_income - total_expenses, 2), | |
| "count": len(transactions), | |
| "monthly_estimate": round(monthly_estimate, 2), | |
| } | |