eshan6704 commited on
Commit
1e5fc44
·
verified ·
1 Parent(s): 8c6ae93

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +146 -273
app.py CHANGED
@@ -1,7 +1,9 @@
1
- import gradio as gr
2
- import pandas as pd
3
- import datetime
 
4
 
 
5
  import common
6
  import stock
7
  import indices_html
@@ -12,10 +14,6 @@ import bhavcopy_html
12
  import nsepython
13
  import yahooinfo
14
  import build_nse_fno
15
- from fastapi import FastAPI, HTTPException
16
- from fastapi.middleware.cors import CORSMiddleware
17
- from pydantic import BaseModel
18
- from typing import Optional, Callable, Dict
19
 
20
  app = FastAPI(title="Stock Backend")
21
 
@@ -27,284 +25,159 @@ app.add_middleware(
27
  allow_headers=["*"],
28
  )
29
 
30
- # ---------- REQUEST MODEL (ONLY 4 FIELDS) ----------
31
  class FetchRequest(BaseModel):
32
- req_type: str # stock_info | stock_intraday | stock_daily | ...
33
  name: str
34
- date_end: str # dd-mm-yyyy (ALWAYS REQUIRED)
35
- date_start: Optional[str] = None # dd-mm-yyyy (optional)
36
-
37
- # ---------- HEALTH ----------
38
- @app.get("/")
39
- def health():
40
- return {"status": "ok", "service": "backend alive"}
41
 
42
- # ---------- HANDLERS ----------
43
  def stock_info(req: FetchRequest):
44
- return {
45
- "success": True,
46
- "meta": {
47
- "req_type": req.req_type,
48
- "name": req.name,
49
- "as_on": req.date_end
50
- },
51
- "data": {
52
- "sector": "FMCG",
53
- "market_cap": "5.2L Cr",
54
- "pe": 28.4
55
- }
56
- }
57
 
58
  def stock_intraday(req: FetchRequest):
59
- return {
60
- "success": True,
61
- "meta": {
62
- "req_type": req.req_type,
63
- "name": req.name,
64
- "as_on": req.date_end,
65
- "interval": "5min"
66
- },
67
- "data": [
68
- {"time": "09:15", "close": 412.5, "volume": 120345},
69
- {"time": "09:20", "close": 413.8, "volume": 98234},
70
- {"time": "09:25", "close": 413.5, "volume": 75621}
71
- ]
72
- }
73
 
74
  def stock_daily(req: FetchRequest):
75
- return {
76
- "success": True,
77
- "meta": {
78
- "req_type": req.req_type,
79
- "name": req.name,
80
- "to": req.date_end
81
- },
82
- "data": [
83
- {"date": "23-12-2025", "close": 410.2},
84
- {"date": "24-12-2025", "close": 412.9},
85
- {"date": "25-12-2025", "close": 413.5}
86
- ]
87
- }
88
-
89
- # ---------- ROUTER ----------
90
- ROUTER: Dict[str, Callable[[FetchRequest], dict]] = {
91
- "stock_info": stock_info,
92
- "stock_intraday": stock_intraday,
93
- "stock_daily": stock_daily,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  }
95
 
96
  # ---------- MAIN ENDPOINT ----------
97
  @app.post("/api/fetch")
98
  def fetch_data(req: FetchRequest):
99
-
100
  handler = ROUTER.get(req.req_type)
101
-
102
  if not handler:
