eshan6704 commited on
Commit
7eee327
·
verified ·
1 Parent(s): 04b70dc

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +297 -0
app.py ADDED
@@ -0,0 +1,297 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from stock import *
3
+ from indices_html import *
4
+ from index_live_html import *
5
+ from preopen_html import *
6
+ from eq_html import *
7
+ import pandas as pd
8
+ from bhavcopy_html import *
9
+ from nsepython import *
10
+ from yahooinfo import fetch_info
11
+ import datetime
12
+ from io import BytesIO
13
+ from datetime import datetime
14
+ import boto3
15
+ import os
16
+
17
+ # ======================================================
18
+ # Backblaze B2 Setup
19
+ # ======================================================
20
+ S3_ENDPOINT = "https://s3.us-east-005.backblazeb2.com"
21
+ BUCKET_NAME = "eshanhf"
22
+ AWS_KEY_ID = "005239ca03b31af0000000001"
23
+ AWS_SECRET_KEY = "K005uGFZkrtYa4Hg1GliFUQohs/BTk4"
24
+
25
+ s3 = boto3.client(
26
+ "s3",
27
+ endpoint_url=S3_ENDPOINT,
28
+ aws_access_key_id=AWS_KEY_ID,
29
+ aws_secret_access_key=AWS_SECRET_KEY,
30
+ )
31
+
32
+ LOG_FILE = "fetch_log.csv" # CSV log in bucket
33
+
34
+ def b2_file(file_path=None, bucket_name=BUCKET_NAME, upload=True, download_path=None):
35
+ """
36
+ Universal upload/download function for Backblaze B2.
37
+ """
38
+ try:
39
+ if upload:
40
+ if not file_path or not os.path.isfile(file_path):
41
+ raise ValueError("Valid local file_path must be provided for upload")
42
+
43
+ with open(file_path, "rb") as f:
44
+ data = f.read()
45
+
46
+ file_name = os.path.basename(file_path)
47
+ s3.put_object(Bucket=bucket_name, Key=file_name, Body=data)
48
+ return True
49
+
50
+ else:
51
+ if not file_path:
52
+ raise ValueError("Bucket file name must be provided for download")
53
+ if not download_path:
54
+ raise ValueError("download_path must be provided for download")
55
+
56
+ obj = s3.get_object(Bucket=bucket_name, Key=file_path)
57
+ data = obj['Body'].read()
58
+
59
+ with open(download_path, "wb") as f:
60
+ f.write(data)
61
+
62
+ return True
63
+
64
+ except Exception as e:
65
+ print(f"Error in B2 operation: {e}")
66
+ return False
67
+
68
+ def log_fetch(client, mode, req_type, name, date_str):
69
+ """
70
+ Append a new fetch record to the CSV in B2.
71
+ """
72
+ try:
73
+ # Try to read existing CSV from B2
74
+ try:
75
+ obj = s3.get_object(Bucket=BUCKET_NAME, Key=LOG_FILE)
76
+ data = obj['Body'].read()
77
+ df = pd.read_csv(BytesIO(data))
78
+ except Exception:
79
+ df = pd.DataFrame(columns=["Sr", "Datetime", "Client", "Mode", "Req_Type", "Name", "Date"])
80
+
81
+ # Append new row
82
+ new_row = {
83
+ "Sr": len(df) + 1,
84
+ "Datetime": datetime.now().strftime("%d-%m-%Y %H:%M:%S"),
85
+ "Client": client,
86
+ "Mode": mode,
87
+ "Req_Type": req_type,
88
+ "Name": name,
89
+ "Date": date_str
90
+ }
91
+ df = df.append(new_row, ignore_index=True)
92
+
93
+ # Save back to B2
94
+ csv_buffer = BytesIO()
95
+ df.to_csv(csv_buffer, index=False)
96
+ csv_buffer.seek(0)
97
+ s3.put_object(Bucket=BUCKET_NAME, Key=LOG_FILE, Body=csv_buffer.getvalue())
98
+ print("Fetch logged successfully.")
99
+ except Exception as e:
100
+ print(f"Error logging fetch: {e}")
101
+
102
+ # ======================================================
103
+ # Scrollable HTML wrapper
104
+ # ======================================================
105
+ SCROLL_WRAP = """
106
+ <div style="
107
+ max-height: 80vh;
108
+ overflow-y: auto;
109
+ overflow-x: auto;
110
+ padding: 10px;
111
+ border: 1px solid #ccc;
112
+ border-radius: 6px;
113
+ ">
114
+ {{HTML}}
115
+ </div>
116
+ """
117
+
118
+ # ======================================================
119
+ # Date helpers
120
+ # ======================================================
121
+ def today_str():
122
+ return datetime.date.today().strftime("%d-%m-%Y")
123
+
124
+ def yesterday_str():
125
+ return (datetime.date.today() - datetime.timedelta(days=1)).strftime("%d-%m-%Y")
126
+
127
+ def last_year_date(d):
128
+ dt = datetime.datetime.strptime(d, "%d-%m-%Y")
129
+ new_dt = dt.replace(year=dt.year - 1)
130
+ return new_dt.strftime("%d-%m-%Y")
131
+
132
+ # ======================================================
133
+ # HTML wrapper
134
+ # ======================================================
135
+ def wrap(html):
136
+ if html is None:
137
+ return "<h3>No Data</h3>"
138
+ return SCROLL_WRAP.replace("{{HTML}}", html)
139
+
140
+ # ======================================================
141
+ # Request Type Options
142
+ # ======================================================
143
+ STOCK_REQ = [
144
+ "info", "intraday", "daily", "nse_eq", "qresult", "result",
145
+ "balance", "cashflow", "dividend", "split", "other", "stock_hist"
146
+ ]
147
+
148
+ INDEX_REQ = [
149
+ "indices", "nse_open", "nse_preopen", "nse_fno", "nse_fiidii",
150
+ "nse_events", "nse_future", "nse_bhav", "nse_highlow",
151
+ "index_history", "nse_largedeals", "nse_most_active",
152
+ "largedeals_historical", "nse_bulkdeals", "nse_blockdeals",
153
+ "index_pe_pb_div", "index_total_returns"
154
+ ]
155
+
156
+ # ======================================================
157
+ # Update UI based on mode
158
+ # ======================================================
159
+ def update_on_mode(mode):
160
+ if mode == "stock":
161
+ return (
162
+ gr.update(choices=STOCK_REQ, value="info"),
163
+ gr.update(value="ITC"),
164
+ gr.update(value=yesterday_str())
165
+ )
166
+ elif mode == "index":
167
+ return (
168
+ gr.update(choices=INDEX_REQ, value="indices"),
169
+ gr.update(value="NIFTY 50"),
170
+ gr.update(value=yesterday_str())
171
+ )
172
+ return (
173
+ gr.update(choices=[], value=""),
174
+ gr.update(value=""),
175
+ gr.update(value="")
176
+ )
177
+
178
+ # ======================================================
179
+ # Data Fetcher
180
+ # ======================================================
181
+ def fetch_data(mode, req_type, name, date_str):
182
+ req_type = req_type.lower()
183
+ name = name.strip()
184
+ date_str = date_str.strip() or yesterday_str()
185
+ date_start = last_year_date(date_str)
186
+
187
+ # Detect client
188
+ client = "gradio"
189
+
190
+ # =====================
191
+ # INDEX MODE
192
+ # =====================
193
+ if mode == "index":
194
+ if req_type == "indices":
195
+ result = build_indices_html()
196
+ elif req_type == "nse_open":
197
+ result = build_index_live_html()
198
+ elif req_type == "nse_preopen":
199
+ result = build_preopen_html()
200
+ elif req_type == "nse_fno":
201
+ result = wrap(nse_fno(name))
202
+ elif req_type == "nse_events":
203
+ result = nse_events().to_html()
204
+ elif req_type == "nse_fiidii":
205
+ result = nse_fiidii().to_html()
206
+ elif req_type == "nse_future":
207
+ result = wrap(nse_future(name))
208
+ elif req_type == "nse_highlow":
209
+ result = wrap(nse_highlow())
210
+ elif req_type == "nse_bhav":
211
+ result = build_bhavcopy_html(date_str)
212
+ elif req_type == "nse_largedeals":
213
+ result = nse_largedeals().to_html()
214
+ elif req_type == "nse_bulkdeals":
215
+ result = nse_bulkdeals().to_html()
216
+ elif req_type == "nse_blockdeals":
217
+ result = nse_blockdeals().to_html()
218
+ elif req_type == "nse_most_active":
219
+ result = nse_most_active().to_html()
220
+ elif req_type == "index_history":
221
+ result = index_history("NIFTY 50", date_start, date_str).to_html()
222
+ elif req_type == "largedeals_historical":
223
+ result = nse_largedeals_historical(date_start, date_str).to_html()
224
+ elif req_type == "index_pe_pb_div":
225
+ result = index_pe_pb_div("NIFTY 50", date_start, date_str).to_html()
226
+ elif req_type == "index_total_returns":
227
+ result = index_total_returns("NIFTY 50", date_start, date_str).to_html()
228
+ else:
229
+ result = wrap(f"<h3>No handler for {req_type}</h3>")
230
+
231
+ # =====================
232
+ # STOCK MODE
233
+ # =====================
234
+ elif mode == "stock":
235
+ if req_type == "daily":
236
+ result = wrap(fetch_daily(name))
237
+ elif req_type == "nse_eq":
238
+ result = build_eq_html(name)
239
+ elif req_type == "intraday":
240
+ result = wrap(fetch_intraday(name))
241
+ elif req_type == "info":
242
+ result = wrap(fetch_info(name))
243
+ elif req_type == "qresult":
244
+ result = wrap(fetch_qresult(name))
245
+ elif req_type == "result":
246
+ result = wrap(fetch_result(name))
247
+ elif req_type == "balance":
248
+ result = wrap(fetch_balance(name))
249
+ elif req_type == "cashflow":
250
+ result = wrap(fetch_cashflow(name))
251
+ elif req_type == "dividend":
252
+ result = wrap(fetch_dividend(name))
253
+ elif req_type == "split":
254
+ result = wrap(fetch_split(name))
255
+ elif req_type == "other":
256
+ result = wrap(fetch_other(name))
257
+ elif req_type == "stock_hist":
258
+ result = nse_stock_hist(date_start, date_str, name).to_html()
259
+ else:
260
+ result = wrap(f"<h3>No handler for {req_type}</h3>")
261
+
262
+ else:
263
+ result = wrap(f"<h3>No valid mode: {mode}</h3>")
264
+
265
+ # =====================
266
+ # Log fetch in CSV
267
+ # =====================
268
+ log_fetch(client, mode, req_type, name, date_str)
269
+ return result
270
+
271
+ # ======================================================
272
+ # UI
273
+ # ======================================================
274
+ with gr.Blocks(title="Stock / Index App") as iface:
275
+ gr.Markdown("### **Stock / Index Data Fetcher**")
276
+
277
+ with gr.Row():
278
+ mode_input = gr.Radio(["stock", "index"], label="Mode", value="stock", scale=1)
279
+ name_input = gr.Textbox(label="Symbol / Index Name", scale=2)
280
+ req_type_input = gr.Dropdown(label="Request Type", allow_custom_value=True, scale=2)
281
+ date_input = gr.Textbox(label="Date (DD-MM-YYYY)", placeholder="Leave empty = yesterday", scale=1)
282
+ fetch_btn = gr.Button("Fetch", scale=1)
283
+
284
+ output = gr.HTML(label="Output")
285
+
286
+ # Mode change → auto defaults
287
+ mode_input.change(update_on_mode, inputs=mode_input, outputs=[req_type_input, name_input, date_input])
288
+ iface.load(update_on_mode, inputs=mode_input, outputs=[req_type_input, name_input, date_input])
289
+
290
+ # Fetch
291
+ fetch_btn.click(fetch_data, inputs=[mode_input, req_type_input, name_input, date_input], outputs=output)
292
+
293
+ # ======================================================
294
+ # Launch
295
+ # ======================================================
296
+ if __name__ == "__main__":
297
+ iface.launch(server_name="0.0.0.0", server_port=7860)