GoldStock / main.py
fishercui's picture
Upload main.py
b10cd7f verified
Raw
History Blame Contribute Delete
3.15 kB
import os
import pypinyin
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse
import akshare as ak
import pandas as pd
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
_stock_cache = None
def load_stock_cache():
global _stock_cache
if _stock_cache is None:
try:
df = ak.stock_info_a_code_name()
_stock_cache = []
for _, row in df.iterrows():
code = str(row['code'])
name = str(row['name'])
py = "".join(pypinyin.lazy_pinyin(name, style=pypinyin.Style.FIRST_LETTER)).lower()
_stock_cache.append({
"code": code,
"name": name,
"pinyin": py
})
except Exception as e:
print("Error loading stock cache:", e)
def get_stock_name(symbol: str) -> str:
load_stock_cache()
if _stock_cache is not None:
symbol = str(symbol)
for item in _stock_cache:
if item["code"] == symbol:
return item["name"]
return ""
def get_prefix_symbol(symbol: str) -> str:
if len(symbol) == 8:
return symbol
if symbol.startswith('6'):
return 'sh' + symbol
return 'sz' + symbol
def format_stock_data(df: pd.DataFrame) -> list:
formatted_data = []
if df is None or df.empty:
return formatted_data
for _, row in df.iterrows():
date_val = row.get('date', '')
if hasattr(date_val, 'strftime'):
date_str = date_val.strftime('%Y-%m-%d')
else:
date_str = str(date_val).split(' ')[0]
formatted_data.append({
'date': date_str,
'open': float(row['open']),
'close': float(row['close']),
'low': float(row['low']),
'high': float(row['high'])
})
return formatted_data
@app.get("/")
def serve_index():
# 根路由直接返回 index.html
html_path = os.path.join(os.path.dirname(__file__), "index.html")
return FileResponse(html_path)
@app.get("/api/health")
def health_check():
return {"status": "ok"}
@app.get("/api/stock")
def get_stock(symbol: str):
full_symbol = get_prefix_symbol(symbol)
stock_name = get_stock_name(symbol)
try:
df = ak.stock_zh_a_daily(symbol=full_symbol)
data = format_stock_data(df)
return {"name": stock_name, "data": data}
except Exception as e:
raise HTTPException(status_code=500, detail=f"网络请求失败。原因: {str(e)}")
@app.get("/api/search")
def search_stock(q: str):
load_stock_cache()
if not _stock_cache:
return []
q_lower = q.lower()
results = []
for item in _stock_cache:
if q_lower in item["code"] or q_lower in item["name"].lower() or q_lower in item["pinyin"]:
results.append(item)
if len(results) >= 10:
break
return results