Commit Β·
2553be8
1
Parent(s): b6cd7a1
financial news app
Browse files
app.py
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import requests
|
| 2 |
+
import gradio as gr
|
| 3 |
+
from langchain_core.tools import tool
|
| 4 |
+
from typing import Annotated, Optional
|
| 5 |
+
|
| 6 |
+
FINANCIAL_DATASETS_API_BASE = "https://api.financialdatasets.ai"
|
| 7 |
+
|
| 8 |
+
STATEMENT_TYPE_KEY_MAP = {
|
| 9 |
+
"income-statements": "income_statements",
|
| 10 |
+
"balance-sheets": "balance_sheets",
|
| 11 |
+
"cash-flow-statements": "cash_flow_statements"
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
# --- LangChain Tool ---
|
| 15 |
+
@tool
|
| 16 |
+
def get_financial_statements(
|
| 17 |
+
ticker: Annotated[str, "e.g. AAPL"],
|
| 18 |
+
report_period_lte: Annotated[str, "End date (YYYY-MM-DD)"],
|
| 19 |
+
report_period_gte: Annotated[str, "Start date (YYYY-MM-DD)"],
|
| 20 |
+
statement_type: Annotated[Optional[str], "income-statements, balance-sheets, cash-flow-statements, or 'all'"] = None,
|
| 21 |
+
period: Annotated[str, "annual, quarterly, or ttm"] = "annual",
|
| 22 |
+
limit: Annotated[int, "1-10 records"] = 4,
|
| 23 |
+
api_key: Annotated[str, "Your FinancialDatasets API Key"] = ""
|
| 24 |
+
) -> str:
|
| 25 |
+
"""Fetch financial statements."""
|
| 26 |
+
if not api_key:
|
| 27 |
+
return "β Error: API key is required."
|
| 28 |
+
|
| 29 |
+
headers = {"X-API-KEY": api_key}
|
| 30 |
+
|
| 31 |
+
if not statement_type or statement_type == "all":
|
| 32 |
+
url = (
|
| 33 |
+
f"{FINANCIAL_DATASETS_API_BASE}/financials"
|
| 34 |
+
f"?ticker={ticker}&period={period}&limit={limit}"
|
| 35 |
+
f"&report_period_lte={report_period_lte}&report_period_gte={report_period_gte}"
|
| 36 |
+
)
|
| 37 |
+
response = requests.get(url, headers=headers)
|
| 38 |
+
if response.status_code != 200:
|
| 39 |
+
return f"β API Error: {response.status_code} - {response.text}"
|
| 40 |
+
return response.text
|
| 41 |
+
|
| 42 |
+
json_key = STATEMENT_TYPE_KEY_MAP.get(statement_type)
|
| 43 |
+
if not json_key:
|
| 44 |
+
return f"β Invalid statement_type: must be one of {list(STATEMENT_TYPE_KEY_MAP.keys())}"
|
| 45 |
+
|
| 46 |
+
url = (
|
| 47 |
+
f"{FINANCIAL_DATASETS_API_BASE}/financials/{statement_type}"
|
| 48 |
+
f"?ticker={ticker}&period={period}&limit={limit}"
|
| 49 |
+
f"&report_period_lte={report_period_lte}&report_period_gte={report_period_gte}"
|
| 50 |
+
)
|
| 51 |
+
response = requests.get(url, headers=headers)
|
| 52 |
+
if response.status_code != 200:
|
| 53 |
+
return f"β API Error: {response.status_code} - {response.text}"
|
| 54 |
+
return response.text
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
# --- Wrapper for Gradio ---
|
| 58 |
+
def run_financial_statements(
|
| 59 |
+
ticker, report_period_gte, report_period_lte,
|
| 60 |
+
statement_type, period, limit, api_key
|
| 61 |
+
):
|
| 62 |
+
result = get_financial_statements.invoke({
|
| 63 |
+
"ticker": ticker.strip(),
|
| 64 |
+
"report_period_gte": report_period_gte,
|
| 65 |
+
"report_period_lte": report_period_lte,
|
| 66 |
+
"statement_type": statement_type,
|
| 67 |
+
"period": period,
|
| 68 |
+
"limit": int(limit),
|
| 69 |
+
"api_key": api_key.strip()
|
| 70 |
+
})
|
| 71 |
+
return result
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
# --- Gradio UI ---
|
| 75 |
+
with gr.Blocks(theme=gr.themes.Soft(), css=".gr-button { font-size: 16px }") as demo:
|
| 76 |
+
gr.Markdown("# π Financial Assistant\nUse this tool to explore company financial statements.")
|
| 77 |
+
|
| 78 |
+
with gr.Row():
|
| 79 |
+
with gr.Column(scale=1):
|
| 80 |
+
gr.Markdown("### π Query Inputs")
|
| 81 |
+
ticker = gr.Textbox(label="Ticker Symbol", placeholder="e.g. AAPL")
|
| 82 |
+
report_gte = gr.Textbox(label="Start Date (YYYY-MM-DD)", value="2020-01-01")
|
| 83 |
+
report_lte = gr.Textbox(label="End Date (YYYY-MM-DD)", value="2024-12-31")
|
| 84 |
+
statement_type = gr.Dropdown(
|
| 85 |
+
["all", "income-statements", "balance-sheets", "cash-flow-statements"],
|
| 86 |
+
label="Statement Type", value="all"
|
| 87 |
+
)
|
| 88 |
+
period = gr.Radio(["annual", "quarterly", "ttm"], label="Period", value="annual")
|
| 89 |
+
limit = gr.Slider(1, 10, value=4, step=1, label="Limit")
|
| 90 |
+
api_key = gr.Textbox(label="API Key", type="password", placeholder="Paste your API key")
|
| 91 |
+
|
| 92 |
+
submit = gr.Button("π Get Financials", variant="primary")
|
| 93 |
+
|
| 94 |
+
with gr.Column(scale=1):
|
| 95 |
+
gr.Markdown("### π Output")
|
| 96 |
+
output = gr.Code(label="JSON Result", language="json")
|
| 97 |
+
|
| 98 |
+
# Hook
|
| 99 |
+
submit.click(
|
| 100 |
+
fn=run_financial_statements,
|
| 101 |
+
inputs=[ticker, report_gte, report_lte, statement_type, period, limit, api_key],
|
| 102 |
+
outputs=output
|
| 103 |
+
)
|
| 104 |
+
|
| 105 |
+
# Footer
|
| 106 |
+
gr.Markdown("---")
|
| 107 |
+
gr.Markdown("Built with β€οΈ using [LangChain](https://www.langchain.com) and [FinancialDatasets.ai](https://financialdatasets.ai)")
|
| 108 |
+
|
| 109 |
+
# Run it
|
| 110 |
+
if __name__ == "__main__":
|
| 111 |
+
demo.launch(mcp_server=True)
|