"""yfinance 차단(예: 데이터센터 IP 의 Yahoo Finance 401) 시 사용하는 fallback 캐시 로더. backend/cache/ 디렉터리에 사전 빌드된 JSON 을 읽어 반환한다. 정상(yfinance 동작) 경로에서는 호출되지 않으며, 라우터의 except/실패 분기에서만 쓰인다. 캐시는 scripts/build_cache.py 로 로컬(yfinance 동작 환경)에서 생성한다. """ import json import os # 이 파일(backend/cache_fallback.py) 기준으로 cache/ 를 찾는다 (CWD 에 의존하지 않음). _CACHE_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "cache") def load_cache(key, ticker=None): """사전 빌드 캐시를 반환한다. - ticker 가 없으면 cache/.json - ticker 가 있으면 cache//.json 파일이 없거나 손상되면 None 을 반환한다 (graceful). """ if ticker is not None: path = os.path.join(_CACHE_DIR, key, f"{ticker}.json") else: path = os.path.join(_CACHE_DIR, f"{key}.json") try: with open(path, "r", encoding="utf-8") as f: return json.load(f) except (FileNotFoundError, json.JSONDecodeError, OSError): return None def load_meta(): """캐시 생성 메타(cache/.meta.json)를 반환한다. 없으면 {'generated_at': None}.""" path = os.path.join(_CACHE_DIR, ".meta.json") try: with open(path, "r", encoding="utf-8") as f: return json.load(f) except (FileNotFoundError, json.JSONDecodeError, OSError): return {"generated_at": None}