Spaces:
Sleeping
Sleeping
File size: 4,236 Bytes
7dfd114 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | """yfinance fallback ์บ์ ๋น๋.
๋ก์ปฌ(yfinance ๊ฐ ์ ์ ๋์ํ๋ ํ๊ฒฝ)์์ ์คํํด ๊ฐ ๋ผ์ฐํฐ ํจ์๋ฅผ ์ง์ ํธ์ถํ๊ณ ,
๊ทธ ๊ฒฐ๊ณผ JSON ์ backend/cache/ ์ ์ ์ฅํ๋ค. Hugging Face Spaces ์ฒ๋ผ ๋ฐ์ดํฐ์ผํฐ
IP ์์ yfinance ๊ฐ 401 ๋ก ์ฐจ๋จ๋๋ ํ๊ฒฝ์์ ์ด ์บ์๊ฐ fallback ์ผ๋ก ์ ๊ณต๋๋ค.
์คํ:
cd D:/OStock/backend
.venv/Scripts/python.exe scripts/build_cache.py
์ฃผ์: news/prediction ๋ผ์ฐํฐ๋ transformers->torch ๋ฅผ ๋์ด์ import ์์ ์ด์๊ฐ
์์ผ๋ฏ๋ก, ์ฌ๊ธฐ์๋ yfinance ๊ธฐ๋ฐ ๋ผ์ฐํฐ(market/quotes/financial/technical)๋ง import ํ๋ค.
"""
import os
import sys
import json
import datetime
# scripts/ ์์ ์คํํด๋ backend/ ๋ชจ๋์ import ํ ์ ์๋๋ก backend ๊ฒฝ๋ก ์ถ๊ฐ
BACKEND_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, BACKEND_DIR)
from config import SECTOR_TICKERS # noqa: E402
from routers import market, quotes, financial, technical # noqa: E402
CACHE_DIR = os.path.join(BACKEND_DIR, "cache")
def _save(relpath, data):
path = os.path.join(CACHE_DIR, relpath)
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
def _is_error(result):
"""์๋ํฌ์ธํธ ๊ฒฐ๊ณผ๊ฐ ์๋ฌ/๋น๊ฐ์ด๋ฉด True (์ ์ฅ ์คํต + ์คํจ ์นด์ดํธ์ฉ)."""
if result is None:
return True
if isinstance(result, dict):
if "error" in result:
return True
vals = list(result.values())
# sectors/bond ์ฒ๋ผ ๋ชจ๋ ํ์ ํญ๋ชฉ์ด ์๋ฌ dict ์ธ ๊ฒฝ์ฐ
if vals and all(isinstance(v, dict) and "error" in v for v in vals):
return True
return False
if isinstance(result, list):
return len(result) == 0
return False
def main():
os.makedirs(CACHE_DIR, exist_ok=True)
stats = {"ok": 0, "fail": 0, "failed": []}
def run(label, relpath, fn):
try:
result = fn()
except Exception as e: # noqa: BLE001
result = {"error": str(e)}
if _is_error(result):
stats["fail"] += 1
stats["failed"].append(label)
print(f" [FAIL] {label}")
else:
_save(relpath, result)
stats["ok"] += 1
print(f" [ OK ] {label}")
print("== ๋ฌดํ๋ผ๋ฏธํฐ ์๋ํฌ์ธํธ ==")
run("indices", "indices.json", market.get_market_indices)
run("sectors", "sectors.json", market.get_sector_data)
run("get_bond_data", "get_bond_data.json", market.get_bond_data)
print(f"== ์ข
๋ชฉ๋ณ ์๋ํฌ์ธํธ ({len(SECTOR_TICKERS)} ์ข
๋ชฉ x 4) ==")
for _name, tk in SECTOR_TICKERS.items():
run(f"stocks/{tk}", f"stocks/{tk}.json",
lambda tk=tk: quotes.get_stock_data(ticker=tk))
# period/interval ์ ๋ช
์ ์ ๋ฌํด์ผ ํ๋ค. ํจ์๋ฅผ ์ง์ ํธ์ถํ๋ฉด FastAPI ๊ฐ
# ์ฃผ์
ํ์ง ์์ ๊ธฐ๋ณธ๊ฐ์ด Query(...) ๊ฐ์ฒด๋ก ๋จ์ .lower() ์์ ๊นจ์ง๋ค.
run(f"stock_chart/{tk}", f"stock_chart/{tk}.json",
lambda tk=tk: quotes.get_stock_chart(ticker=tk, period="1mo", interval="1d"))
run(f"financial_info/{tk}", f"financial_info/{tk}.json",
lambda tk=tk: financial.get_financial_info(ticker=tk))
run(f"technical_info/{tk}", f"technical_info/{tk}.json",
lambda tk=tk: technical.get_technical_info(ticker=tk))
meta = {
"generated_at": datetime.datetime.now().astimezone().isoformat(timespec="seconds"),
"endpoints": [
"indices", "sectors", "get_bond_data",
"stocks", "stock_chart", "financial_info", "technical_info",
],
"ticker_count": len(SECTOR_TICKERS),
"success": stats["ok"],
"failed": stats["fail"],
}
with open(os.path.join(CACHE_DIR, ".meta.json"), "w", encoding="utf-8") as f:
json.dump(meta, f, ensure_ascii=False, indent=2)
print(f"\n์๋ฃ: ์ฑ๊ณต {stats['ok']} / ์คํจ {stats['fail']}")
if stats["failed"]:
print("์คํจ ํญ๋ชฉ:", ", ".join(stats["failed"]))
print("์์ฑ ์๊ฐ:", meta["generated_at"])
if __name__ == "__main__":
main()
|