# ============================== # Imports # ============================== import requests import zipfile from io import BytesIO, StringIO from datetime import datetime as dt from typing import Dict, Union import pandas as pd # persist helpers from .persist import exists, load, save # ============================== # Raw CSV Loader (NO parsing) # ============================== def load_csv(url: str) -> Union[str, Dict[str, str]]: """ Pure transport loader - .csv -> raw CSV text (str) - .zip -> {filename: raw CSV text} NO parsing NO cleaning NO assumptions """ r = requests.get(url) r.raise_for_status() if url.lower().endswith(".zip"): z = zipfile.ZipFile(BytesIO(r.content)) out: Dict[str, str] = {} for name in z.namelist(): if name.lower().endswith(".csv"): with z.open(name) as f: out[name] = f.read().decode("utf-8", errors="ignore") return out return r.text # ============================== # NSE High-Low HTML Formatter # ============================== def _highlow_html_formatter(df: pd.DataFrame, date_str: str) -> str: metric = "PERCENT_CHANGE" df_html = df.copy() top_up = df[metric].nlargest(3).index if metric in df else [] top_dn = df[metric].nsmallest(3).index if metric in df else [] for idx, row in df_html.iterrows(): for col in df_html.columns: val = row[col] style = "" if isinstance(val, (int, float)): txt = f"{val:.2f}" if val > 0: style = "pos" elif val < 0: style = "neg" if col == metric: if idx in top_up: style += " top-up" elif idx in top_dn: style += " top-down" df_html.at[idx, col] = f'{txt}' else: df_html.at[idx, col] = str(val) return f""" NSE High-Low {date_str}

NSE Index High / Low — {date_str}

{df_html.to_html(index=False, escape=False)} """ # ============================== # NSE High-Low Master Function # ============================== def nse_highlow(date_str: str | None = None) -> str: """ Master NSE High-Low function Responsibilities: - Knows NSE CSV structure - Header starts at row index 2 (skip 0 & 1) - Uses raw CSV loader - Builds HTML - Persists ONLY HTML """ if not date_str: date_str = dt.now().strftime("%d-%m-%Y") cache_key = f"highlow_{date_str}" if exists(cache_key, "html"): return load(cache_key, "html") d = dt.strptime(date_str, "%d-%m-%Y") url = ( "https://archives.nseindia.com/content/indices/" f"ind_close_all_{d.strftime('%d%m%Y')}.csv" ) # 1️⃣ Load raw CSV text csv_text = load_csv(url) # 2️⃣ NSE-specific parsing (header row = 2) df = pd.read_csv( StringIO(csv_text), header=0 ) # 3️⃣ Build HTML html = _highlow_html_formatter(df, date_str) # 4️⃣ Persist HTML only save(cache_key, html, "html") return html