From e6e2e85665e0b9f8b686309091e4d973e83318b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Fri, 25 Oct 2024 10:08:49 +0200 Subject: [PATCH] fix: avoid throttling issues with Fio API We cannot do info and last requests in 30 seconds, so instead introduce new API to fiobank module to return both info at once. The customization can be removed once https://github.com/honzajavorek/fiobank/pull/38 is released. Fixes WEBSITE-1Q --- weblate_web/payments/backends.py | 45 +++++++++++++++++++++++++++++--- weblate_web/payments/tests.py | 10 ------- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/weblate_web/payments/backends.py b/weblate_web/payments/backends.py index 3423b6dafc..d190329ca7 100644 --- a/weblate_web/payments/backends.py +++ b/weblate_web/payments/backends.py @@ -46,6 +46,9 @@ from .utils import send_notification if TYPE_CHECKING: + from collections.abc import Generator + from datetime import date, datetime + from django.http import HttpRequest, HttpResponseRedirect from django_stubs_ext import StrOrPromise from fakturace.invoices import Invoice @@ -464,6 +467,41 @@ class ThePayBitcoin(ThePayCard): thepay_method = 29 +class FioBankAPI(fiobank.FioBank): + """ + Fio API wrapper. + + Backported API from + https://github.com/honzajavorek/fiobank/pull/38. + + TODO: Remove this wrapper once it is released. + """ + + def _fetch_last( + self, from_id: str | None = None, from_date: str | date | datetime | None = None + ) -> dict: + if from_id and from_date: + raise ValueError("Only one constraint is allowed.") + + if from_id: + self._request("set-last-id", from_id=from_id) + elif from_date: + self._request("set-last-date", from_date=fiobank.coerce_date(from_date)) + + return self._request("last") + + def last( + self, from_id: str | None = None, from_date: str | date | datetime | None = None + ) -> Generator[dict]: + return self._parse_transactions(self._fetch_last(from_id, from_date)) + + def last_transactions( + self, from_id: str | None = None, from_date: str | date | datetime | None = None + ) -> tuple[dict, Generator[dict]]: + data = self._fetch_last(from_id, from_date) + return (self._parse_info(data), self._parse_transactions(data)) + + @register_backend class FioBank(LegacyBackend): # TODO: migrate from legacy backend @@ -519,10 +557,11 @@ def fetch_payments(cls, from_date: str | None = None) -> None: else: tokens = settings.FIO_TOKEN for token in tokens: - client = fiobank.FioBank(token=token) - info = client.info() + # TODO: change to fiobank.FioBank(token=token, decimal=True) with fiobank 4.0 + client = FioBankAPI(token=token) + info, transactions = client.last_transactions(from_date=from_date) currency = info["currency"] - for entry in client.last(from_date=from_date): + for entry in transactions: matches = [] # Extract from message if entry["recipient_message"]: diff --git a/weblate_web/payments/tests.py b/weblate_web/payments/tests.py index 6d3d3bbc90..6fe62e57e4 100644 --- a/weblate_web/payments/tests.py +++ b/weblate_web/payments/tests.py @@ -51,9 +51,6 @@ FIO_API = "https://fioapi.fio.cz/v1/rest/last/test-token/transactions.json" -FIO_INFO_API = ( - "https://fioapi.fio.cz/v1/rest/periods/test-token/{0}/{0}/transactions.json" -) FIO_TRASACTIONS = { "accountStatement": { "info": { @@ -266,13 +263,6 @@ def test_proforma(self): self.assertFalse(backend.complete(None)) self.check_payment(Payment.PENDING) responses.add(responses.GET, FIO_API, body=json.dumps(FIO_TRASACTIONS)) - responses.add( - responses.GET, - FIO_INFO_API.format( - date.today().isoformat() # noqa: DTZ011 - ), - body=json.dumps(FIO_TRASACTIONS), - ) FioBank.fetch_payments() self.check_payment(Payment.PENDING) self.assertEqual(len(mail.outbox), 1)