mindate / app.py
Subham9126's picture
WITH LOGS
fda112c verified
Raw
History Blame Contribute Delete
6.63 kB
import gradio as gr
import requests
import json
from datetime import datetime
import pytz
def validate_date_format(date_str):
"""Validate if the date is in dd-mm-yyyy format"""
try:
datetime.strptime(date_str, "%d-%m-%Y")
return True
except ValueError:
return False
def convert_to_unix_millis(date_str, time_str):
"""Convert dd-mm-yyyy date and time to Unix timestamp in milliseconds (IST)"""
ist = pytz.timezone('Asia/Kolkata')
datetime_str = f"{date_str} {time_str}"
dt = datetime.strptime(datetime_str, "%d-%m-%Y %H:%M")
dt_ist = ist.localize(dt)
return int(dt_ist.timestamp() * 1000)
def epoch_to_ist_time(epoch_seconds):
"""Convert epoch timestamp (seconds) to IST time string (HH:MM:SS)"""
ist = pytz.timezone('Asia/Kolkata')
dt = datetime.fromtimestamp(epoch_seconds, tz=pytz.UTC)
dt_ist = dt.astimezone(ist)
return dt_ist.strftime("%H:%M:%S")
def fetch_stock_data(ticker, date):
"""Fetch stock data from Groww API and return simplified JSON"""
debug_log = []
# Validate date format
debug_log.append(f"[DEBUG] Input - Ticker: {ticker}, Date: {date}")
if not validate_date_format(date):
return "Error: Please enter date in dd-mm-yyyy format"
# Validate ticker
if not ticker or ticker.strip() == "":
return "Error: Please enter a valid ticker symbol"
ticker = ticker.strip().upper()
debug_log.append(f"[DEBUG] Cleaned Ticker: {ticker}")
try:
# Calculate start and end timestamps
start_millis = convert_to_unix_millis(date, "00:05")
end_millis = convert_to_unix_millis(date, "23:55")
debug_log.append(f"[DEBUG] Start Time (IST 00:05): {start_millis} ms")
debug_log.append(f"[DEBUG] End Time (IST 23:55): {end_millis} ms")
# Construct API URL
url = f"https://groww.in/v1/api/charting_service/v4/chart/exchange/NSE/segment/CASH/{ticker}"
params = {
"endTimeInMillis": end_millis,
"intervalInMinutes": 1,
"startTimeInMillis": start_millis
}
# Full URL with parameters
full_url = f"{url}?endTimeInMillis={end_millis}&intervalInMinutes=1&startTimeInMillis={start_millis}"
debug_log.append(f"[DEBUG] Full API URL: {full_url}")
# Make API request
debug_log.append("[DEBUG] Making API request...")
response = requests.get(url, params=params, timeout=10)
debug_log.append(f"[DEBUG] Response Status Code: {response.status_code}")
debug_log.append(f"[DEBUG] Response Headers: {dict(response.headers)}")
# Check if request was successful
if response.status_code != 200:
debug_log.append(f"[DEBUG] Response Body: {response.text[:500]}")
return "\n".join(debug_log) + "\n\n[ERROR] Invalid ticker or no data available for the given date."
debug_log.append(f"[DEBUG] Response Content Length: {len(response.text)} bytes")
data = response.json()
debug_log.append(f"[DEBUG] Response JSON Keys: {list(data.keys())}")
# Check if candles data exists
if "candles" not in data or not data["candles"]:
debug_log.append("[DEBUG] No 'candles' key found or candles array is empty")
debug_log.append(f"[DEBUG] Full Response: {json.dumps(data, indent=2)[:1000]}")
return "\n".join(debug_log) + "\n\n[ERROR] Invalid ticker or no data available for the given date."
debug_log.append(f"[DEBUG] Number of candles received: {len(data['candles'])}")
debug_log.append(f"[DEBUG] First candle sample: {data['candles'][0]}")
debug_log.append(f"[DEBUG] Last candle sample: {data['candles'][-1]}")
# Process candles data
simplified_data = []
for candle in data["candles"]:
epoch_seconds = candle[0]
opening_price = candle[1]
time_ist = epoch_to_ist_time(epoch_seconds)
simplified_data.append({
"time": time_ist,
"open": opening_price
})
debug_log.append(f"[DEBUG] Successfully processed {len(simplified_data)} candles")
debug_log.append("\n" + "="*50 + "\n[SUCCESS] DATA OUTPUT:\n" + "="*50 + "\n")
# Return debug log + JSON string
return "\n".join(debug_log) + "\n" + json.dumps(simplified_data, indent=2)
except requests.exceptions.Timeout:
debug_log.append("[DEBUG] Request timed out")
return "\n".join(debug_log) + "\n\n[ERROR] Request timed out. Please try again."
except requests.exceptions.RequestException as e:
debug_log.append(f"[DEBUG] Request Exception: {type(e).__name__} - {str(e)}")
return "\n".join(debug_log) + "\n\n[ERROR] Invalid ticker or no data available for the given date."
except Exception as e:
debug_log.append(f"[DEBUG] Unexpected Exception: {type(e).__name__} - {str(e)}")
import traceback
debug_log.append(f"[DEBUG] Traceback:\n{traceback.format_exc()}")
return "\n".join(debug_log) + "\n\n[ERROR] An unexpected error occurred"
# Create Gradio interface
with gr.Blocks(title="Groww Stock Data Fetcher") as app:
gr.Markdown("# Groww Stock Data Fetcher")
gr.Markdown("Fetch intraday 1-minute candle data for NSE stocks")
with gr.Row():
with gr.Column():
ticker_input = gr.Textbox(
label="Ticker / Symbol",
placeholder="e.g., RELIANCE, TCS, HDFCBANK",
lines=1
)
date_input = gr.Textbox(
label="Date (dd-mm-yyyy)",
placeholder="e.g., 05-11-2025",
lines=1
)
submit_btn = gr.Button("Submit", variant="primary")
with gr.Row():
output = gr.Textbox(
label="Output",
lines=20,
max_lines=30,
show_copy_button=True
)
submit_btn.click(
fn=fetch_stock_data,
inputs=[ticker_input, date_input],
outputs=output
)
gr.Markdown("### Instructions")
gr.Markdown("""
1. Enter a valid NSE stock ticker (e.g., RELIANCE, TCS, HDFCBANK)
2. Enter the date in **dd-mm-yyyy** format (e.g., 05-11-2025)
3. Click Submit to fetch the data
4. The output will show timestamp (IST) and opening price for each 1-minute candle
""")
# Launch the app
if __name__ == "__main__":
app.launch()