103
- raise HTTPException(
104
- status_code=400,
105
- detail=f"Unsupported req_type: {req.req_type}"
106
- )
107
-
108
- return handler(req)
109
-
110
-
111
- # ======================================================
112
- # Date helpers
113
- # ======================================================
114
- def today_str():
115
- return datetime.date.today().strftime("%d-%m-%Y")
116
-
117
- import datetime
118
-
119
- def sd_ed(d: str) -> tuple[str, str]:
120
- base_date = datetime.datetime.strptime(d, "%d-%m-%Y").date()
121
-
122
- def is_working_day(x):
123
- return x.weekday() < 5 # Mon–Fri
124
-
125
- def prev_working(x):
126
- while not is_working_day(x):
127
- x -= datetime.timedelta(days=1)
128
- return x
129
-
130
- # -------- Last working day (before given date) --------
131
- last_working = prev_working(base_date - datetime.timedelta(days=1))
132
-
133
- # -------- 364-day back, fallback to 363, 362, ... --------
134
- past_working = prev_working(base_date - datetime.timedelta(days=364))
135
-
136
- return (
137
-
138
- past_working.strftime("%d-%m-%Y"),
139
- last_working.strftime("%d-%m-%Y")
140
- )
141
-
142
-
143
- # ======================================================
144
- # Request Type Options
145
- # ======================================================
146
- STOCK_REQ = [
147
- "info", "intraday", "daily", "nse_eq", "qresult", "result",
148
- "balance", "cashflow", "dividend", "split", "other", "stock_hist"
149
- ]
150
-
151
- INDEX_REQ = [
152
- "indices", "nse_open", "nse_preopen", "nse_fno", "nse_fiidii",
153
- "nse_events", "nse_future", "nse_bhav", "nse_highlow","stock_highlow",
154
- "index_history", "nse_largedeals", "nse_most_active",
155
- "largedeals_historical", "nse_bulkdeals", "nse_blockdeals",
156
- "index_pe_pb_div", "index_total_returns"
157
- ]
158
-
159
-
160
- # ======================================================
161
- # Update UI based on mode
162
- # ======================================================
163
- def update_on_mode(mode):
164
- if mode == "stock":
165
- return (
166
- gr.update(choices=STOCK_REQ, value="info"),
167
- gr.update(value="ITC"),
168
- gr.update(value=today_str())
169
- )
170
- elif mode == "index":
171
- return (
172
- gr.update(choices=INDEX_REQ, value="indices"),
173
- gr.update(value="NIFTY 50"),
174
- gr.update(value=today_str())
175
- )
176
- return (
177
- gr.update(choices=[], value=""),
178
- gr.update(value=""),
179
- gr.update(value="")
180
- )
181
-
182
-
183
- # ======================================================
184
- # Data Fetcher
185
- # ======================================================
186
- def fetch_data(mode, req_type, name, date_str):
187
- req_type = req_type.lower()
188
- name = name.strip()
189
- from_date,to_date = sd_ed(date_str.strip())
190
-
191
-
192
- if mode == "index":
193
- if req_type == "indices":
194
- return indices_html.build_indices_html()
195
- elif req_type == "nse_open":
196
- return index_live_html.build_index_live_html()
197
- elif req_type == "nse_preopen":
198
- return preopen_html.build_preopen_html()
199
- elif req_type == "nse_fno":
200
- return build_nse_fno.nse_fno_html(to_date, name)
201
- elif req_type == "nse_events":
202
- return nsepython.nse_events().to_html()
203
- elif req_type == "nse_fiidii":
204
- return nsepython.nse_fiidii().to_html()
205
- elif req_type == "nse_future":
206
- return common.wrap(nsepython.nse_future(name))
207
- elif req_type == "nse_highlow":
208
- return nsepython.nse_highlow(to_date).to_html()
209
- elif req_type == "stock_highlow":
210
- return nsepython.stock_highlow(to_date).to_html()
211
- elif req_type == "nse_bhav":
212
- return bhavcopy_html.build_bhavcopy_html(to_date)
213
- elif req_type == "nse_largedeals":
214
- return nsepython.nse_largedeals().to_html()
215
- elif req_type == "nse_bulkdeals":
216
- return nsepython.nse_bulkdeals().to_html()
217
- elif req_type == "nse_blockdeals":
218
- return nsepython.nse_blockdeals().to_html()
219
- elif req_type == "nse_most_active":
220
- return nsepython.nse_most_active().to_html()
221
- elif req_type == "index_history":
222
- return nsepython.index_history("NIFTY", from_date, to_date).to_html()
223
- elif req_type == "largedeals_historical":
224
- return nsepython.nse_largedeals_historical(from_date, to_date).to_html()
225
- elif req_type == "index_pe_pb_div":
226
- return nsepython.index_pe_pb_div("NIFTY", from_date, to_date).to_html()
227
- elif req_type == "index_total_returns":
228
- return nsepython.index_total_returns("NIFTY", from_date, to_date).to_html()
229
- else:
230
- return common.wrap(f"<h3>No handler for {req_type}</h3>")
231
-
232
- elif mode == "stock":
233
- if req_type == "daily":
234
- return common.wrap(stock.fetch_daily(name))
235
- elif req_type == "nse_eq":
236
- return eq_html.build_eq_html(name)
237
- elif req_type == "intraday":
238
- return common.wrap(stock.fetch_intraday(name))
239
- elif req_type == "info":
240
- return common.wrap(yahooinfo.fetch_info(name))
241
- elif req_type == "qresult":
242
- return common.wrap(stock.fetch_qresult(name))
243
- elif req_type == "result":
244
- return common.wrap(stock.fetch_result(name))
245
- elif req_type == "balance":
246
- return common.wrap(stock.fetch_balance(name))
247
- elif req_type == "cashflow":
248
- return common.wrap(stock.fetch_cashflow(name))
249
- elif req_type == "dividend":
250
- return common.wrap(stock.fetch_dividend(name))
251
- elif req_type == "split":
252
- return common.wrap(stock.fetch_split(name))
253
- elif req_type == "other":
254
- return common.wrap(stock.fetch_other(name))
255
- elif req_type == "stock_hist":
256
- return nsepython.nse_stock_hist(from_date, to_date, name).to_html()
257
- else:
258
- return common.wrap(f"<h3>No handler for {req_type}</h3>")
259
-
260
- return common.wrap(f"<h3>No valid mode: {mode}</h3>")
261
-
262
-
263
- # ======================================================
264
- # Gradio UI
265
- # ======================================================
266
- with gr.Blocks(title="Stock / Index App") as iface:
267
-
268
- gr.Markdown("### **Stock / Index Data Fetcher**")
269
-
270
- with gr.Row():
271
- mode_input = gr.Radio(
272
- ["stock", "index"],
273
- label="Mode",
274
- value="stock",
275
- scale=1
276
- )
277
- name_input = gr.Textbox(label="Symbol / Index Name", scale=2)
278
- req_type_input = gr.Dropdown(label="Request Type", allow_custom_value=True, scale=2)
279
- date_input = gr.Textbox(label="Date (DD-MM-YYYY)", placeholder="Leave empty = yesterday", scale=1)
280
- fetch_btn = gr.Button("Fetch", scale=1)
281
-
282
- output = gr.HTML(label="Output")
283
-
284
- # Mode change → auto defaults
285
- mode_input.change(
286
- update_on_mode,
287
- inputs=mode_input,
288
- outputs=[req_type_input, name_input, date_input]
289
- )
290
-
291
- # Initial load defaults
292
- iface.load(
293
- update_on_mode,
294
- inputs=mode_input,
295
- outputs=[req_type_input, name_input, date_input]
296
- )
297
-
298
- # Fetch
299
- fetch_btn.click(
300
- fetch_data,
301
- inputs=[mode_input, req_type_input, name_input, date_input],
302
- outputs=output
303
- )
304
-
305
-
306
- # ======================================================
307
- # Launch
308
- # ======================================================
309
- if __name__ == "__main__":
310
- iface.launch(server_name="0.0.0.0", server_port=7860)
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from pydantic import BaseModel
4
+ from typing import Optional
5
 
