eshan6704 commited on
Commit
31ca2a2
·
verified ·
1 Parent(s): 1dd3a14

Create app.py

Browse files
Files changed (1) hide show
  1. app/app.py +227 -0
app/app.py ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from fastapi.responses import HTMLResponse
3
+ from fastapi.middleware.cors import CORSMiddleware
4
+ from fastapi.middleware.gzip import GZipMiddleware
5
+ from pydantic import BaseModel
6
+
7
+ # -------------------------------------------------------
8
+ # Local modules
9
+ # -------------------------------------------------------
10
+ from . import common
11
+ from . import stock
12
+ from . import indices_html as indices
13
+ from . import index_live_html as live
14
+ from . import preopen_html as pre
15
+ from . import eq_html as eq
16
+ from . import bhavcopy_html as bhav
17
+ from . import build_nse_fno as fno
18
+ from . import nsepythonmodified as ns
19
+ from . import yahooinfo
20
+ from . import screener # screener owns its map
21
+
22
+
23
+ # -------------------------------------------------------
24
+ # FastAPI app
25
+ # -------------------------------------------------------
26
+ app = FastAPI(title="Stock / Index Backend")
27
+
28
+ # -------------------------------------------------------
29
+ # Middleware
30
+ # -------------------------------------------------------
31
+ app.add_middleware(
32
+ CORSMiddleware,
33
+ allow_origins=["*"],
34
+ allow_methods=["*"],
35
+ allow_headers=["*"],
36
+ )
37
+
38
+ app.add_middleware(GZipMiddleware, minimum_size=1000)
39
+
40
+
41
+ # -------------------------------------------------------
42
+ # Request model
43
+ # -------------------------------------------------------
44
+ class FetchRequest(BaseModel):
45
+ mode: str
46
+ req_type: str
47
+ name: str = ""
48
+ date_start: str = ""
49
+ date_end: str = ""
50
+
51
+
52
+ # -------------------------------------------------------
53
+ # Health
54
+ # -------------------------------------------------------
55
+ @app.get("/")
56
+ def health():
57
+ return {"status": "ok", "service": "backend alive"}
58
+
59
+
60
+ # -------------------------------------------------------
61
+ # REQ TYPE MAP (stock & index only)
62
+ # -------------------------------------------------------
63
+ REQ_TYPE_MAP = {
64
+ "stock": [
65
+ "info", "intraday", "daily", "nse_eq", "qresult",
66
+ "result", "balance", "cashflow", "dividend",
67
+ "split", "other", "stock_hist"
68
+ ],
69
+ "index": [
70
+ "indices", "nse_open", "nse_preopen", "nse_fno",
71
+ "nse_fiidii", "nse_events", "nse_future",
72
+ "nse_highlow", "stock_highlow", "nse_bhav",
73
+ "nse_largedeals", "nse_bulkdeals", "nse_blockdeals",
74
+ "nse_most_active", "index_history",
75
+ "largedeals_historical", "index_pe_pb_div",
76
+ "index_total_returns"
77
+ ],
78
+ }
79
+
80
+
81
+ # -------------------------------------------------------
82
+ # HTML builder for req_type discovery
83
+ # -------------------------------------------------------
84
+ def build_req_type_list_html():
85
+ html = ["<div id='req_type_list'>"]
86
+
87
+ # STOCK & INDEX
88
+ for mode, items in REQ_TYPE_MAP.items():
89
+ html.append(f"<h3>{mode.upper()}</h3><ul>")
90
+ for it in items:
91
+ html.append(
92
+ f"<li class='{mode}-req' data-mode='{mode}'>{it}</li>"
93
+ )
94
+ html.append("</ul>")
95
+
96
+ # SCREENER (keys extracted from screener.py)
97
+ html.append("<h3>SCREENER</h3><ul>")
98
+ for key in screener.SCREENER_MAP.keys():
99
+ html.append(
100
+ f"<li class='screener-req' data-mode='screener'>{key}</li>"
101
+ )
102
+ html.append("</ul></div>")
103
+
104
+ return "".join(html)
105
+
106
+
107
+ # -------------------------------------------------------
108
+ # STOCK handler
109
+ # -------------------------------------------------------
110
+ def handle_stock(req: FetchRequest):
111
+ t = req.req_type.lower()
112
+
113
+ if t == "info":
114
+ return yahooinfo.fetch_info(req.name)
115
+ if t == "intraday":
116
+ return stock.fetch_intraday(req.name)
117
+ if t == "daily":
118
+ return stock.fetch_daily(req.name, req.date_end)
119
+ if t == "nse_eq":
120
+ return eq.build_eq_html(req.name)
121
+ if t == "qresult":
122
+ return stock.fetch_qresult(req.name)
123
+ if t == "result":
124
+ return stock.fetch_result(req.name)
125
+ if t == "balance":
126
+ return stock.fetch_balance(req.name)
127
+ if t == "cashflow":
128
+ return stock.fetch_cashflow(req.name)
129
+ if t == "dividend":
130
+ return stock.fetch_dividend(req.name)
131
+ if t == "split":
132
+ return stock.fetch_split(req.name)
133
+ if t == "other":
134
+ return stock.fetch_other(req.name)
135
+ if t == "stock_hist":
136
+ return ns.nse_stock_hist(
137
+ req.date_start, req.date_end, req.name
138
+ ).to_html()
139
+
140
+ return common.wrap(f"<h3>Unhandled stock req_type: {t}</h3>")
141
+
142
+
143
+ # -------------------------------------------------------
144
+ # INDEX handler
145
+ # -------------------------------------------------------
146
+ def handle_index(req: FetchRequest):
147
+ t = req.req_type.lower()
148
+
149
+ if t == "indices":
150
+ return indices.build_indices_html()
151
+ if t == "nse_open":
152
+ return live.build_index_live_html()
153
+ if t == "nse_preopen":
154
+ return pre.build_preopen_html()
155
+ if t == "nse_fno":
156
+ return fno.nse_fno_html(req.date_end, req.name)
157
+ if t == "nse_fiidii":
158
+ return ns.nse_fiidii()
159
+ if t == "nse_events":
160
+ return ns.nse_events()
161
+ if t == "nse_future":
162
+ return ns.nse_future(req.name)
163
+ if t == "nse_highlow":
164
+ return ns.nse_highlow(req.date_end)
165
+ if t == "stock_highlow":
166
+ return ns.stock_highlow(req.date_end)
167
+ if t == "nse_bhav":
168
+ return bhav.build_bhavcopy_html(req.date_end)
169
+ if t == "nse_largedeals":
170
+ return ns.nse_largedeals()
171
+ if t == "nse_bulkdeals":
172
+ return ns.nse_bulkdeals()
173
+ if t == "nse_blockdeals":
174
+ return ns.nse_blockdeals()
175
+ if t == "nse_most_active":
176
+ return ns.nse_most_active()
177
+ if t == "index_history":
178
+ return ns.index_history("NIFTY", req.date_start, req.date_end)
179
+ if t == "largedeals_historical":
180
+ return ns.nse_largedeals_historical(
181
+ req.date_start, req.date_end
182
+ )
183
+ if t == "index_pe_pb_div":
184
+ return ns.index_pe_pb_div(
185
+ "NIFTY", req.date_start, req.date_end
186
+ )
187
+ if t == "index_total_returns":
188
+ return ns.index_total_returns(
189
+ "NIFTY", req.date_start, req.date_end
190
+ )
191
+
192
+ return common.wrap(f"<h3>Unhandled index req_type: {t}</h3>")
193
+
194
+
195
+ # -------------------------------------------------------
196
+ # SCREENER handler
197
+ # -------------------------------------------------------
198
+ def handle_screener(req: FetchRequest):
199
+ return screener.fetch_screener(req.req_type.lower())
200
+
201
+
202
+ # -------------------------------------------------------
203
+ # Main API
204
+ # -------------------------------------------------------
205
+ @app.post("/api/fetch", response_class=HTMLResponse)
206
+ def fetch_data(req: FetchRequest):
207
+
208
+ mode = req.mode.lower()
209
+
210
+ # ✅ Used by frontend on page load
211
+ if mode == "list":
212
+ return HTMLResponse(content=build_req_type_list_html())
213
+
214
+ if mode == "stock":
215
+ html = handle_stock(req)
216
+
217
+ elif mode == "index":
218
+ html = handle_index(req)
219
+
220
+ elif mode == "screener":
221
+ html = handle_screener(req)
222
+
223
+ else:
224
+ raise HTTPException(status_code=400, detail="Invalid mode")
225
+
226
+ # 🔒 Always return HTML
227
+ return HTMLResponse(content=str(html))