eshan6704 commited on
Commit
4f453c6
·
verified ·
1 Parent(s): 81bf4ef

Create csvloader.py

Browse files
Files changed (1) hide show
  1. app/csvloader.py +144 -0
app/csvloader.py ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ==============================
2
+ # Imports
3
+ # ==============================
4
+ import requests
5
+ import zipfile
6
+ from io import BytesIO, StringIO
7
+ from datetime import datetime as dt
8
+ from typing import Dict, Union
9
+
10
+ import pandas as pd
11
+
12
+ from persist import exists, load, save
13
+
14
+
15
+ # ==============================
16
+ # Raw CSV Loader (NO parsing)
17
+ # ==============================
18
+ def load_csv(url: str) -> Union[str, Dict[str, str]]:
19
+ """
20
+ Pure transport loader
21
+ - .csv -> raw CSV text (str)
22
+ - .zip -> {filename: raw CSV text}
23
+
24
+ NO parsing
25
+ NO cleaning
26
+ NO assumptions
27
+ """
28
+ r = requests.get(url)
29
+ r.raise_for_status()
30
+
31
+ if url.lower().endswith(".zip"):
32
+ z = zipfile.ZipFile(BytesIO(r.content))
33
+ out: Dict[str, str] = {}
34
+
35
+ for name in z.namelist():
36
+ if name.lower().endswith(".csv"):
37
+ with z.open(name) as f:
38
+ out[name] = f.read().decode("utf-8", errors="ignore")
39
+ return out
40
+
41
+ return r.text
42
+
43
+
44
+ # ==============================
45
+ # NSE High-Low HTML Formatter
46
+ # ==============================
47
+ def _highlow_html_formatter(df: pd.DataFrame, date_str: str) -> str:
48
+ metric = "PERCENT_CHANGE"
49
+ df_html = df.copy()
50
+
51
+ top_up = df[metric].nlargest(3).index if metric in df else []
52
+ top_dn = df[metric].nsmallest(3).index if metric in df else []
53
+
54
+ for idx, row in df_html.iterrows():
55
+ for col in df_html.columns:
56
+ val = row[col]
57
+ style = ""
58
+
59
+ if isinstance(val, (int, float)):
60
+ txt = f"{val:.2f}"
61
+ if val > 0:
62
+ style = "pos"
63
+ elif val < 0:
64
+ style = "neg"
65
+
66
+ if col == metric:
67
+ if idx in top_up:
68
+ style += " top-up"
69
+ elif idx in top_dn:
70
+ style += " top-down"
71
+
72
+ df_html.at[idx, col] = f'<span class="{style.strip()}">{txt}</span>'
73
+ else:
74
+ df_html.at[idx, col] = str(val)
75
+
76
+ return f"""
77
+ <!DOCTYPE html>
78
+ <html>
79
+ <head>
80
+ <meta charset="UTF-8">
81
+ <title>NSE High-Low {date_str}</title>
82
+ <style>
83
+ body {{ font-family: Arial; background:#f5f5f5; padding:12px; }}
84
+ table {{ border-collapse: collapse; width:100%; background:white; }}
85
+ th, td {{ border:1px solid #bbb; padding:6px; font-size:13px; }}
86
+ th {{ background:#222; color:white; }}
87
+ .pos {{ color:green; font-weight:bold; }}
88
+ .neg {{ color:red; font-weight:bold; }}
89
+ .top-up {{ background:#b6f2b6; }}
90
+ .top-down {{ background:#f2b6b6; }}
91
+ </style>
92
+ </head>
93
+ <body>
94
+ <h2>NSE Index High / Low — {date_str}</h2>
95
+ {df_html.to_html(index=False, escape=False)}
96
+ </body>
97
+ </html>
98
+ """
99
+
100
+
101
+ # ==============================
102
+ # NSE High-Low Master Function
103
+ # ==============================
104
+ def nse_highlow(date_str: str | None = None) -> str:
105
+ """
106
+ Master NSE High-Low function
107
+
108
+ Responsibilities:
109
+ - Knows NSE CSV structure
110
+ - Header starts at row index 2 (skip 0 & 1)
111
+ - Uses raw CSV loader
112
+ - Builds HTML
113
+ - Persists ONLY HTML
114
+ """
115
+ if not date_str:
116
+ date_str = dt.now().strftime("%d-%m-%Y")
117
+
118
+ cache_key = f"highlow_{date_str}"
119
+
120
+ if exists(cache_key, "html"):
121
+ return load(cache_key, "html")
122
+
123
+ d = dt.strptime(date_str, "%d-%m-%Y")
124
+ url = (
125
+ "https://archives.nseindia.com/content/indices/"
126
+ f"ind_close_all_{d.strftime('%d%m%Y')}.csv"
127
+ )
128
+
129
+ # 1️⃣ Load raw CSV text
130
+ csv_text = load_csv(url)
131
+
132
+ # 2️⃣ NSE-specific parsing (header row = 2)
133
+ df = pd.read_csv(
134
+ StringIO(csv_text),
135
+ header=0
136
+ )
137
+
138
+ # 3️⃣ Build HTML
139
+ html = _highlow_html_formatter(df, date_str)
140
+
141
+ # 4️⃣ Persist HTML only
142
+ save(cache_key, html, "html")
143
+
144
+ return html