QuantumLearner commited on
Commit
70dc5cc
·
verified ·
1 Parent(s): c086145

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +257 -0
app.py ADDED
@@ -0,0 +1,257 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+ import pandas as pd
4
+ from datetime import date
5
+ import asyncio
6
+ import aiohttp
7
+
8
+ # Set wide layout
9
+ st.set_page_config(layout="wide")
10
+
11
+ # Global API key
12
+ API_KEY = os.getenv("FMP_API_KEY")
13
+
14
+ ########################################
15
+ # SYNCHRONOUS FUNCTION FOR LIVE FEED
16
+ ########################################
17
+
18
+ @st.cache_data(show_spinner=False)
19
+ def get_live_feed_data(limit, filing_type, from_date, to_date, is_done):
20
+ params = {
21
+ "apikey": API_KEY,
22
+ "limit": limit,
23
+ "from": from_date,
24
+ "to": to_date,
25
+ "isDone": str(is_done).lower()
26
+ }
27
+ if filing_type != "All":
28
+ params["type"] = filing_type
29
+ url = "https://financialmodelingprep.com/api/v4/rss_feed"
30
+ response = requests.get(url, params=params)
31
+ if response.status_code == 200:
32
+ return pd.DataFrame(response.json())
33
+ else:
34
+ st.error(f"Error fetching data (Status Code {response.status_code}).")
35
+ return pd.DataFrame()
36
+
37
+ ########################################
38
+ # ASYNCHRONOUS FUNCTIONS FOR 8-K FILINGS
39
+ ########################################
40
+
41
+ async def fetch_8k_page(session, page, from_date, to_date, has_financial):
42
+ params = {
43
+ "apikey": API_KEY,
44
+ "page": page,
45
+ "from": from_date,
46
+ "to": to_date,
47
+ "hasFinancial": str(has_financial).lower()
48
+ }
49
+ url = "https://financialmodelingprep.com/api/v4/rss_feed_8k"
50
+ async with session.get(url, params=params) as resp:
51
+ if resp.status == 200:
52
+ data = await resp.json()
53
+ return pd.DataFrame(data)
54
+ else:
55
+ return pd.DataFrame()
56
+
57
+ async def fetch_all_8k(pages_to_fetch, from_date, to_date, has_financial):
58
+ async with aiohttp.ClientSession() as session:
59
+ tasks = [fetch_8k_page(session, p, from_date, to_date, has_financial) for p in range(pages_to_fetch)]
60
+ results = []
61
+ progress_bar = st.progress(0)
62
+ completed = 0
63
+ for task in asyncio.as_completed(tasks):
64
+ result = await task
65
+ results.append(result)
66
+ completed += 1
67
+ progress_bar.progress(completed / pages_to_fetch)
68
+ return results
69
+
70
+ ########################################
71
+ # ASYNCHRONOUS FUNCTIONS FOR COMPANY FILINGS
72
+ ########################################
73
+
74
+ async def fetch_company_page(session, symbol, filing_type, page):
75
+ params = {
76
+ "apikey": API_KEY,
77
+ "page": page,
78
+ "type": filing_type
79
+ }
80
+ url = f"https://financialmodelingprep.com/api/v3/sec_filings/{symbol}"
81
+ async with session.get(url, params=params) as resp:
82
+ if resp.status == 200:
83
+ data = await resp.json()
84
+ return pd.DataFrame(data)
85
+ else:
86
+ return pd.DataFrame()
87
+
88
+ async def fetch_all_company(symbol, filing_type, pages_to_fetch):
89
+ async with aiohttp.ClientSession() as session:
90
+ tasks = [fetch_company_page(session, symbol, filing_type, p) for p in range(pages_to_fetch)]
91
+ results = []
92
+ progress_bar = st.progress(0)
93
+ completed = 0
94
+ for task in asyncio.as_completed(tasks):
95
+ result = await task
96
+ results.append(result)
97
+ completed += 1
98
+ progress_bar.progress(completed / pages_to_fetch)
99
+ return results
100
+
101
+ ########################################
102
+ # PAGE FUNCTIONS
103
+ ########################################
104
+
105
+ def live_feed_page():
106
+ st.title("Live SEC Filings Feed")
107
+ st.write(
108
+ """
109
+ This page displays a list of recent SEC filings by public companies.
110
+ Filings include annual reports (10-K), quarterly reports (10-Q), and other important updates.
111
+ Use the filters to narrow down the list by filing type, date range, and whether the filing is complete.
112
+ """
113
+ )
114
+
115
+ with st.sidebar:
116
+ with st.expander("Live Feed Filter Parameters", expanded=True):
117
+ filing_type = st.selectbox(
118
+ "Filing Type",
119
+ options=["All", "10-K", "10-Q", "8-K", "6-K"],
120
+ help="Choose a specific filing type or 'All' for no filtering."
121
+ )
122
+ from_date = st.date_input(
123
+ "From Date",
124
+ value=date(2025, 1, 1),
125
+ help="Start date for the filings."
126
+ )
127
+ to_date = st.date_input(
128
+ "To Date",
129
+ value=date.today(),
130
+ help="End date for the filings."
131
+ )
132
+ is_done = st.checkbox(
133
+ "Completed Filings Only",
134
+ value=True,
135
+ help="Check to show only filings marked as completed."
136
+ )
137
+ run_live = st.button("Run Live Feed Query")
138
+
139
+ # Fixed backend parameter: limit is set to 500
140
+ limit = 500
141
+
142
+ if run_live:
143
+ df = get_live_feed_data(limit, filing_type, from_date.isoformat(), to_date.isoformat(), is_done)
144
+ st.write("### Live SEC Filings Data")
145
+ st.dataframe(df, use_container_width=True)
146
+
147
+ def eight_k_page():
148
+ st.title("8-K Filings Specialized")
149
+ st.write(
150
+ """
151
+ This page displays 8-K filings from public companies.
152
+ 8-K filings are reports companies file when major events occur, like mergers, acquisitions, or leadership changes.
153
+ Use the filter below to show only filings that include financial information if you prefer.
154
+ """
155
+ )
156
+
157
+ with st.sidebar:
158
+ with st.expander("8-K Filter Parameters", expanded=True):
159
+ from_date = st.date_input(
160
+ "From Date (8-K)",
161
+ value=date(2025, 1, 1),
162
+ help="Start date for 8-K filings."
163
+ )
164
+ to_date = st.date_input(
165
+ "To Date (8-K)",
166
+ value=date.today(),
167
+ help="End date for 8-K filings."
168
+ )
169
+ has_financial_option = st.selectbox(
170
+ "Only Filings with Financial Data",
171
+ options=["True", "False"],
172
+ help="Select 'True' to display only filings that include financial statements."
173
+ )
174
+ has_financial = has_financial_option.lower() == "true"
175
+ run_8k = st.button("Run 8-K Query")
176
+
177
+ pages_to_fetch = 15 # Fixed number of pages to iterate over
178
+ if run_8k:
179
+ # Run async requests to fetch 8-K pages concurrently and update a progress bar.
180
+ results = asyncio.run(fetch_all_8k(pages_to_fetch, from_date.isoformat(), to_date.isoformat(), has_financial))
181
+ dfs = [df for df in results if not df.empty]
182
+ if dfs:
183
+ df_all = pd.concat(dfs, ignore_index=True)
184
+ st.write("### 8-K Filings Data")
185
+ st.dataframe(df_all, use_container_width=True)
186
+ else:
187
+ st.warning("No data returned for the given parameters.")
188
+
189
+ def company_specific_page():
190
+ st.title("Company Specific SEC Filings")
191
+ st.write(
192
+ """
193
+ This page displays filings for a specific company.
194
+ SEC filings are official documents companies file with the government.
195
+ Enter a company ticker (e.g., AAPL) and select a filing type (like 10-K or 10-Q) to view the reports.
196
+ """
197
+ )
198
+
199
+ with st.sidebar:
200
+ with st.expander("Company Filings Parameters", expanded=True):
201
+ symbol = st.text_input(
202
+ "Company Ticker",
203
+ value="AAPL",
204
+ help="Enter the ticker symbol of the company (e.g., AAPL)."
205
+ )
206
+ filing_type = st.selectbox(
207
+ "Filing Type",
208
+ options=["10-K", "10-Q", "8-K", "6-K"],
209
+ help="Select the type of filing to retrieve."
210
+ )
211
+ run_company = st.button("Run Company Query")
212
+
213
+ pages_to_fetch = 10 # Fixed number of pages to iterate over
214
+
215
+ if run_company:
216
+ if symbol.strip():
217
+ results = asyncio.run(fetch_all_company(symbol.upper(), filing_type, pages_to_fetch))
218
+ dfs = [df for df in results if not df.empty]
219
+ if dfs:
220
+ df_all = pd.concat(dfs, ignore_index=True)
221
+ st.write(f"### SEC Filings for {symbol.upper()}")
222
+ st.dataframe(df_all, use_container_width=True)
223
+ else:
224
+ st.warning("No filings found for the given parameters.")
225
+ else:
226
+ st.warning("Please enter a valid company ticker.")
227
+
228
+ ########################################
229
+ # MAIN APPLICATION
230
+ ########################################
231
+
232
+ def main():
233
+ st.sidebar.title("Input Parameters")
234
+ page_selection = st.sidebar.radio(
235
+ "Select a Page",
236
+ ("Live Feed", "8-K Specialized", "Company Specific"),
237
+ help="Navigate to the desired SEC filings page."
238
+ )
239
+
240
+ if page_selection == "Live Feed":
241
+ live_feed_page()
242
+ elif page_selection == "8-K Specialized":
243
+ eight_k_page()
244
+ elif page_selection == "Company Specific":
245
+ company_specific_page()
246
+
247
+ if __name__ == "__main__":
248
+ main()
249
+
250
+
251
+ hide_streamlit_style = """
252
+ <style>
253
+ #MainMenu {visibility: hidden;}
254
+ footer {visibility: hidden;}
255
+ </style>
256
+ """
257
+ st.markdown(hide_streamlit_style, unsafe_allow_html=True)