Skip to content

Usage πŸ”Œβš“

Settings Managementβš“

With Pydanticβš“

Pydantic provides a convenient interface for managing settings and reading them from environment variables or .env.

Pydantic settings management:

Documentation

Here is an example how you can manage your BankID environments:

settings.py

import functools

from pydantic import BaseSettings, Field

__all__ = ["BankIDSettings"]


class _BankIDSettings(BaseSettings):
    BANK_ID_CERTIFICATE: str
    BANK_ID_HOST: str = Field(default="https://appapi2.test.bankid.com/rp/v5.1")
    BANK_ID_KEY: str

    class Config:
        env_file = ".env"
        env_file_encoding = "UTF-8"


@functools.lru_cache()
def get_bank_id_settings() -> _BankIDSettings:
    return _BankIDSettings()


BankIDSettings: _BankIDSettings = get_bank_id_settings()

With Dynaconfβš“

Another good option to manage your settings and environments.

https://www.dynaconf.com/

BankID Factory πŸ¦πŸ­βš“

To initialize BankID you should use BankIDFactory class and then use make_client method to retrieve necessary client.

from settings import BankIDSettings

from bankid_asyncio import BankIDFactory

bank_id_factory = BankIDFactory(
    host=BankIDSettings.BANK_ID_HOST,
    certificate=BankIDSettings.BANK_ID_CERTIFICATE,
    key=BankIDSettings.BANK_ID_KEY,
)

Clientsβš“

Key differencesβš“

With Pydanticβš“

Clients with Pydantic require schema kwarg only attribute to all methods. It also returns BaseModel based results from all methods (all Pydantic features included).

It helps to easily transform results to complex structures written by schemas, that you can access with . dot notation, like class attributes, transform to dict with aliases and python snake case attribute names.

Asynchronousβš“

Clients with asyncio support, based on httpx.AsyncClient.

Synchronousβš“

Clients, that based on httpx.Client.

Async with Pydantic (preferable)βš“

Why this one preferable?

Because clients with Pydantic have extra validations (realization via BaseModel schema classes). It should prevent errors at develop & testing stages.

To use asynchronous BankID client with Pydantic use asynchronous=True together with pydantic=True inside make_client method.

from bankid_asyncio import (
    BankIDFactory,
    BankIDAsyncPydanticClient,
    AuthRequestSchema,
    AuthResponseSchema,
)
from settings import BankIDSettings

bank_id_factory = BankIDFactory(
    host=BankIDSettings.BANK_ID_HOST,
    certificate=BankIDSettings.BANK_ID_CERTIFICATE,
    key=BankIDSettings.BANK_ID_KEY,
)
bank_id_client: BankIDAsyncPydanticClient = bank_id_factory.make_client(
    asynchronous=True, pydantic=True
)

# === Async code ===
# Then you'll be able to use BankID client coroutines inside async code.
auth_response: AuthResponseSchema = await bank_id_client.auth(
    schema=AuthRequestSchema(user_ip="127.0.0.1")
)

TODO

Make demo (example purposes) repository with FastAPI based back-end using this client.

Warning

async methods (coroutines) should be run from async code.

Async without Pydanticβš“

To use asynchronous BankID client without Pydantic use asynchronous=True together with pydantic=False inside make_client method.

from bankid_asyncio import BankIDFactory, BankIDAsyncClient
from settings import BankIDSettings

bank_id_factory = BankIDFactory(
    host=BankIDSettings.BANK_ID_HOST,
    certificate=BankIDSettings.BANK_ID_CERTIFICATE,
    key=BankIDSettings.BANK_ID_KEY,
)
bank_id_client: BankIDAsyncClient = bank_id_factory.make_client(
    asynchronous=True, pydantic=False
)

# === Async code ===
# Then you'll be able to use BankID client coroutines inside async code.
auth_response = await bank_id_client.auth(user_ip="127.0.0.1")

Warning

async methods (coroutines) should be run from async code.

Sync with Pydanticβš“

