import json from pycoingecko import CoinGeckoAPI from rediscluster import RedisCluster # from redis import Redis import ast import requests import traceback #const DEFAULT_PRICE = 0.00000000000000001 #redis keys TOKENPRICE = 'TOKENPRICE_TO_FETCH' def get_swap_price(tokens): ret_d = {} for t in tokens: segs = t.split('_') chain = segs[0] contract = segs[1] if chain.strip().upper() == 'bsc': price = get_pancakeswap_price(contract) if price is not None: ret_d[t] = price return ret_d def get_pancakeswap_price(contract): url = f'https://api.pancakeswap.info/api/v2/tokens/{contract}' try: ret = requests.get(url) price = float(ret.json()['data']['price']) print(price) return price except: traceback.print_exc() return None def get_coingecko_price(tokens): exceptions = set() ret_d = {} try: cg = CoinGeckoAPI() coin_prices = cg.get_price(ids=list(tokens), vs_currencies='usd') print(coin_prices) for k, v in coin_prices.items(): if v.get('usd') is None: exceptions.add(k) continue price = v['usd'] ret_d[k] = price except: traceback.print_exc() print('get_coingecko_price exception tokens', exceptions) return ret_d def get_tokens(): tokens = r.smembers(TOKENPRICE) tokens = [ast.literal_eval(t) for t in tokens] realtime_price_token = set() fixed_or_swap_price_token = set() for t in tokens: if t.get('fixed_price') is None: realtime_price_token.add(t.get('coingecko_id')) else: fixed_or_swap_price_token.add(f"{t.get('chain')}_{t.get('contract')}") realtime_price = get_coingecko_price(realtime_price_token) #{'coingecko_id':price} swap_price_token = get_swap_price(fixed_or_swap_price_token) #{'chain_contract': price} return tokens, realtime_price, swap_price_token def merge_price(tokens, realtime_price, swap_price_token): ret_d = {} exceptions = set() for t in tokens: chain = t.get('chain') contract = t.get('contract') coingecko_id = t.get('coingecko_id') fixed_price = t.get('fixed_price') now_price = realtime_price.get(coingecko_id) if now_price is None: now_price = swap_price_token.get(f'{chain}_{contract}') if now_price is None: now_price = fixed_price if now_price is None: exceptions.add(t) else: l = ret_d.get(chain, []) l.append({'contract': contract_address, 'usdPrice': price}) ret_d[chain] = l print('merge_price exceptions', exceptions) return ret_d def save_price(prices): for chain, token_dict in prices.items(): r.set(f'{TOKENPRICE}{chain.upper()}', json.dumps({'tokenPrice':token_dict})) def _recover_history_data(): #TODO #1. 读取历史数据,修改数据格式,并重新导入 #2. 对比历史token记录表,筛选是否有丢失数据的情况 #3. 修改api server接口,以新数据结构存储 pass if __name__ == '__main__': tokens, realtime_price, swap_price_token = get_tokens() prices = merge_price(tokens, realtime_price, swap_price_token) save_price(prices)