import gradio as gr import yfinance as yf import plotly.graph_objs as go import pandas as pd STYLE_BLOCK = """ """ def fetch_data(symbol, req_type): try: ticker = yf.Ticker(symbol) # Info block as cards + big boxes if req_type.lower() == "info": info = ticker.info if not info: return "

No info available

" long_summary = info.pop("longBusinessSummary", None) officers = info.pop("companyOfficers", None) cards = "".join( f"

{key}

{value}

" for key, value in info.items() ) extra_sections = "" if long_summary: extra_sections += f"

Business Summary

{long_summary}

" if officers: officer_rows = "".join( f"{o.get('name','')}{o.get('title','')}{o.get('age','')}" for o in officers ) officer_table = f"{officer_rows}
NameTitleAge
" extra_sections += f"

Company Officers

{officer_table}
" return f"{STYLE_BLOCK}{cards}{extra_sections}" # Daily chart elif req_type.lower() == "daily": df = yf.download(symbol, period="1y", interval="1d").round(2) if df.empty: return f"

No daily data for {symbol}

" if isinstance(df.columns, pd.MultiIndex): df.columns = df.columns.get_level_values(0) low_price = df["Low"].min() high_price = df["High"].max() price_range = high_price - low_price vol_band_min = low_price - (price_range / 5) vol_band_max = low_price vol_max = df["Volume"].max() vol_scale = (vol_band_max - vol_band_min) / vol_max if vol_max > 0 else 1 fig = go.Figure() fig.add_trace(go.Candlestick( x=df.index, open=df["Open"], high=df["High"], low=df["Low"], close=df["Close"], name="Price" )) fig.add_trace(go.Bar( x=df.index, y=df["Volume"] * vol_scale + vol_band_min, name="Volume", marker_color="lightblue", customdata=df["Volume"], hovertemplate="Volume: %{customdata}" )) fig.update_layout( xaxis_title="Date", yaxis_title="Price", yaxis=dict(range=[vol_band_min, high_price]), xaxis_rangeslider_visible=False, height=600 ) chart_html = fig.to_html(full_html=False) table_html = df.tail(30).to_html(classes="styled-table", border=0) return f"{chart_html}

Recent Daily Data (last 30 rows)

{STYLE_BLOCK}{table_html}" # Intraday chart elif req_type.lower() == "intraday": df = yf.download(symbol, period="1d", interval="5m").round(2) if df.empty: return f"

No intraday data for {symbol}

" if isinstance(df.columns, pd.MultiIndex): df.columns = df.columns.get_level_values(0) low_price = df["Low"].min() high_price = df["High"].max() price_range = high_price - low_price vol_band_min = low_price - (price_range / 5) vol_band_max = low_price vol_max = df["Volume"].max() vol_scale = (vol_band_max - vol_band_min) / vol_max if vol_max > 0 else 1 fig = go.Figure() fig.add_trace(go.Candlestick( x=df.index, open=df["Open"], high=df["High"], low=df["Low"], close=df["Close"], name="Price" )) fig.add_trace(go.Bar( x=df.index, y=df["Volume"] * vol_scale + vol_band_min, name="Volume", marker_color="orange", customdata=df["Volume"], hovertemplate="Volume: %{customdata}" )) fig.update_layout( xaxis_title="Time", yaxis_title="Price", yaxis=dict(range=[vol_band_min, high_price]), xaxis_rangeslider_visible=False, height=600 ) chart_html = fig.to_html(full_html=False) table_html = df.tail(50).to_html(classes="styled-table", border=0) return f"{chart_html}

Recent Intraday Data (last 50 rows)

{STYLE_BLOCK}{table_html}" # Financial sections elif req_type.lower() == "qresult": df = ticker.quarterly_financials return f"

Quarterly Results

{STYLE_BLOCK}{df.to_html(classes='styled-table', border=0)}" if not df.empty else "

No quarterly results available

" elif req_type.lower() == "result": df = ticker.financials return f"

Annual Results

{STYLE_BLOCK}{df.to_html(classes='styled-table', border=0)}" if not df.empty else "

No annual results available

" elif req_type.lower() == "balance": df = ticker.balance_sheet return f"

Balance Sheet

{STYLE_BLOCK}{df.to_html(classes='styled-table', border=0)}" if not df.empty else "

No balance sheet available

" elif req_type.lower() == "cashflow": df = ticker.cashflow return f"

Cash Flow

{STYLE_BLOCK}{df.to_html(classes='styled-table', border=0)}" if not df.empty else "

No cashflow available

" elif req_type.lower() == "dividend": s = ticker.dividends return f"

Dividend History

{STYLE_BLOCK}{s.to_frame('Dividend').to_html(classes='styled-table', border=0)}" if not s.empty else "

No dividend history available

" elif req_type.lower() == "split": s = ticker.splits return f"

Split History

{STYLE_BLOCK}{s.to_frame('Split').to_html(classes='styled-table', border=0)}" if not s.empty else "

No split history available

" elif req_type.lower() == "other": df = ticker.earnings return f"

Earnings

{STYLE_BLOCK}{df.to_html(classes='styled-table', border=0)}" if not df.empty else "

No earnings data available

" else: return f"

No handler for {req_type}

" except Exception as e: return f"

Error

{str(e)}

" iface = gr.Interface( fn=fetch_data, inputs=[ gr.Textbox(label="Stock Symbol", value="PNB.NS"), gr.Dropdown( label="Request Type", choices=[ "info", "intraday", "daily", "qresult", "result", "balance", "cashflow", "dividend", "split", "other" ], value="info" ) ], outputs=gr.HTML(label="Full HTML Output"), title="Stock Data API (Full)", description="Fetch data from NSE and yfinance", api_name="fetch_data" ) if __name__ == "__main__": iface.launch(server_name="0.0.0.0", server_port=7860)