From 4129ac7273fbd1d7d97621127e07adc07a3975ef Mon Sep 17 00:00:00 2001 From: Dmytro Samoylenko Date: Tue, 16 Apr 2024 21:34:33 +0000 Subject: [PATCH] Add configurable timeouts for http requests --- shkeeper/__init__.py | 11 +++++++++++ shkeeper/api_v1.py | 2 +- shkeeper/callback.py | 17 +++++++++++++---- shkeeper/modules/classes/bitcoin_like_crypto.py | 2 +- shkeeper/modules/classes/bnb.py | 7 +++---- shkeeper/modules/classes/ethereum.py | 2 +- shkeeper/modules/classes/tron_token.py | 2 +- shkeeper/modules/classes/xrp.py | 10 ++++------ shkeeper/modules/rates/binance.py | 2 +- shkeeper/modules/rates/manual.py | 2 +- 10 files changed, 37 insertions(+), 20 deletions(-) diff --git a/shkeeper/__init__.py b/shkeeper/__init__.py index d2051d4..914b914 100644 --- a/shkeeper/__init__.py +++ b/shkeeper/__init__.py @@ -1,3 +1,4 @@ +import functools import os import logging import secrets @@ -5,6 +6,7 @@ import shutil from flask import Flask +import requests from .utils import format_decimal @@ -41,6 +43,8 @@ def create_app(test_config=None): TRON_MULTISERVER_GUI=bool(os.environ.get('TRON_MULTISERVER_GUI')), FORCE_WALLET_ENCRYPTION=bool(os.environ.get('FORCE_WALLET_ENCRYPTION')), UNCONFIRMED_TX_NOTIFICATION=bool(os.environ.get('UNCONFIRMED_TX_NOTIFICATION')), + REQUESTS_TIMEOUT=int(os.environ.get('REQUESTS_TIMEOUT', 10)), + REQUESTS_NOTIFICATION_TIMEOUT=int(os.environ.get('REQUESTS_NOTIFICATION_TIMEOUT', 30)), ) if test_config is None: @@ -81,6 +85,13 @@ def default(self, obj): app.json_decoder = ShkeeperJSONDecoder app.json_encoder = ShkeeperJSONEncoder + for method in ("get", "options", "head", "post", "put", "patch", "delete"): + setattr( + requests, + method, + functools.partial(getattr(requests, method), timeout=app.config.get('REQUESTS_TIMEOUT')), + ) + db.init_app(app) migrate.init_app(app, db) with app.app_context(): diff --git a/shkeeper/api_v1.py b/shkeeper/api_v1.py index 8220d95..a0888c5 100644 --- a/shkeeper/api_v1.py +++ b/shkeeper/api_v1.py @@ -10,7 +10,7 @@ from flask import current_app as app from flask.json import JSONDecoder from flask_sqlalchemy import sqlalchemy -import requests +from shkeeper import requests from shkeeper import db from shkeeper.auth import basic_auth_optional, login_required, api_key_required diff --git a/shkeeper/callback.py b/shkeeper/callback.py index f5a7d27..62a0397 100644 --- a/shkeeper/callback.py +++ b/shkeeper/callback.py @@ -1,5 +1,5 @@ import click -import requests +from shkeeper import requests from flask import Blueprint from flask import current_app as app @@ -29,7 +29,12 @@ def send_unconfirmed_notification(crypto_name, txid, addr, amount): app.logger.warning(f'[{crypto_name}/{txid}] Posting {notification} to {invoice.callback_url} with api key {apikey}') try: - r = requests.post(invoice.callback_url, json=notification, headers={"X-Shkeeper-Api-Key": apikey}) + r = requests.post( + invoice.callback_url, + json=notification, + headers={"X-Shkeeper-Api-Key": apikey}, + timeout=app.config.get('REQUESTS_NOTIFICATION_TIMEOUT'), + ) except Exception as e: app.logger.error(f'[{crypto_name}/{txid}] Unconfirmed TX notification failed: {e}') return False @@ -68,8 +73,12 @@ def send_notification(tx): apikey = Crypto.instances[tx.crypto].wallet.apikey app.logger.warning(f'[{tx.crypto}/{tx.txid}] Posting {notification} to {tx.invoice.callback_url} with api key {apikey}') try: - r = requests.post(tx.invoice.callback_url, - json=notification, headers={"X-Shkeeper-Api-Key": apikey}) + r = requests.post( + tx.invoice.callback_url, + json=notification, + headers={"X-Shkeeper-Api-Key": apikey}, + timeout=app.config.get('REQUESTS_NOTIFICATION_TIMEOUT'), + ) except Exception as e: app.logger.error(f'[{tx.crypto}/{tx.txid}] Notification failed: {e}') return False diff --git a/shkeeper/modules/classes/bitcoin_like_crypto.py b/shkeeper/modules/classes/bitcoin_like_crypto.py index da3afde..9b8142f 100644 --- a/shkeeper/modules/classes/bitcoin_like_crypto.py +++ b/shkeeper/modules/classes/bitcoin_like_crypto.py @@ -4,7 +4,7 @@ import datetime import functools -import requests +from shkeeper import requests from shkeeper.modules.classes.crypto import Crypto diff --git a/shkeeper/modules/classes/bnb.py b/shkeeper/modules/classes/bnb.py index f02b4ba..6fd6fba 100644 --- a/shkeeper/modules/classes/bnb.py +++ b/shkeeper/modules/classes/bnb.py @@ -1,7 +1,7 @@ from abc import abstractmethod from os import environ import json -import requests +from shkeeper import requests import datetime from collections import namedtuple from decimal import Decimal @@ -28,7 +28,7 @@ def get_auth_creds(self): return (username, password) - def mkpayout(self, destination, amount, fee, subtract_fee_from_amount=False): + def mkpayout(self, destination, amount, fee, subtract_fee_from_amount=False): if self.crypto == self.network_currency and subtract_fee_from_amount: fee = Decimal(self.estimate_tx_fee(amount)['fee']) if fee >= amount: @@ -40,7 +40,7 @@ def mkpayout(self, destination, amount, fee, subtract_fee_from_amount=False): auth=self.get_auth_creds(), ).json(parse_float=Decimal) return response - + def getstatus(self): try: response = requests.post( @@ -59,4 +59,3 @@ def getstatus(self): except Exception as e: return "Offline" - diff --git a/shkeeper/modules/classes/ethereum.py b/shkeeper/modules/classes/ethereum.py index 3766ca6..c672e15 100644 --- a/shkeeper/modules/classes/ethereum.py +++ b/shkeeper/modules/classes/ethereum.py @@ -1,7 +1,7 @@ from abc import abstractmethod from os import environ import json -import requests +from shkeeper import requests import datetime from collections import namedtuple from decimal import Decimal diff --git a/shkeeper/modules/classes/tron_token.py b/shkeeper/modules/classes/tron_token.py index fc248f7..43cfab3 100644 --- a/shkeeper/modules/classes/tron_token.py +++ b/shkeeper/modules/classes/tron_token.py @@ -5,7 +5,7 @@ import json from collections import namedtuple -import requests +from shkeeper import requests from flask import current_app as app from shkeeper.modules.classes.crypto import Crypto diff --git a/shkeeper/modules/classes/xrp.py b/shkeeper/modules/classes/xrp.py index 3c04813..2395e65 100644 --- a/shkeeper/modules/classes/xrp.py +++ b/shkeeper/modules/classes/xrp.py @@ -1,7 +1,7 @@ from abc import abstractmethod from os import environ import json -import requests +from shkeeper import requests import datetime from collections import namedtuple from decimal import Decimal @@ -26,7 +26,7 @@ def get_auth_creds(self): return (username, password) - def mkpayout(self, destination, amount, fee, subtract_fee_from_amount=False): + def mkpayout(self, destination, amount, fee, subtract_fee_from_amount=False): if self.crypto == self.network_currency and subtract_fee_from_amount: fee = Decimal(self.estimate_tx_fee(amount)['fee']) if fee >= amount: @@ -38,8 +38,8 @@ def mkpayout(self, destination, amount, fee, subtract_fee_from_amount=False): auth=self.get_auth_creds(), ).json(parse_float=Decimal) return response - - + + def getstatus(self): try: response = requests.post( @@ -59,5 +59,3 @@ def getstatus(self): except Exception as e: return "Offline" - - diff --git a/shkeeper/modules/rates/binance.py b/shkeeper/modules/rates/binance.py index 71053c0..ebbf04d 100644 --- a/shkeeper/modules/rates/binance.py +++ b/shkeeper/modules/rates/binance.py @@ -1,7 +1,7 @@ import json from decimal import Decimal -import requests +from shkeeper import requests from shkeeper.modules.classes.rate_source import RateSource diff --git a/shkeeper/modules/rates/manual.py b/shkeeper/modules/rates/manual.py index 9d8e4db..8d69ad3 100644 --- a/shkeeper/modules/rates/manual.py +++ b/shkeeper/modules/rates/manual.py @@ -1,7 +1,7 @@ import json from decimal import Decimal -import requests +from shkeeper import requests from shkeeper.modules.classes.rate_source import RateSource