comdirect ingest: some code structurerefinement

This commit is contained in:
2026-09-11 10:16:51 +02:00
parent f50b28a387
commit d502e9ef0d
11 changed files with 83 additions and 40 deletions
+1
View File
@@ -11,6 +11,7 @@ wheels/
# Environment variables
.env
settings.py
# Database instances
*.db
+1
View File
@@ -32,5 +32,6 @@ build-backend = "uv_build"
dev = [
"black>=26.5.1",
"debugpy>=1.8.21",
"faker>=40.38.0",
"polyfactory>=3.3.0",
]
+32
View File
@@ -0,0 +1,32 @@
from faker import Faker
from src.models import ComdirectCreditCard, ComdirectDepot, ComdirectGiro
from src.settings.constants import Currency
from src.settings.models import AccountInfo
fake = Faker()
BANK_ACCOUNTS = {
"comdirect": {
"Girokonto": AccountInfo(
iban=fake.iban(),
ingestion_function=lambda x: ComdirectGiro.model_validate(x),
currency=Currency.EUR,
),
"Visa-Karte (Kreditkarte)": AccountInfo(
iban=fake.iban(),
ingestion_function=lambda x: ComdirectCreditCard.model_validate(x),
currency=Currency.EUR,
),
"Tagesgeld PLUS-Konto": AccountInfo(
iban=fake.iban(),
ingestion_function=lambda x: ComdirectGiro.model_validate(x),
currency=Currency.EUR,
),
"Depot": AccountInfo(
iban=fake.iban(),
ingestion_function=lambda x: ComdirectDepot.model_validate(x),
currency=Currency.EUR,
),
}
}
+1 -14
View File
@@ -4,20 +4,7 @@ from enum import Enum
from pydantic import BaseModel, Field, field_validator
IBAN_PATTERN = r"^[A-Z]{2}\d{2}[A-Z0-9]{11,30}$"
class Currency(str, Enum):
EUR = "EUR"
USD = "USD"
GBP = "GBP"
CHF = "CHF"
def __str__(self):
return self.value
def __repr__(self):
return f"Currency.{self.name}"
from src.settings.constants import IBAN_PATTERN, Currency
class Sign(str, Enum):
+8 -9
View File
@@ -3,8 +3,9 @@ import re
from enum import Enum, auto
from pathlib import Path
from settings import BANK_ACCOUNTS
from src.models import B4wExport
from src.settings.account_ingest import ACCOUNT_INGESTION_FUNCTIONS
from src.settings.models import AccountInfo
def _reader_raw(path: Path):
@@ -29,18 +30,16 @@ class EXPECT_LINE(Enum):
DATA = auto()
def reader_comdirect(path: Path):
bank_name = "comdirect"
ingestion_functions = ACCOUNT_INGESTION_FUNCTIONS.get(bank_name)
assert ingestion_functions
COMDIRECT_ACCOUNTS = BANK_ACCOUNTS.get("comdirect", {})
assert isinstance(COMDIRECT_ACCOUNTS, dict)
def reader_comdirect(path: Path):
result = {}
raw = _reader_raw_comdirect(path)
for account_name, account_data in raw.items():
ingestion_function = ingestion_functions.get(account_name)
assert ingestion_function
result[account_name] = list(map(ingestion_function, account_data))
account = COMDIRECT_ACCOUNTS.get(account_name)
assert isinstance(account, AccountInfo)
result[account_name] = list(map(account.ingestion_function, account_data))
return result
def _reader_raw_comdirect(path: Path):
View File
-10
View File
@@ -1,10 +0,0 @@
from src.models import ComdirectCreditCard, ComdirectDepot, ComdirectGiro
ACCOUNT_INGESTION_FUNCTIONS = {
"comdirect": {
"Girokonto": lambda x: ComdirectGiro.model_validate(x),
"Visa-Karte (Kreditkarte)": lambda x: ComdirectCreditCard.model_validate(x),
"Tagesgeld PLUS-Konto": lambda x: ComdirectGiro.model_validate(x),
"Depot": lambda x: ComdirectDepot.model_validate(x),
}
}
+18
View File
@@ -0,0 +1,18 @@
from enum import Enum
IBAN_PATTERN = r"^[A-Z]{2}\d{2}[A-Z0-9]{11,30}$"
class Currency(str, Enum):
EUR = "EUR"
USD = "USD"
GBP = "GBP"
CHF = "CHF"
def __str__(self):
return self.value
def __repr__(self):
return f"Currency.{self.name}"
+14
View File
@@ -0,0 +1,14 @@
from collections.abc import Callable
from pydantic import BaseModel, Field
from src.settings.constants import IBAN_PATTERN, Currency
class AccountInfo(BaseModel):
iban: str = Field(pattern=IBAN_PATTERN)
ingestion_function: Callable
currency: Currency
+6 -7
View File
@@ -1,19 +1,18 @@
from pathlib import Path
from src.models import ComdirectCreditCard, ComdirectDepot, ComdirectGiro
from src.reader import reader_comdirect
from src.settings.account_ingest import ACCOUNT_INGESTION_FUNCTIONS
from src.reader import COMDIRECT_ACCOUNTS, reader_comdirect
TEST_DATA_PATH = ".local/data/comdirect/umsaetze_9773063005_20260906-2043.csv"
def test_reader_comdirect():
bank_name = "comdirect"
assert bank_name in ACCOUNT_INGESTION_FUNCTIONS
test_path = Path(".local/data/comdirect/umsaetze_9773063005_20260906-2043.csv")
test_path = Path(TEST_DATA_PATH)
assert test_path.exists()
data = reader_comdirect(test_path)
assert data
assert len(data) == len(ACCOUNT_INGESTION_FUNCTIONS.get(bank_name))
assert set(data) == set(ACCOUNT_INGESTION_FUNCTIONS.get(bank_name))
assert len(data) == len(COMDIRECT_ACCOUNTS)
assert set(data) == set(COMDIRECT_ACCOUNTS)
assert all(isinstance(row, ComdirectGiro) for row in data["Girokonto"])
assert all(isinstance(row, ComdirectCreditCard) for row in data["Visa-Karte (Kreditkarte)"])
assert all(isinstance(row, ComdirectGiro) for row in data["Tagesgeld PLUS-Konto"])
Generated
+2
View File
@@ -128,6 +128,7 @@ dependencies = [
dev = [
{ name = "black" },
{ name = "debugpy" },
{ name = "faker" },
{ name = "polyfactory" },
]
@@ -146,6 +147,7 @@ requires-dist = [
dev = [
{ name = "black", specifier = ">=26.5.1" },
{ name = "debugpy", specifier = ">=1.8.21" },
{ name = "faker", specifier = ">=40.38.0" },
{ name = "polyfactory", specifier = ">=3.3.0" },
]