[Python] Resolving CORS Error in Python Stock Analyzer

Discussão em 'Python' iniciado por Stack, Abril 13, 2025.

  1. Stack

    Stack Membro Participativo

    I've been working on this stock analysis and prediction web application (python backend, JS/React frontend) and I keep getting "Cross-Origin Request Blocked" when I have it try to calculate indicators. Backend code below, any assistance is appreciated.

    from fastapi import FastAPI, HTTPException
    from fastapi.middleware.cors import CORSMiddleware
    from pydantic import BaseModel
    from typing import List, Optional
    import yfinance as yf
    import pandas as pd
    import numpy as np
    from datetime import datetime, timedelta
    from sklearn.model_selection import train_test_split
    from sklearn.linear_model import LinearRegression
    from sklearn.ensemble import RandomForestRegressor
    from sklearn.metrics import mean_squared_error, r2_score
    from ta.trend import SMAIndicator, MACD
    from ta.momentum import RSIIndicator
    from ta.volatility import BollingerBands

    app = FastAPI(title="Stock Analysis and Prediction Platform")

    # Configure CORS
    app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
    expose_headers=["*"]
    )

    class StockRequest(BaseModel):
    symbol: str
    period: str = "1y"

    class PredictionRequest(BaseModel):
    symbol: str
    features: List[str]
    target: str
    days_ahead: int = 5
    model_type: str

    @app.get("/")
    async def root():
    return {"message": "Welcome to Stock Analysis and Prediction API"}

    @app.post("/stock/historical")
    async def get_historical_data(request: StockRequest):
    try:
    # Get historical data
    stock = yf.Ticker(request.symbol)
    df = stock.history(period=request.period)

    if df.empty:
    raise HTTPException(status_code=404, detail=f"No data found for symbol {request.symbol}")

    # Convert DataFrame to list of dictionaries
    df.index = df.index.strftime('%Y-%m-%d')
    return df.reset_index().to_dict('records')

    except Exception as e:
    raise HTTPException(status_code=500, detail=str(e))

    @app.post("/stock/indicators")
    async def calculate_indicators(request: StockRequest):
    try:
    # Get historical data
    stock = yf.Ticker(request.symbol)
    df = stock.history(period=request.period)

    if df.empty:
    raise HTTPException(status_code=404, detail=f"No data found for symbol {request.symbol}")

    # Calculate indicators
    # RSI
    rsi = RSIIndicator(close=df['Close'], window=14)
    df['RSI'] = rsi.rsi()

    # MACD
    macd = MACD(close=df['Close'])
    df['MACD'] = macd.macd()

    # Bollinger Bands
    bollinger = BollingerBands(close=df['Close'])
    df['BB_high'] = bollinger.bollinger_hband()
    df['BB_low'] = bollinger.bollinger_lband()

    # Convert DataFrame to list of dictionaries
    df.index = df.index.strftime('%Y-%m-%d')
    return df.reset_index().to_dict('records')

    except Exception as e:
    raise HTTPException(status_code=500, detail=str(e))

    @app.post("/stock/predict")
    async def predict_stock(request: PredictionRequest):
    try:
    # Get historical data
    stock = yf.Ticker(request.symbol)
    df = stock.history(period="2y")

    if df.empty:
    raise HTTPException(status_code=404, detail=f"No data found for symbol {request.symbol}")

    # Prepare features
    for feature in request.features:
    if feature not in df.columns:
    raise HTTPException(status_code=400, detail=f"Feature {feature} not found")

    X = df[request.features].values
    y = df[request.target].values

    # Split data
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

    # Train model
    if request.model_type == "linear":
    model = LinearRegression()
    elif request.model_type == "random_forest":
    model = RandomForestRegressor(n_estimators=100, random_state=42)
    else:
    raise HTTPException(status_code=400, detail="Unsupported model type")

    model.fit(X_train, y_train)
    y_pred = model.predict(X_test)

    # Calculate metrics
    mse = mean_squared_error(y_test, y_pred)
    r2 = r2_score(y_test, y_pred)

    # Predict next n days
    last_data = df[request.features].values[-1:]
    future_pred = model.predict(last_data)

    return {
    "current_price": float(df['Close'].iloc[-1]),
    "predicted_price": float(future_pred[0]),
    "mse": float(mse),
    "r2": float(r2),
    "days_ahead": request.days_ahead
    }

    except Exception as e:
    raise HTTPException(status_code=500, detail=str(e))

    if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8000)


    I expected it to calculate technical indicators (RSI, Bollinger bands, etc.), but I get "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8000/stock/indicators. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 500."

    Continue reading...

Compartilhe esta Página