diff --git a/eodhd/APIs/BaseAPI.py b/eodhd/APIs/BaseAPI.py index b4e919d..2bf521e 100644 --- a/eodhd/APIs/BaseAPI.py +++ b/eodhd/APIs/BaseAPI.py @@ -6,6 +6,8 @@ from requests.exceptions import HTTPError as requests_HTTPError from rich.console import Console +from eodhd.rates import Rate + class BaseAPI: def __init__(self) -> None: @@ -21,6 +23,7 @@ def _rest_get_method(self, api_key: str, endpoint: str = "", uri: str = "", quer try: resp = requests_get(f"{self._api_url}/{endpoint}/{uri}?api_token={api_key}&fmt=json{querystring}") + Rate().update_from_headers(resp.headers) if resp.status_code != 200: try: diff --git a/eodhd/apiclient.py b/eodhd/apiclient.py index 7f1205b..dd5b4a2 100644 --- a/eodhd/apiclient.py +++ b/eodhd/apiclient.py @@ -38,6 +38,7 @@ from eodhd.APIs import EodHistoricalStockMarketDataAPI from eodhd.APIs import StockMarketTickDataAPI from eodhd.APIs import HistoricalMarketCapitalization +from eodhd.rates import Rate # minimal traceback sys.tracebacklimit = 1 @@ -105,6 +106,7 @@ def __init__(self, api_key: str) -> None: self._api_key = api_key self._api_url = "https://eodhd.com/api" + self.rate = Rate() self.console = Console() @@ -116,6 +118,7 @@ def _rest_get(self, endpoint: str = "", uri: str = "", querystring: str = "") -> try: resp = requests_get(f"{self._api_url}/{endpoint}/{uri}?api_token={self._api_key}&fmt=json{querystring}") + self.rate.update_from_headers(resp.headers) if resp.status_code != 200: try: diff --git a/eodhd/rates.py b/eodhd/rates.py new file mode 100644 index 0000000..ad00204 --- /dev/null +++ b/eodhd/rates.py @@ -0,0 +1,38 @@ +"""rates.py""" + +from typing import Dict, Optional + +LIMIT_HEADER = "X-RateLimit-Limit" +REMAINING_HEADER = "X-RateLimit-Remaining" + + +class Rate(object): + def __new__(cls): + if not hasattr(cls, 'instance'): + cls.instance = super(Rate, cls).__new__(cls) + return cls.instance + + def __init__(self): + self._limit: Optional[int] = None + self._remaining: Optional[int] = None + + def __str__(self): + return f"{self.remaining} / {self.limit} remaining" + + @property + def limit(self) -> Optional[int]: + return self._limit + + @property + def remaining(self) -> Optional[int]: + return self._remaining + + def update_from_headers(self, headers: Dict[str, str]) -> None: + if not all(key in headers for key in [LIMIT_HEADER, REMAINING_HEADER]): + return + + limit = int(headers.get(LIMIT_HEADER)) + remaining = int(headers.get(REMAINING_HEADER)) + + self._limit = limit + self._remaining = remaining diff --git a/example_api.py b/example_api.py index 11ea0b8..ec61964 100644 --- a/example_api.py +++ b/example_api.py @@ -11,11 +11,13 @@ def main() -> None: resp = api.get_exchanges() print(resp) + # print(api.rate) # print(resp.dtypes) # print(resp.describe()) resp = api.get_exchange_symbols("US") print(resp) + # print(api.rate) # print(resp.dtypes) # print(resp.describe()) @@ -23,6 +25,7 @@ def main() -> None: # resp = api.get_historical_data("BTC-USD.CC", "1m", "2021-11-27 23:56:00") # resp = api.get_historical_data("BTC-USD.CC", "1m", "2021-11-27 23:56:00", "2021-11-27 23:59:00") print(resp) + # print(api.rate) # print(resp.dtypes) # print(resp.describe()) @@ -30,6 +33,7 @@ def main() -> None: # resp = api.get_historical_data("BTC-USD.CC", "5m", "2021-11-27 23:55:00") # resp = api.get_historical_data("BTC-USD.CC", "5m", "2021-11-27 23:55:00", "2021-11-28 02:00:00") print(resp) + # print(api.rate) # print(resp.dtypes) # print(resp.describe()) @@ -37,6 +41,7 @@ def main() -> None: # resp = api.get_historical_data("BTC-USD.CC", "1h", "2021-11-27 23:00:00") # resp = api.get_historical_data("BTC-USD.CC", "1h", "2021-11-27 23:00:00", "2021-11-28 23:59:00") print(resp) + # print(api.rate) # print(resp.dtypes) # print(resp.describe()) @@ -44,6 +49,7 @@ def main() -> None: # resp = api.get_historical_data("BTC-USD.CC", "d", "2021-11-24") # resp = api.get_historical_data("BTC-USD.CC", "d", "2021-11-24", "2021-11-27") print(resp) + # print(api.rate) # print(resp.dtypes) # print(resp.describe()) @@ -51,93 +57,119 @@ def main() -> None: # resp = api.get_historical_data("BTC-USD.CC", "d", "2021-11-24") # resp = api.get_historical_data("BTC-USD.CC", "d", "2021-11-24", "2021-11-27") print(resp) + # print(api.rate) # print(resp.dtypes) # print(resp.describe()) resp = api.get_details_trading_hours_stock_market_holidays(code = 'US', from_date = '2022-12-01', to_date = '2023-01-03') # resp = api.get_details_trading_hours_stock_market_holidays(code = 'US') print(resp) + # print(api.rate) resp = api.get_bonds_fundamentals_data(isin = 'DE000CB83CF0') print(resp) + # print(api.rate) resp = api.get_eod_splits_dividends_data(country = 'US', type = 'splits', date = '2010-09-21', symbols = 'MSFT', filter = 'extended') # resp = api.get_eod_splits_dividends_data(country = 'US', type = 'dividends', date = '2010-09-21', symbols = 'MSFT', filter = 'extended') print(resp) + # print(api.rate) resp = api.get_earning_trends_data(symbols = 'AAPL.US') # resp = api.get_earning_trends_data(symbols = 'AAPL.US, MS') print(resp) + # print(api.rate) resp = api.get_economic_events_data(date_from = '2020-01-05', date_to = '2020-02-10', country = 'AU', comparison = 'mom', offset = 50, limit = 50) # resp = api.get_economic_events_data(date_from = '2020-01-05', date_to = '2020-02-10', country = 'AU', comparison = 'qoq', offset = 50, limit = 50) # resp = api.get_economic_events_data(date_from = '2020-01-05', date_to = '2020-02-10', country = 'AU', comparison = 'yoy', offset = 50, limit = 50) print(resp) + # print(api.rate) resp = api.financial_news(s = 'AAPL.US', t = None, from_date = '2020-01-05', to_date = '2020-02-10', limit = 100, offset = 200) # resp = api.financial_news(s = None, t = 'balance sheet', from_date = '2020-01-05', to_date = '2020-02-10', limit = 100, offset = 200) print(resp) + # print(api.rate) resp = api.get_fundamentals_data(ticker = 'AAPL') print(resp) + # print(api.rate) resp = api.get_historical_dividends_data(date_from = '2020-01-05', date_to = '2020-02-10', ticker = 'AAPL.US') print(resp) + # print(api.rate) resp = api.get_historical_splits_data(date_from = '2020-01-05', date_to = '2020-02-10', ticker = 'AAPL.US') print(resp) + # print(api.rate) resp = api.get_insider_transactions_data(date_from = '2020-01-05', date_to = '2020-02-10', code = 'AAPL', limit = 200) #resp = api.get_insider_transactions_data(date_from = '2020-01-05', date_to = '2020-02-10', code = 'AAPL.US', limit = 200) print(resp) + # print(api.rate) resp = api.get_live_stock_prices(date_from = '2020-01-05', date_to = '2020-02-10', ticker = 'AAPL.US') print(resp) + # print(api.rate) resp = api.get_macro_indicators_data(country = 'US', indicator = 'population_total') # resp = api.get_macro_indicators_data(country = 'US', indicator = 'consumer_price_index') print(resp) + # print(api.rate) resp = api.stock_market_screener(sort = 'market_capitalization.desc', filters = '[["market_capitalization",">",1000], ["name","match","apple"], ["code","=","AAPL"],["exchange","=","us"],["sector","=","Technology"]]', limit = 10, signals = 'bookvalue_neg', offset = 0) print(resp) + # print(api.rate) resp = api.get_upcoming_earnings_data(from_date = '2020-01-05', to_date = '2020-02-10', symbols = 'MSFT') print(resp) + # print(api.rate) resp = api.get_upcoming_IPOs_data(from_date = '2020-01-05', to_date = '2020-02-10') print(resp) + # print(api.rate) resp = api.get_upcoming_splits_data(from_date = '2020-01-05', to_date = '2020-02-10') print(resp) + # print(api.rate) resp = api.get_technical_indicator_data(ticker = 'AAPL.US', function = 'avgvolccy', period = 100, date_from = '2020-01-05', date_to = '2020-02-10', order = 'a', splitadjusted_only = '0') print(resp) + # print(api.rate) resp = api.get_list_of_exchanges() print(resp) + # print(api.rate) resp = api.get_list_of_tickers(delisted = 1, code = 'US') print(resp) + # print(api.rate) resp = api.symbol_change_history(from_date = '2020-01-05', to_date = '2020-02-10') print(resp) + # print(api.rate) resp = api.get_intraday_historical_data(symbol = 'AAPL.MX', from_unix_time = '1627896900', to_unix_time = '1630575300', interval='1h') print(resp) + # print(api.rate) resp = api.get_eod_historical_stock_market_data(symbol = 'AAPL.MX', period='d', from_date = '2023-01-01', to_date = '2023-01-15', order='a') print(resp) + # print(api.rate) resp = api.get_stock_market_tick_data(from_timestamp = '1627896900', to_timestamp = '1630575300', symbol = 'AAPL', limit = 1) print(resp) + # print(api.rate) resp = api.get_sentiment(s = 'btc-usd.cc', from_date = '2023-01-01', to_date = '2023-01-15') print(resp) + # print(api.rate) resp = api.get_historical_market_capitalization_data(ticker = 'AAPL.US', from_date = '2023-01-01', to_date = '2023-01-15') print(resp) + # print(api.rate) if __name__ == "__main__":