Download main.py from XMFML6/GoldStock: direct link, hf CLI and curl.
- Browser
- Download file 3.15 kB
-
https://huggingface.co/spaces/XMFML6/GoldStock/resolve/main/main.py
- Command line
-
hf download hf://spaces/XMFML6/GoldStock/main.py
-
curl -L -o main.py https://huggingface.co/spaces/XMFML6/GoldStock/resolve/main/main.py
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 | |
| def serve_index(): | |
| # 根路由直接返回 index.html | |
| html_path = os.path.join(os.path.dirname(__file__), "index.html") | |
| return FileResponse(html_path) | |
| def health_check(): | |
| return {"status": "ok"} | |
| 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)}") | |
| 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 | |