From e8a8844b101e2b86528163f1bb04a00f17a59105 Mon Sep 17 00:00:00 2001 From: Mathias Schneider Date: Sat, 5 Sep 2026 11:28:29 +0200 Subject: [PATCH] factories init (tbc) --- pyproject.toml | 5 +++++ src/models.py | 30 ++++++++++++++++-------------- tests/factories.py | 13 +++++++++++++ uv.lock | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 14 deletions(-) create mode 100644 tests/factories.py diff --git a/pyproject.toml b/pyproject.toml index 6c461a9..efe4800 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,3 +27,8 @@ module-root = "" [build-system] requires = ["uv_build>=0.12.9,<0.13.0"] build-backend = "uv_build" + +[dependency-groups] +dev = [ + "polyfactory>=3.3.0", +] diff --git a/src/models.py b/src/models.py index 4c8ca21..28ce945 100644 --- a/src/models.py +++ b/src/models.py @@ -22,6 +22,20 @@ class Currency(str, Enum): return f"Currency.{self.name}" +class Sign(str, Enum): + DEBIT = "DBIT" + CREDIT = "CRDT" + + def __str__(self): + return self.value + + def __repr__(self): + return f"Sign.{self.name}" + + def to_sign(self) -> int: + return -1 if self is Sign.DEBIT else 1 + + class B4wExport(BaseModel): id: int = Field(alias="Id1", description="internal B4w ID") account_iban: str = Field(alias="OwnrAcctIBAN", pattern=IBAN_PATTERN) @@ -30,7 +44,7 @@ class B4wExport(BaseModel): date_book: date = Field(alias="BookgDt") amount: Decimal = Field(alias="Amt") amount_currency: Currency = Field(alias="AmtCcy") - sign: int = Field(alias="CdtDbtInd") + sign: Sign = Field(alias="CdtDbtInd") reference: str = Field(alias="RmtInf") other_name: str = Field(alias="RmtdNm") other_iban: str = Field(alias="RmtdAcctIBAN") @@ -39,19 +53,7 @@ class B4wExport(BaseModel): @property def amount_signed(self) -> Decimal: - return self.amount * self.sign - - @field_validator("sign", mode="before") - @classmethod - def get_sign(cls, input_value: str) -> int: - if input_value == "DBIT": - return -1 - elif input_value == "CRDT": - return 1 - else: - raise ValidationError( - f"Invalid amount type: {input_value}. Expected DBIT or CRDT" - ) + return self.amount * self.sign.to_sign() @field_validator("category", mode="before") @classmethod diff --git a/tests/factories.py b/tests/factories.py new file mode 100644 index 0000000..6090f0a --- /dev/null +++ b/tests/factories.py @@ -0,0 +1,13 @@ +#!/bin/python + +from polyfactory.factories.pydantic_factory import ModelFactory + +from src.models import B4wExport + +CATEGORIES = [ + "single_category", + "root_category:parent_category:leaf_category", + ] + +class B4wExportFactory(ModelFactory[B4wExport]): + __model__ = B4wExport diff --git a/uv.lock b/uv.lock index 213b7d5..ce639ec 100644 --- a/uv.lock +++ b/uv.lock @@ -54,6 +54,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b2/b7/545d2c10c1fc15e48653c91efde329a790f2eecfbbf2bd16003b5db2bab0/dotenv-0.9.9-py2.py3-none-any.whl", hash = "sha256:29cf74a087b31dafdb5a446b6d7e11cbce8ed2741540e2339c69fbef92c94ce9", size = 1892, upload-time = "2025-02-19T22:15:01.647Z" }, ] +[[package]] +name = "faker" +version = "40.38.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "tzdata", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f2/55/baeae0ecb04ef56c92d6ac1ef7b3b965af0502ac9863fc85db7afc0884fd/faker-40.38.0.tar.gz", hash = "sha256:72e421098664edf38478f4269a5d5a539337de5da18883ce67cb1e6bb96b0b3a", size = 2029190, upload-time = "2026-09-01T19:19:46.958Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/b8/48cb8733de8448023983f64e81d7f731ce1459c21e93b9b29657e5c48cab/faker-40.38.0-py3-none-any.whl", hash = "sha256:69927515d61759c8a257540b8a91891cd622ba1c24a386b62a0a777e44ba46a9", size = 2065931, upload-time = "2026-09-01T19:19:45.234Z" }, +] + [[package]] name = "finanz-cockpit" version = "0.1.0" @@ -68,6 +80,11 @@ dependencies = [ { name = "sqlalchemy" }, ] +[package.dev-dependencies] +dev = [ + { name = "polyfactory" }, +] + [package.metadata] requires-dist = [ { name = "alembic", specifier = ">=1.19.1" }, @@ -79,6 +96,9 @@ requires-dist = [ { name = "sqlalchemy", specifier = ">=2.0.52" }, ] +[package.metadata.requires-dev] +dev = [{ name = "polyfactory", specifier = ">=3.3.0" }] + [[package]] name = "greenlet" version = "3.5.5" @@ -187,6 +207,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] +[[package]] +name = "polyfactory" +version = "3.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "faker" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/85/68/7717bd9e63ed254617a7d3dc9260904fb736d6ea203e58ffddcb186c64e4/polyfactory-3.3.0.tar.gz", hash = "sha256:237258b6ff43edf362ffd1f68086bb796466f786adfa002b0ac256dbf2246e9a", size = 348668, upload-time = "2026-02-22T09:46:28.01Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dd/34/b6f19941adcdaf415b5e8a8d577499f5b6a76b59cbae37f9b125a9ffe9f2/polyfactory-3.3.0-py3-none-any.whl", hash = "sha256:686abcaa761930d3df87b91e95b26b8d8cb9fdbbbe0b03d5f918acff5c72606e", size = 62707, upload-time = "2026-02-22T09:46:25.985Z" }, +] + [[package]] name = "pydantic" version = "2.13.5" @@ -318,3 +351,12 @@ sdist = { url = "https://files.pythonhosted.org/packages/a3/26/b09b8010994eccc3c wheels = [ { url = "https://files.pythonhosted.org/packages/67/81/4add07e5172b7ac40d8ed5ff580409a7801a4fe26d529bdd915401dabfbe/typing_inspection-0.4.4-py3-none-any.whl", hash = "sha256:65b8397ba37ccbce054456aaccddfc91e6e3083c92824df348d96ca832f3f147", size = 14750, upload-time = "2026-08-12T12:37:24.648Z" }, ] + +[[package]] +name = "tzdata" +version = "2026.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/92/ff/5a28bdfd8c3ebec42564ac7d0e54ca3db65044a9314a97f9564fa7a1e926/tzdata-2026.3.tar.gz", hash = "sha256:4a1518b8993086a7982523e071643f3c0e5f213e75b21318e78bcabfff9d1415", size = 198674, upload-time = "2026-07-10T08:50:37.887Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/6d/b53b99a9f2766d095985947a5782f1702cabb129a34f7a802d7197af832f/tzdata-2026.3-py2.py3-none-any.whl", hash = "sha256:dc096730c87af6cab1b171c9d532be840741ff5d459015e7f6947bd7d7e54931", size = 348168, upload-time = "2026-07-10T08:50:36.46Z" }, +]