'HTTP 429 Error and very slow execution using APIs from financial modeling prep
I am trying to create a script in python using APIs from https://site.financialmodelingprep.com/ , but am running into an issue.
The main goal behind this script is to grab all the stocks within the Nasdaq using the function def nasdaq_api_call(url): and then grabbing their 1 year / 1 month price with the two functions def historic_stock_price_api_call_1year(URL): & def historic_stock_price_api_call_1month(url):
I then calculate the percentage change using the current price with function def current_stock_price(url):. Additionally, I loop through raw_data in the Main(): function which lets me grab the stock symbol for each stock in the Nasdaq and use that to find all the prices. I added time.sleep(2) to all the functions with loops since I kept getting an HTTP 429 error.
The issue:
The code seems to work for a few iterations but then shoots back an HTTP error again. I am asking two things:
- is there a way to help alleviate the server from my pulls where I would not get an HTTP 429 error and all the code will execute?
- I am not sure if I have a bottleneck anywhere, but when I run the code it runs super slow regardless of the
time.sleep. Is there any optimization I can do to speed up the execution or anything I can add/remove to help speed it up?
Symbol = ATVI || Company Name = Activision Blizzard || 1 Year Change = -0.21
Symbol = ADBE || Company Name = Adobe || 1 Year Change = -0.07
Symbol = ADP || Company Name = ADP || 1 Year Change = 0.20
Symbol = ABNB || Company Name = Airbnb || 1 Year Change = -0.09
Symbol = ALGN || Company Name = Align || 1 Year Change = -0.16
Symbol = GOOGL || Company Name = Alphabet (Class A) || 1 Year Change = 0.25
Symbol = GOOG || Company Name = Alphabet (Class C) || 1 Year Change = 0.24
Symbol = AMZN || Company Name = Amazon || 1 Year Change = -0.07
Symbol = AMD || Company Name = AMD || 1 Year Change = 0.25
Traceback (most recent call last):
File "C:\Users\leona\PycharmProjects\PythonMain\Training files\testing.py", line 144, in <module>
one_year_ago_price = float(historic_stock_price_api_call_1year(historic_price_url))
File "C:\Users\leona\PycharmProjects\PythonMain\Training files\testing.py", line 29, in historic_stock_price_api_call_1year
response = urlopen(url, context=ssl.create_default_context(cafile=certifi.where()))
File "C:\Python39\lib\urllib\request.py", line 214, in urlopen
return opener.open(url, data, timeout)
File "C:\Python39\lib\urllib\request.py", line 523, in open
response = meth(req, response)
File "C:\Python39\lib\urllib\request.py", line 632, in http_response
response = self.parent.error(
File "C:\Python39\lib\urllib\request.py", line 561, in error
return self._call_chain(*args)
File "C:\Python39\lib\urllib\request.py", line 494, in _call_chain
result = func(*args)
File "C:\Python39\lib\urllib\request.py", line 641, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 429:
Process finished with exit code 1
# Libraries needed for functions
import ssl
import time
from urllib.request import urlopen
import certifi
import json
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
# Dates for one year ago today and one month ago today
one_year_ago_list = (str(datetime.now() - relativedelta(years=1))[0:10]).split('-')
one_month_ago_list = (str(datetime.now() - relativedelta(months=1))[0:10]).split('-')
month_timestamp = datetime(int(one_month_ago_list[0]), int(one_month_ago_list[1]), int(one_month_ago_list[2]))
year_timestamp = datetime(int(one_year_ago_list[0]), int(one_year_ago_list[1]), int(one_year_ago_list[2]))
one_year = str(datetime.now() - relativedelta(years=1))[0:10]
one_month = str(datetime.now() - relativedelta(months=1))[0:10]
api_key = "insert here" # FIX ME insert API key from https://site.financialmodelingprep.com/
# Api call to grab list of NASDAQ stocks
def nasdaq_api_call(url):
response = urlopen(url, context=ssl.create_default_context(cafile=certifi.where()))
data = response.read().decode("utf-8")
return json.loads(data)
# Api call to grab the historic stock price of a stock
def historic_stock_price_api_call_1year(url):
response = urlopen(url, context=ssl.create_default_context(cafile=certifi.where()))
data = response.read().decode("utf-8")
raw_data = json.loads(data)
# the below code skips to the second key in the api response dict which has the actual data
raw_data = raw_data["historical"]
# Looping through the historical data until we can find the EOD price for a year ago
for i in raw_data:
if i["date"] == one_year:
return i["close"]
elif datetime.strftime(year_timestamp, "%A") == 'Sunday':
one_year_sunday = str(datetime.now() - relativedelta(years=1) - timedelta(days=1))[0:10]
if i['date'] == one_year_sunday:
return i['close']
else:
one_year_holiday = str(datetime.now() - relativedelta(years=1) - timedelta(days=2))[0:10]
if i['date'] == one_year_holiday:
return i['close']
elif datetime.strftime(year_timestamp, "%A") == 'Saturday':
one_year_saturday = str(datetime.now() - relativedelta(years=1) + timedelta(days=1))[0:10]
if i['date'] == one_year_saturday:
return i['close']
else:
one_year_holiday = str(datetime.now() - relativedelta(years=1) + timedelta(days=2))[0:10]
if i['date'] == one_year_holiday:
return i['close']
else:
continue
time.sleep(2.0)
# API call to return current stock price
def current_stock_price(url):
response = urlopen(url, context=ssl.create_default_context(cafile=certifi.where()))
data = response.read().decode("utf-8")
raw_date = json.loads(data)
return raw_date[0]["price"]
# API to call to return monthly stock price
def historic_stock_price_api_call_1month(url):
response = urlopen(url, context=ssl.create_default_context(cafile=certifi.where()))
data = response.read().decode("utf-8")
raw_data = json.loads(data)
# the below code skips to the second key in the api response dict which has the actual data
raw_data = raw_data["historical"]
# Looping through the historical data until we can find the EOD price for a month ago
for i in raw_data:
if i["date"] == one_month:
return i["close"]
elif datetime.strftime(month_timestamp, "%A") == 'Sunday':
one_month_sunday = str(datetime.now() - relativedelta(months=1) - timedelta(days=1))[0:10]
if i['date'] == one_month_sunday:
return i['close']
else:
one_month_holiday = str(datetime.now() - relativedelta(months=1) - timedelta(days=2))[0:10]
if i['date'] == one_month_holiday:
return i['close']
elif datetime.strftime(month_timestamp, "%A") == 'Saturday':
one_month_saturday = str(datetime.now() - relativedelta(months=1) + timedelta(days=1))[0:10]
if i['date'] == one_month_saturday:
return i['close']
else:
one_month_holiday = str(datetime.now() - relativedelta(months=1) + timedelta(days=2))[0:10]
if i['date'] == one_month_holiday:
return i['close']
elif datetime.strftime(month_timestamp, "%A") == 'Monday' and i['date'] != one_month:
one_month_holiday = str(datetime.now() - relativedelta(months=1) + timedelta(days=1))[0:10]
if i['date'] == one_month_holiday:
return i['close']
elif datetime.strftime(month_timestamp, "%A") == 'Friday' and i['date'] != one_month:
one_month_holiday = str(datetime.now() - relativedelta(months=1) - timedelta(days=1))[0:10]
if i['date'] == one_month_holiday:
return i['close']
else:
continue
time.sleep(2.0)
def main():
# API URL with my key
nasdaq_url = "https://financialmodelingprep.com/api/v3/nasdaq_constituent?apikey="+api_key
# Using the NASDAQ function and storing the results in the below variable
nasdaq_raw_date = nasdaq_api_call(nasdaq_url)
# Looping through the nasdaq_api_call and adding the symbol for each stock to the URL below so we can use it for the historic price API call
for i in nasdaq_raw_date:
# url that houses all listed stocks in teh index
historic_price_url = "https://financialmodelingprep.com/api/v3/historical-price-full/" + i[
'symbol'] + "?apikey="+api_key
current_price_url = "https://financialmodelingprep.com/api/v3/quote-short/" + i[
'symbol'] + "?apikey="+api_key
one_year_ago_price = float(historic_stock_price_api_call_1year(historic_price_url))
one_month_ago_price = float(historic_stock_price_api_call_1month(historic_price_url))
current_price = float(current_stock_price(current_price_url))
one_year_price_change = float((current_price - one_year_ago_price) / one_year_ago_price)
one_month_price_change = float((current_price - one_month_ago_price) / one_month_ago_price)
print(
"Symbol = {:10s}|| Company Name = {:35s}|| 1 Year Change = {:5.2f} || 1 Month Change = {:5.2f}".format(
i["symbol"], i["name"],
one_year_price_change,
one_month_price_change))
time.sleep(2.0)
if __name__ == "__main__":
main()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