6
+ # Existing modules
7
  import common
8
  import stock
9
  import indices_html
 
14
  import nsepython
15
  import yahooinfo
16
  import build_nse_fno
 
 
 
 
17
 
18
  app = FastAPI(title="Stock Backend")
19
 
 
25
  allow_headers=["*"],
26
  )
27
 
28
+ # ---------- Request Model ----------
29
  class FetchRequest(BaseModel):
30
+ req_type: str # From STOCK_REQ or INDEX_REQ
31
  name: str
32
+ date_start: str # dd-mm-yyyy
33
+ date_end: str # dd-mm-yyyy
 
 
 
 
 
34
 
35
+ # ---------- STOCK Handlers ----------
36
  def stock_info(req: FetchRequest):
37
+ return common.wrap(yahooinfo.fetch_info(req.name))
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
  def stock_intraday(req: FetchRequest):
40
+ return common.wrap(stock.fetch_intraday(req.name, req.date_start, req.date_end))
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
  def stock_daily(req: FetchRequest):
43
+ return common.wrap(stock.fetch_daily(req.name, req.date_start, req.date_end))
44
+
45
+ def stock_nse_eq(req: FetchRequest):
46
+ return eq_html.build_eq_html(req.name)
47
+
48
+ def stock_qresult(req: FetchRequest):
49
+ return common.wrap(stock.fetch_qresult(req.name))
50
+
51
+ def stock_result(req: FetchRequest):
52
+ return common.wrap(stock.fetch_result(req.name))
53
+
54
+ def stock_balance(req: FetchRequest):
55
+ return common.wrap(stock.fetch_balance(req.name))
56
+
57
+ def stock_cashflow(req: FetchRequest):
58
+ return common.wrap(stock.fetch_cashflow(req.name))
59
+
60
+ def stock_dividend(req: FetchRequest):
61
+ return common.wrap(stock.fetch_dividend(req.name))
62
+
63
+ def stock_split(req: FetchRequest):
64
+ return common.wrap(stock.fetch_split(req.name))
65
+
66
+ def stock_other(req: FetchRequest):
67
+ return common.wrap(stock.fetch_other(req.name))
68
+
69
+ def stock_hist(req: FetchRequest):
70
+ return nsepython.nse_stock_hist(req.date_start, req.date_end, req.name).to_html()
71
+
72
+
73
+ # ---------- INDEX Handlers ----------
74
+ def index_indices(req: FetchRequest):
75
+ return indices_html.build_indices_html()
76
+
77
+ def index_nse_open(req: FetchRequest):
78
+ return index_live_html.build_index_live_html()
79
+
80
+ def index_nse_preopen(req: FetchRequest):
81
+ return preopen_html.build_preopen_html()
82
+
83
+ def index_nse_fno(req: FetchRequest):
84
+ return build_nse_fno.nse_fno_html(req.date_end, req.name)
85
+
86
+ def index_nse_fiidii(req: FetchRequest):
87
+ return nsepython.nse_fiidii().to_html()
88
+
89
+ def index_nse_events(req: FetchRequest):
90
+ return nsepython.nse_events().to_html()
91
+
92
+ def index_nse_future(req: FetchRequest):
93
+ return common.wrap(nsepython.nse_future(req.name))
94
+
95
+ def index_nse_bhav(req: FetchRequest):
96
+ return bhavcopy_html.build_bhavcopy_html(req.date_end)
97
+
98
+ def index_nse_highlow(req: FetchRequest):
99
+ return nsepython.nse_highlow(req.date_end).to_html()
100
+
101
+ def index_stock_highlow(req: FetchRequest):
102
+ return nsepython.stock_highlow(req.date_end).to_html()
103
+
104
+ def index_history(req: FetchRequest):
105
+ return nsepython.index_history("NIFTY", req.date_start, req.date_end).to_html()
106
+
107
+ def index_nse_largedeals(req: FetchRequest):
108
+ return nsepython.nse_largedeals().to_html()
109
+
110
+ def index_nse_most_active(req: FetchRequest):
111
+ return nsepython.nse_most_active().to_html()
112
+
113
+ def index_largedeals_historical(req: FetchRequest):
114
+ return nsepython.nse_largedeals_historical(req.date_start, req.date_end).to_html()
115
+
116
+ def index_nse_bulkdeals(req: FetchRequest):
117
+ return nsepython.nse_bulkdeals().to_html()
118
+
119
+ def index_nse_blockdeals(req: FetchRequest):
120
+ return nsepython.nse_blockdeals().to_html()
121
+
122
+ def index_pe_pb_div(req: FetchRequest):
123
+ return nsepython.index_pe_pb_div("NIFTY", req.date_start, req.date_end).to_html()
124
+
125
+ def index_total_returns(req: FetchRequest):
126
+ return nsepython.index_total_returns("NIFTY", req.date_start, req.date_end).to_html()
127
+
128
+
129
+ # ---------- ROUTER MAPPING ----------
130
+ ROUTER = {
131
+ # STOCK
132
+ "info": stock_info,
133
+ "intraday": stock_intraday,
134
+ "daily": stock_daily,
135
+ "nse_eq": stock_nse_eq,
136
+ "qresult": stock_qresult,
137
+ "result": stock_result,
138
+ "balance": stock_balance,
139
+ "cashflow": stock_cashflow,
140
+ "dividend": stock_dividend,
141
+ "split": stock_split,
142
+ "other": stock_other,
143
+ "stock_hist": stock_hist,
144
+
145
+ # INDEX
146
+ "indices": index_indices,
147
+ "nse_open": index_nse_open,
148
+ "nse_preopen": index_nse_preopen,
149
+ "nse_fno": index_nse_fno,
150
+ "nse_fiidii": index_nse_fiidii,
151
+ "nse_events": index_nse_events,
152
+ "nse_future": index_nse_future,
153
+ "nse_bhav": index_nse_bhav,
154
+ "nse_highlow": index_nse_highlow,
155
+ "stock_highlow": index_stock_highlow,
156
+ "index_history": index_history,
157
+ "nse_largedeals": index_nse_largedeals,
158
+ "nse_most_active": index_nse_most_active,
159
+ "largedeals_historical": index_largedeals_historical,
160
+ "nse_bulkdeals": index_nse_bulkdeals,
161
+ "nse_blockdeals": index_nse_blockdeals,
162
+ "index_pe_pb_div": index_pe_pb_div,
163
+ "index_total_returns": index_total_returns
164
  }
165
 
166
  # ---------- MAIN ENDPOINT ----------
167
  @app.post("/api/fetch")
168
  def fetch_data(req: FetchRequest):
 
169
  handler = ROUTER.get(req.req_type)
 
170
  if not handler:
171
+ raise HTTPException(status_code=400, detail=f"Unsupported req_type: {req.req_type}")
172
+ try:
173
+ html_content = handler(req)
174
+ return {
175
+ "success": True,
176
+ "req_type": req.req_type,
177
+ "name": req.name,
178
+ "date_start": req.date_start,
179
+ "date_end": req.date_end,
180
+ "html": html_content
181
+ }
182
+ except Exception as e:
183
+ raise HTTPException(status_code=500, detail=str(e))