To use synchronous BankID client with Pydantic use asynchronous=False together with pydantic=True inside make_client method.

from bankid_asyncio import (
    BankIDFactory,
    BankIDSyncPydanticClient,
    AuthRequestSchema,
    AuthResponseSchema,
)
from settings import BankIDSettings

bank_id_factory = BankIDFactory(
    host=BankIDSettings.BANK_ID_HOST,
    certificate=BankIDSettings.BANK_ID_CERTIFICATE,
    key=BankIDSettings.BANK_ID_KEY,
)
bank_id_client: BankIDSyncPydanticClient = bank_id_factory.make_client(
    asynchronous=False, pydantic=True
)

auth_response: AuthResponseSchema = bank_id_client.auth(
    schema=AuthRequestSchema(user_ip="127.0.0.1")
)
# Possible usage of responses
print(
    auth_response.order_ref, auth_response.auto_start_token,
    auth_response.qr_start_token, auth_response.qr_start_secret,
)
print(auth_response.dict(), auth_response.json())
print(auth_response.dict(by_alias=True), auth_response.json(by_alias=True))

Example output
66d2323a-40a0-49e2-822d-f95f2fdc1c58 556080cd-aa51-4c37-82e8-f34d6dcebf4b 36d7f12b-52f5-44c4-9514-2a5d3d2b22d8 33b73952-f2dd-4c99-a727-c7ae77bdc834
{'order_ref': '66d2323a-40a0-49e2-822d-f95f2fdc1c58', 'auto_start_token': '556080cd-aa51-4c37-82e8-f34d6dcebf4b', 'qr_start_token': '36d7f12b-52f5-44c4-9514-2a5d3d2b22d8', 'qr_start_secret': '33b73952-f2dd-4c99-a727-c7ae77bdc834'} {"order_ref": "66d2323a-40a0-49e2-822d-f95f2fdc1c58", "auto_start_token": "556080cd-aa51-4c37-82e8-f34d6dcebf4b", "qr_start_token": "36d7f12b-52f5-44c4-9514-2a5d3d2b22d8", "qr_start_secret": "33b73952-f2dd-4c99-a727-c7ae77bdc834"}
{'orderRef': '66d2323a-40a0-49e2-822d-f95f2fdc1c58', 'autoStartToken': '556080cd-aa51-4c37-82e8-f34d6dcebf4b', 'qrStartToken': '36d7f12b-52f5-44c4-9514-2a5d3d2b22d8', 'qrStartSecret': '33b73952-f2dd-4c99-a727-c7ae77bdc834'} {"orderRef": "66d2323a-40a0-49e2-822d-f95f2fdc1c58", "autoStartToken": "556080cd-aa51-4c37-82e8-f34d6dcebf4b", "qrStartToken": "36d7f12b-52f5-44c4-9514-2a5d3d2b22d8", "qrStartSecret": "33b73952-f2dd-4c99-a727-c7ae77bdc834"}

Sync without Pydanticβš“

To use synchronous BankID client without Pydantic use asynchronous=False together with pydantic=False inside make_client method.

from bankid_asyncio import BankIDFactory, BankIDSyncClient
from settings import BankIDSettings

bank_id_factory = BankIDFactory(
    host=BankIDSettings.BANK_ID_HOST,
    certificate=BankIDSettings.BANK_ID_CERTIFICATE,
    key=BankIDSettings.BANK_ID_KEY,
)
bank_id_client: BankIDSyncClient = bank_id_factory.make_client(
    asynchronous=False, pydantic=False
)

auth_response = bank_id_client.auth(user_ip="127.0.0.1")

# Results from clients is simple python's dict
print(auth_response)

Example output
{'orderRef': 'f7508caf-5e3c-40ed-b8a0-b47e3b82819f', 'autoStartToken': '45dd8454-9b43-4b3d-bbe8-ced64056d415', 'qrStartToken': '19f814b1-a198-4328-be1f-83a02f46890a', 'qrStartSecret': '663fee80-0a25-40a3-8d1b-a5c4046c01f1'}