from nsepython import * import pandas as pd def build_index_live_html(name=""): p = nse_index_live(name) full_df = p.get("data", pd.DataFrame()) rem_df = p.get("rem", pd.DataFrame()) if full_df.empty: main_df = pd.DataFrame() const_df = pd.DataFrame() else: main_df = full_df.iloc[[0]] const_df = full_df.iloc[1:] # Constituents if not const_df.empty: const_df = const_df.iloc[:, 1:] # Remove first column # Columns to move from constituents to info move_to_info = [c for c in ['segment', 'equityTime', 'preOpenTime'] if c in const_df.columns] if move_to_info: rem_df = pd.concat([rem_df, const_df[move_to_info].iloc[[0]]], axis=1) const_df = const_df.drop(columns=move_to_info) # Drop unnecessary columns from Constituents drop_cols_const = [ "identifier", "ffmc", "stockIndClosePrice", "lastUpdateTime", "chartTodayPath", "chart30dPath", "chart365dPath", "series", "symbol_meta", "activeSeries", "debtSeries", "isFNOSec", "isCASec", "isSLBSec", "isDebtSec", "isSuspended", "tempSuspendedSeries", "isETFSec", "isDelisted", "slb_isin", "isMunicipalBond", "isHybridSymbol", "QuotePreOpenFlag" ] const_df = const_df.drop(columns=[c for c in drop_cols_const if c in const_df.columns]) # Drop unnecessary columns from Main Data drop_cols_main = [ "series", "symbol_meta", "companyName", "industry", "activeSeries", "debtSeries", "isFNOSec", "isCASec", "isSLBSec", "isDebtSec", "isSuspended", "tempSuspendedSeries", "isETFSec", "isDelisted", "isin", "slb_isin", "listingDate", "isMunicipalBond", "isHybridSymbol", "segment", "equityTime", "preOpenTime", "QuotePreOpenFlag" ] main_df = main_df.drop(columns=[c for c in drop_cols_main if c in main_df.columns]) # Ensure pChange is numeric and sort if 'pChange' in const_df.columns: const_df['pChange'] = pd.to_numeric(const_df['pChange'], errors='coerce') const_df = const_df.sort_values('pChange', ascending=False) # ================= HELPER FUNCTION: COLOR-CODE AND FORMAT NUMERIC ================= def df_to_html_color(df, metric_col=None): df_html = df.copy() top3_up = [] top3_down = [] if metric_col and metric_col in df_html.columns and pd.api.types.is_numeric_dtype(df_html[metric_col]): col_numeric = df_html[metric_col].dropna() top3_up = col_numeric.nlargest(3).index.tolist() top3_down = col_numeric.nsmallest(3).index.tolist() for idx, row in df_html.iterrows(): for col in df_html.columns: val = row[col] style = "" if pd.api.types.is_numeric_dtype(type(val)) or isinstance(val, (int, float)): val_fmt = f"{val:.2f}" if val > 0: style = "numeric-positive" elif val < 0: style = "numeric-negative" if metric_col and col == metric_col: if idx in top3_up: style += " top-up" elif idx in top3_down: style += " top-down" df_html.at[idx, col] = f'{val_fmt}' else: df_html.at[idx, col] = str(val) return df_html.to_html(index=False, escape=False, classes="compact-table") # ================= MERGE INFO AND MAIN KEYS INTO MINI CARDS ================= def merge_info_main_cards(rem_df, main_df): combined = pd.concat([rem_df, main_df], axis=1) # Remove duplicate columns combined = combined.loc[:, ~combined.columns.duplicated()] # Generate mini cards cards_html = '