main.py
from fastapi import FastAPI
import yfinance as yf
import pandas as pd
from typing import Optional
from fastapi.middleware.cors import CORSMiddleware
from datetime import datetime, timedelta
import logging
# Create a cache for temporary in-memory storage
stock_data_cache = {}
CACHE_EXPIRY_TIME = 10 # Cache expiry time in minutes
app = FastAPI()
#Disable WebSocket logs to debug connectivity issues
logging.getLogger("uvicorn.error").setLevel(logging.ERROR)
logging.getLogger("uvicorn.access").setLevel(logging.ERROR)
# Allow requests from React frontend
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"], # Allow requests from frontend
allow_credentials=True,
allow_methods=["*"], # Allow all HTTP methods
allow_headers=["*"], # Allow all headers
)
@app.get("/stocks/{symbol}")
def get_stock_data(symbol: str, start: str = "2023-01-01", end: str = "2024-01-01"):
"""Fetch historical stock data from Yahoo Finance with temporary in-memory cache"""
# Check if the symbol is provided (non-empty)
if not symbol:
return {"error": "Symbol is required. Please provide a valid stock symbol."}
# Check if the data is already cached and still valid
if symbol in stock_data_cache:
cached_data, last_fetched = stock_data_cache[symbol]
# If cached data is older than the expiry time, invalidate it
if datetime.now() - last_fetched < timedelta(minutes=CACHE_EXPIRY_TIME):
print("Returning cached data.")
return {"data": cached_data}
try:
print(f"Fetching data for {symbol} from {start} to {end}...")
data = yf.download(symbol, start=start, end=end)
if data.empty:
return {"error": f"No data found for symbol '{symbol}'. Please check the symbol and try again."}
# Convert DataFrame to JSON
data_json = data.to_json(orient="split")
# Cache the data with the current time
stock_data_cache[symbol] = (data_json, datetime.now())
return {"data": data_json}
except Exception as e:
# Catch any errors during data fetching or processing
print(f"Error: {e}")
return {"error": f"An error occurred while processing the request: {str(e)}"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)
< /code>
app.js
import React, { useState } from "react";
const API_BASE_URL = "http://127.0.0.1:8000"; // Backend URL
function App() {
const [symbol, setSymbol] = useState(""); // Stores user input for stock symbol
const [data, setData] = useState(null); // Stores fetched stock data
const [error, setError] = useState(""); // Stores error messages
const fetchStock = async () => {
setError(""); // Clear previous errors
setData(null); // Reset data before new request
if (!symbol) {
setError("Please enter a stock symbol!"); // Prevent empty input
return;
}
try {
const requestUrl = `${API_BASE_URL}/stocks/${symbol}`;
console.log(`Fetching data from: ${requestUrl}`); // Debugging log
const response = await fetch(requestUrl);
console.log("Response Status:", response.status);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const result = await response.json();
console.log("API Response:", result);
if (result.error) {
setError(result.error); // Handle API error response
} else {
setData(result.data); // Store API response
}
} catch (error) {
console.error("Fetch Error:", error);
setError("Failed to fetch stock data"); // Display generic error
}
};
return (
Stock Market Data
setSymbol(e.target.value.toUpperCase())}
className="border p-2 w-full"
/>
Get Stock Data
{error &&
{error}
}
{data && (
{JSON.stringify(data, null, 2)}
)}
);
}
export default App;
< /code>
- Я использовал Axios раньше, но он тоже не работал < /li>
Я добавил промежуточное программное обеспечение Cors и в Corsmiddleware, но но все еще не знаю, в чем проблема
Подробнее здесь: https://stackoverflow.com/questions/794 ... om-backend