mirror of
https://github.com/shawnkim1997/All-in-one-Financial-Analysis.git
synced 2026-08-02 05:17:45 +00:00
d337c63976
Architecture (3,909-line monolith → 28 focused modules, all < 300 lines):
- config/: constants.py (company lists, row maps, Damodaran baselines), theme.py (CSS/HTML)
- utils/: prefs, formatting, ticker, dcf, charts, ui_helpers
- data/: sec_parser, sec_fetcher, sec_downloader, financials, fundamentals,
valuation, ratios, scores, scores_ai, market
- ai/: gemini_core, gemini_sec, gemini_insights
- views/: sidebar, tab1_quant, tab1_ai, tab1_filings, tab2_dcf,
tab3_comps, tab4_news, tab5_markets, tab6_crypto, tab7_technical
- app.py: thin orchestrator (~118 lines)
- Strict unidirectional dependency graph (no circular imports)
- All @st.cache_data TTLs and st.session_state keys preserved identically
SEC filing viewer fix:
- Rebuilt EDGAR fetch chain: company_tickers.json → CIK → submissions API
→ filings.recent.primaryDocument[] (replaces deprecated directory.item)
- Filing type selectbox (10-K, 10-Q, 8-K, 20-F, 6-K) connected to backend
- Native HTML rendered via streamlit.components.v1.html() with CSS reset
- Errors surfaced explicitly with st.error()
- DART direct links restored for Korean-listed companies
.gitignore: data/ → data/*.json + data/*.html (preserve Python modules)
README: full rewrite for master's portfolio — 7-tab layout, architecture
diagram, modular structure tree, technical challenges, design rationale
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
44 lines
1.6 KiB
Python
44 lines
1.6 KiB
Python
"""
|
|
Local preferences: API keys, email, last ticker. Saved to .app_prefs.json.
|
|
"""
|
|
import json
|
|
from pathlib import Path
|
|
|
|
_PREFS_PATH = Path(__file__).resolve().parent.parent / ".app_prefs.json"
|
|
_DATA_DIR = Path(__file__).resolve().parent.parent / "data"
|
|
|
|
|
|
def _load_prefs() -> dict:
|
|
"""Load saved API keys and email from local file. Keys: google_api_key, sec_email."""
|
|
try:
|
|
if _PREFS_PATH.exists():
|
|
with open(_PREFS_PATH, "r", encoding="utf-8") as f:
|
|
return json.load(f)
|
|
except Exception:
|
|
pass
|
|
return {}
|
|
|
|
|
|
def _save_prefs(google_api_key: str, sec_email: str, last_ticker: str = None, last_company_options: list = None, last_company_symbols: list = None) -> None:
|
|
"""Save API keys, email, and last selected company to local file."""
|
|
try:
|
|
data = {}
|
|
if _PREFS_PATH.exists():
|
|
try:
|
|
with open(_PREFS_PATH, "r", encoding="utf-8") as f:
|
|
data = json.load(f)
|
|
except Exception:
|
|
pass
|
|
data["google_api_key"] = (google_api_key or "").strip()
|
|
data["sec_email"] = (sec_email or "").strip()
|
|
if last_ticker is not None:
|
|
data["last_ticker"] = (last_ticker or "").strip()
|
|
if last_company_options is not None:
|
|
data["last_company_options"] = list(last_company_options) if last_company_options else []
|
|
if last_company_symbols is not None:
|
|
data["last_company_symbols"] = list(last_company_symbols) if last_company_symbols else []
|
|
with open(_PREFS_PATH, "w", encoding="utf-8") as f:
|
|
json.dump(data, f, indent=2)
|
|
except Exception:
|
|
pass
|