"""SEC filings — recent 10-K, 10-Q, 8-K and other forms with direct links.""" import pandas as pd import streamlit as st from services.fmp_service import get_sec_filings _FORM_DESCRIPTIONS = { "10-K": "Annual report", "10-Q": "Quarterly report", "8-K": "Material event disclosure", "DEF 14A": "Proxy statement", "S-1": "IPO registration", "S-3": "Securities registration", "4": "Insider ownership change", "SC 13G": "Beneficial ownership (passive)", "SC 13D": "Beneficial ownership (active)", } _FORM_COLORS = { "10-K": "rgba(79,142,247,0.15)", "10-Q": "rgba(130,224,170,0.15)", "8-K": "rgba(247,162,79,0.15)", } def _describe_form(form_type: str) -> str: return _FORM_DESCRIPTIONS.get(form_type.strip().upper(), "") def render_filings(ticker: str): with st.spinner("Loading SEC filings…"): raw = get_sec_filings(ticker) if not raw: st.info("No SEC filing data available. Requires FMP API key.") return # Collect unique form types for filter form_types = sorted({str(r.get("type") or r.get("form") or "").strip() for r in raw if r.get("type") or r.get("form")}) filter_options = ["All"] + [t for t in ["10-K", "10-Q", "8-K"] if t in form_types] + \ [t for t in form_types if t not in ("10-K", "10-Q", "8-K")] filter_col, _ = st.columns([1, 3]) with filter_col: selected_type = st.selectbox("Form type", options=filter_options, index=0, key="filings_filter") # Summary counts counts = {} for r in raw: ft = str(r.get("type") or r.get("form") or "Other").strip() counts[ft] = counts.get(ft, 0) + 1 priority_forms = ["10-K", "10-Q", "8-K"] summary_forms = [f for f in priority_forms if f in counts] if summary_forms: cols = st.columns(len(summary_forms)) for col, ft in zip(cols, summary_forms): col.metric(ft, counts[ft]) st.write("") # Filter if selected_type == "All": filtered = raw else: filtered = [ r for r in raw if str(r.get("type") or r.get("form") or "").strip() == selected_type ] if not filtered: st.info("No filings match the current filter.") return # Build display table rows = [] for item in filtered: form_type = str(item.get("type") or item.get("form") or "—").strip() date = str(item.get("filingDate") or item.get("date") or "")[:10] description = item.get("description") or _describe_form(form_type) or "—" url = item.get("link") or item.get("finalLink") or item.get("url") or "" rows.append({ "Date": date, "Form": form_type, "Description": description, "Link": url, }) df = pd.DataFrame(rows) # Render as clickable table — Streamlit doesn't natively support link columns, # so we render each row as a compact card for the most recent 30 entries. for _, row in df.head(30).iterrows(): form = row["Form"] color = _FORM_COLORS.get(form, "rgba(255,255,255,0.05)") date = row["Date"] desc = row["Description"] link = row["Link"] with st.container(): left, right = st.columns([5, 1]) with left: st.markdown( f"
" f"{form}  ·  {date}
" f"{desc}" f"
", unsafe_allow_html=True, ) with right: if link: st.markdown( f"
🔗 View
", unsafe_allow_html=True, )