Add caching CoinGecko price api endpoint

/api/prices returns all supported CoinGecko vs currencies;
/api/price/btc (or any other base) returns the price in the given base
(if supported by CoinGecko).
This commit is contained in:
Jason Rhinelander 2021-01-04 13:40:47 -04:00
parent c69390ef04
commit 443b2d21cf

View file

@ -7,6 +7,8 @@ import json
import sys import sys
import statistics import statistics
import string import string
import requests
import time
from base64 import b32encode, b16decode from base64 import b32encode, b16decode
from werkzeug.routing import BaseConverter from werkzeug.routing import BaseConverter
from pygments import highlight from pygments import highlight
@ -750,3 +752,43 @@ def api_block(blkid=None, height=None):
"status": block['status'], "status": block['status'],
"data": data, "data": data,
}) })
ticker_vs, ticker_vs_expires = [], None
ticker_cache, ticker_cache_expires = {}, None
@app.route('/api/prices')
@app.route('/api/price/<fiat>')
def api_price(fiat=None):
global ticker_cache, ticker_cache_expires, ticker_vs, ticker_vs_expires
# TODO: will need to change to 'oxen' when the ticker changes:
ticker = 'loki-network'
if not ticker_cache or not ticker_cache_expires or ticker_cache_expires < time.time():
if not ticker_vs_expires or ticker_vs_expires < time.time():
try:
x = requests.get("https://api.coingecko.com/api/v3/simple/supported_vs_currencies").json()
if x:
ticker_vs = x
ticker_vs_expires = time.time() + 300
except RuntimeError as e:
print("Failed to retrieve vs currencies: {}".format(e), file=sys.stderr)
# ignore failure because we might have an old value that is still usable
if not ticker_vs:
raise RuntimeError("Failed to retrieve CoinGecko currency list")
try:
x = requests.get("https://api.coingecko.com/api/v3/simple/price?ids={}&vs_currencies={}".format(
ticker, ",".join(ticker_vs))).json()
except RuntimeError as e:
print("Failed to retrieve prices: {}".format(e), file=sys.stderr)
if not x or ticker not in x or not x[ticker]:
raise RuntimeError("Failed to retrieve prices from CoinGecko")
ticker_cache = x[ticker]
ticker_cache_expires = time.time() + 60
if fiat is None:
return flask.jsonify(ticker_cache)
else:
fiat = fiat.lower()
return flask.jsonify({ fiat: ticker_cache[fiat] } if fiat in ticker_cache else {})