为异步类方法应用条件速率限制装饰器

问题描述 投票:0回答:1

我正在使用

ccxt
库从各种加密货币交易所下载 OHLC 数据。这是使用 REST 请求在内部完成的。这些交易所有不同的请求速率限制,因此我必须对我的方法应用速率限制。为了限制速率,我使用库
limiter
。这是我现在所拥有的:

import ccxt.async_support as ccxt
from limiter import Limiter

limiter_binance = Limiter(rate=19, capacity=19, consume=1)
limiter_coinbase = Limiter(rate=3, capacity=3, consume=1)

class CCXTFeed:

    def __init__(self, exchange_name):
        self._exchange = ccxt.binance()
        self._exchange_name = exchange_name

    @limiter_binance 
    async def __FetchSymbolOHLCChunk(self, symbol, timeframe, startTime, limit=1000):
        data = await self._exchange.fetch_ohlcv(symbol, timeframe, since=startTime, limit=limit)
        return data

我现在想要的是,如果类是用

limiter_coinbase
实例化的,则以某种方式应用
exchange_name="coinbase"
。我希望能够根据我当前正在使用的交易所选择应用的速率限制器装饰器。交换名称是在运行时定义的。

python python-asyncio python-decorators rate-limiting ccxt
1个回答
0
投票

您可以做的是创建一个自定义装饰器,然后将您重定向到正确的装饰器, 例如:


import ccxt.async_support as ccxt
from limiter import Limiter

limiter_binance = Limiter(rate=19, capacity=19, consume=1)
limiter_coinbase = Limiter(rate=3, capacity=3, consume=1)

def dispatch_limiter(func):
    async def mod_func(self, *args, **kwargs):
        if self._exchange_name == "coinbase":
            return await (limiter_coinbase(func)(self, *args, **kwargs)) # basically, because limiter_coinbase is intended to be a decorator, we first instantiate it with the function and then we call it as if it was the original function.
        elif self._exchange_name == "binance":
            return await (limiter_binance(func)(self, *args, **kwargs))
   return mod_func

class CCXTFeed:

    def __init__(self, exchange_name):
        self._exchange = ccxt.binance()
        self._exchange_name = exchange_name

    @dispatch_limiter
    async def __FetchSymbolOHLCChunk(self, symbol, timeframe, startTime, limit=1000):
        data = await self._exchange.fetch_ohlcv(symbol, timeframe, since=startTime, limit=limit)
        return data
© www.soinside.com 2019 - 2024. All rights reserved.