Verified Commit 9195c1f8 authored by Jakob Moser's avatar Jakob Moser
Browse files

Add method to get FinTS Client

You need the Bankleitzahl (which we get from the IBAN), user name and password (which the FinTS standard calls PIN), the URL and the product id to create a client.

## Why `@contextmanager`?

The Python `fints` library (https://python-fints.readthedocs.io/en/latest/quickstart.html) then suggests a construct like:

```
client = FinTS3PinTanClient(...)
with client:
    foo(client)
```

I personally want to use it like this in my code:

```
with bank_account._fints_client(...) as client:
    foo(client)
```

To allow the `as` construction (see https://docs.python.org/3/reference/compound_stmts.html#with), the bank_account._fints_client(...).__enter__() needs to return the client object. I didn't want to create a throwaway object for that, but luckily, the @contextmanager decorator does exactly that.

Once the user of my library exits their `with bank_account._fints_client(...) as client:` context, the code returns to the line after my "yield client", which will then close the "with client" context, which will correctly close the client object as the fints library authors intended.
parent 07213fcd
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
from collections.abc import Generator
from contextlib import contextmanager

from fints.client import FinTS3PinTanClient
from schwifty import IBAN
from sqlalchemy.orm import Mapped, mapped_column

@@ -29,3 +33,15 @@ class BankAccount(Base):
    # Technically, if we hadn't registered the product as "FinTS Kernel" (which seems to be for individual/testing use
    # only), we could have just hardcoded the product ID).
    product_id: Mapped[str]

    @contextmanager
    def _fints_client(self, password: str) -> Generator[FinTS3PinTanClient]:
        client = FinTS3PinTanClient(
            bank_identifier=self.iban.bank_code,
            user_id=self.user,
            pin=password,
            server=self.url,
            product_id=self.product_id,
        )
        with client:
            yield client