Hi, I am having issues with a flask web api I deployed on Vercel. The deployment and upload works fine.
So if I go to the API url works and shows the JSON data (see below screenshot):
If I include the link into a JS code to show the data in an HTML file doesnt work:
In the FLask Python code I include the allow CORS, infact when I tested the flask api locally works fine and shows the data correctly. The python code I deployed on vercel is the following:
from flask import Flask, jsonify
from flask_cors import CORS
import yfinance as yf
from datetime import date, datetime, timedelta
import pandas as pd
import numpy as np
app = Flask(__name__)
CORS(app)
@app.route('/')
def home():
return "Marcello Personal Portfolio Dashboard API"
@app.route('/stock-data')
def get_stock_data():
tickers = ['VHYL.L', 'MSFT', 'SGLN.L', 'IMEU.L', 'BABA', 'SAAA.L', 'XYZ']
# weights of the stocks
weights = np.array([0.2164, 0.1797, 0.1536, 0.1304, 0.1289, 0.1275, 0.0635])
today = date.today()
data = yf.download(tickers, start='2021-01-19', end="2025-02-21", interval="1mo", auto_adjust = False)['Adj Close']
# normalize the price
normalized_data = data / data.iloc[0]
# portfolio performance
portfolio_performance = (normalized_data * weights).sum(axis=1) # weighted sum of all shares in the portfolio
# Calculate the percentage change
pct_change = (portfolio_performance.pct_change().fillna(0) * 100).tolist()
# Prepare JSON response
response_data = {
"labels": normalized_data.index.strftime("%Y-%m-%d").tolist(),
# add the percentage change to the response
"pct_change": pct_change, # percentage change
# add the weights to the response to show the weights of the stocks showing also the ticker of the stock
"portfolio_weights": {
"tickers": tickers,
"weights": weights.tolist()
}
}
return jsonify(response_data)
PORTFOLIO = ['VHYL.L', 'MSFT', 'SGLN.L', 'IMEU.L', 'BABA', 'SAAA.L', 'XYZ']
def calculate_performance(ticker_data, periods):
"""Calculate performance for different time periods"""
results = {}
latest_price = ticker_data.iloc[-1]
for period_name, days in periods.items():
if days > len(ticker_data):
results[period_name] = None
continue
start_price = ticker_data.iloc[-days]
performance = ((latest_price - start_price) / start_price) * 100
results[period_name] = round(performance, 2)
return results
@app.route('/portfolio-performance')
def portfolio_performance():
today = datetime.now()
# Define time periods in trading days (approximations)
periods = {
'1_month': 21,
'ytd': max(1, (today - datetime(today.year, 1, 1)).days), # Year-to-date (from Jan 1st) excluding weekends
'1_year': 252,
'3_year': 756,
'5_year': 1260
}
# Calculate start date for data retrieval (add some buffer)
start_date = (today - timedelta(days=1900)).strftime('%Y-%m-%d')
end_date = today.strftime('%Y-%m-%d')
portfolio_data = []
for ticker in PORTFOLIO:
try:
# Get historical data
stock_data = yf.Ticker(ticker)
hist = stock_data.history(start=start_date, end=end_date)
# Skip if no data
if hist.empty:
continue
# Get adjusted close prices
adj_close = hist['Close']
# Calculate performance for different periods
performance = calculate_performance(adj_close, periods)
# Get current price
current_price = round(float(adj_close.iloc[-1]), 2)
# Get company name
info = stock_data.info
company_name = info.get('shortName', ticker)
portfolio_data.append({
'ticker': ticker,
'name': company_name,
'current_price': current_price,
'performance': performance
})
except Exception as e:
print(f"Error processing {ticker}: {e}")
return jsonify(portfolio_data)
if __name__ == '__main__':
#app.run(debug=True) # run the app in debug mode locally
app.run() # run the app in production mode
Hope someone can help thanks. Marcello