mirror of
https://github.com/Redume/Shirino.git
synced 2024-12-25 01:33:45 +03:00
CoinAPI token rotation
This commit is contained in:
parent
2573253e2b
commit
b98c16f642
3 changed files with 45 additions and 10 deletions
10
.env_sample
10
.env_sample
|
@ -1,5 +1,5 @@
|
||||||
DEBUG=false # debug logging
|
DEBUG=false # debug logging
|
||||||
TIMEOUT=2 # http requests timeout
|
TIMEOUT=2 # http requests timeout
|
||||||
NDIGITS=3 # digits after floating point or after zeroes
|
NDIGITS=3 # digits after floating point or after zeroes
|
||||||
COINAPI_KEY= # coinapi key
|
COINAPI_KEYS=["key"] # coinapi keys list
|
||||||
TELEGRAM_TOKEN= # telegram bot token
|
TELEGRAM_TOKEN= # telegram bot token
|
||||||
|
|
12
README.md
12
README.md
|
@ -10,7 +10,7 @@ https://t.me/Shirino_bot
|
||||||
Вставьте в файл `.env` в формате:
|
Вставьте в файл `.env` в формате:
|
||||||
|
|
||||||
```
|
```
|
||||||
COINAPI_KEY=Токен от апи CoinAPI
|
COINAPI_KEYS=["Токен от CoinAPI"]
|
||||||
TELEGRAM_TOKEN=Токен Telegram-бота
|
TELEGRAM_TOKEN=Токен Telegram-бота
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -24,3 +24,13 @@ TIMEOUT=таймаут для библиотеки requests, в секундах
|
||||||
Ставьте pylint и mypy для статической проверки кода.
|
Ставьте pylint и mypy для статической проверки кода.
|
||||||
Конфиги уже есть в репозитории.
|
Конфиги уже есть в репозитории.
|
||||||
После проверок можете открывать PR.
|
После проверок можете открывать PR.
|
||||||
|
|
||||||
|
## Почему энв для CoinAPI -- список?
|
||||||
|
Можно получить несколько ключей на разные почтовые ящики
|
||||||
|
и все ключи вписать в список:
|
||||||
|
```
|
||||||
|
COINAPI_KEYS=["первый", "второй", "и так далее"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Если вдруг один из них будет заблокирован по рейтлимиту,
|
||||||
|
бот автоматически переключиться на следующий (token rotation).
|
||||||
|
|
33
main.py
33
main.py
|
@ -31,7 +31,7 @@ class Settings(BaseSettings):
|
||||||
debug: bool
|
debug: bool
|
||||||
timeout: int = 2
|
timeout: int = 2
|
||||||
ndigits: int = 3
|
ndigits: int = 3
|
||||||
coinapi_key: str
|
coinapi_keys: List[str]
|
||||||
telegram_token: str
|
telegram_token: str
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
|
@ -57,6 +57,8 @@ if settings.debug:
|
||||||
# ---
|
# ---
|
||||||
|
|
||||||
|
|
||||||
|
coinapi_len = len(settings.coinapi_keys)
|
||||||
|
coinapi_active = [0] # API key index
|
||||||
bot = Bot(token=settings.telegram_token)
|
bot = Bot(token=settings.telegram_token)
|
||||||
dp = Dispatcher(bot)
|
dp = Dispatcher(bot)
|
||||||
|
|
||||||
|
@ -143,8 +145,15 @@ class CurrencyConverter:
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def coinapi(self) -> None:
|
def coinapi(self, depth: int = coinapi_len) -> None:
|
||||||
"""Get data from CoinAPI (for cryptocurrencies)"""
|
"""Get data from CoinAPI (for cryptocurrencies)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
depth (int, optional): Counter protecting from infinite recursion
|
||||||
|
"""
|
||||||
|
|
||||||
|
if depth <= 0:
|
||||||
|
raise RecursionError('Рейтлимит на всех токенах')
|
||||||
|
|
||||||
resp = requests.get(
|
resp = requests.get(
|
||||||
(
|
(
|
||||||
|
@ -152,11 +161,16 @@ class CurrencyConverter:
|
||||||
f'/{self.conv_currency}'
|
f'/{self.conv_currency}'
|
||||||
),
|
),
|
||||||
headers={
|
headers={
|
||||||
'X-CoinAPI-Key': settings.coinapi_key,
|
'X-CoinAPI-Key': settings.coinapi_keys[coinapi_active[0]],
|
||||||
},
|
},
|
||||||
timeout=settings.timeout,
|
timeout=settings.timeout,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if resp.status_code == 429:
|
||||||
|
log.warning('CoinAPI ratelimited, rotating token')
|
||||||
|
rotate_token(settings.coinapi_keys, coinapi_active)
|
||||||
|
self.coinapi(depth - 1)
|
||||||
|
|
||||||
data: Dict[str, Any] = resp.json()
|
data: Dict[str, Any] = resp.json()
|
||||||
rate = data.get('rate')
|
rate = data.get('rate')
|
||||||
if rate is None:
|
if rate is None:
|
||||||
|
@ -164,6 +178,17 @@ class CurrencyConverter:
|
||||||
self.conv_amount = float(rate * self.amount)
|
self.conv_amount = float(rate * self.amount)
|
||||||
|
|
||||||
|
|
||||||
|
def rotate_token(lst: List[str], active: List[int]) -> None:
|
||||||
|
"""Rotates API key to prevent ratelimits
|
||||||
|
|
||||||
|
Args:
|
||||||
|
lst (List[str]): Keys list
|
||||||
|
active (List[str]): Mutable object with current key index
|
||||||
|
"""
|
||||||
|
|
||||||
|
active[0] = (active[0] + 1) % len(lst)
|
||||||
|
|
||||||
|
|
||||||
@dp.inline_handler()
|
@dp.inline_handler()
|
||||||
async def currency(inline_query: InlineQuery) -> None:
|
async def currency(inline_query: InlineQuery) -> None:
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue