from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel import os import importlib.util # ------------------------------------------------------- # Explicit module loader (HF-safe) # ------------------------------------------------------- BASE_DIR = os.path.dirname(os.path.abspath(__file__)) def load_module(name): path = os.path.join(BASE_DIR, f"{name}.py") if not os.path.exists(path): raise ImportError(f"Module file not found: {path}") spec = importlib.util.spec_from_file_location(name, path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module # ------------------------------------------------------- # Load ALL local modules explicitly # ------------------------------------------------------- common = load_module("common") stock = load_module("stock") indices_html = load_module("indices_html") index_live_html = load_module("index_live_html") preopen_html = load_module("preopen_html") eq_html = load_module("eq_html") bhavcopy_html = load_module("bhavcopy_html") build_nse_fno = load_module("build_nse_fno") # External libs (installed via requirements.txt) import nsepython import yahooinfo # ------------------------------------------------------- # FastAPI app # ------------------------------------------------------- app = FastAPI(title="Stock / Index Backend") app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) # ------------------------------------------------------- # Valid request types # ------------------------------------------------------- STOCK_REQ = [ "info", "intraday", "daily", "nse_eq", "qresult", "result", "balance", "cashflow", "dividend", "split", "other", "stock_hist" ] INDEX_REQ = [ "indices", "nse_open", "nse_preopen", "nse_fno", "nse_fiidii", "nse_events", "nse_future", "nse_bhav", "nse_highlow", "stock_highlow", "index_history", "nse_largedeals", "nse_most_active", "largedeals_historical", "nse_bulkdeals", "nse_blockdeals", "index_pe_pb_div", "index_total_returns" ] # ------------------------------------------------------- # Request model # ------------------------------------------------------- class FetchRequest(BaseModel): mode: str req_type: str name: str date_start: str date_end: str # ------------------------------------------------------- # Health # ------------------------------------------------------- @app.get("/") def health(): return {"status": "ok", "service": "backend alive"} # ------------------------------------------------------- # STOCK handler # ------------------------------------------------------- def handle_stock(req: FetchRequest): t = req.req_type.lower() if t == "info": return common.wrap(yahooinfo.fetch_info(req.name)) if t == "intraday": return common.wrap(stock.fetch_intraday(req.name, req.date_start, req.date_end)) if t == "daily": return common.wrap(stock.fetch_daily(req.name, req.date_start, req.date_end)) if t == "nse_eq": return eq_html.build_eq_html(req.name) if t == "qresult": return common.wrap(stock.fetch_qresult(req.name)) if t == "result": return common.wrap(stock.fetch_result(req.name)) if t == "balance": return common.wrap(stock.fetch_balance(req.name)) if t == "cashflow": return common.wrap(stock.fetch_cashflow(req.name)) if t == "dividend": return common.wrap(stock.fetch_dividend(req.name)) if t == "split": return common.wrap(stock.fetch_split(req.name)) if t == "other": return common.wrap(stock.fetch_other(req.name)) if t == "stock_hist": return nsepython.nse_stock_hist( req.date_start, req.date_end, req.name ).to_html() return common.wrap(f"