""" One-shot installer: pip install requirements + download spaCy model. Run once before first use: python install.py """ import subprocess import sys def run(cmd: list[str]) -> int: print(f"\n$ {' '.join(cmd)}") return subprocess.call(cmd) def main(): print("=" * 60) print(" Crypto Narrative Analysis — Dependency Installer") print("=" * 60) # Core requirements (lean, always needed) ret = run([sys.executable, "-m", "pip", "install", "-r", "requirements.txt"]) if ret != 0: print("\n[!] pip install failed. Check requirements.txt and your Python env.") sys.exit(1) # Full ML extras (CryptoBERT ensemble, spaCy, BERTopic) — heavy (~2GB) print("\nInstalling full ML extras for the CryptoBERT ensemble (~2GB)...") ret = run([sys.executable, "-m", "pip", "install", "-r", "requirements-ml.txt"]) if ret != 0: print("[!] ML extras failed — app still works on the VADER fallback.") # spaCy model print("\nDownloading spaCy en_core_web_sm model...") run([sys.executable, "-m", "spacy", "download", "en_core_web_sm"]) # CryptoBERT model (~500MB) for the ensemble sentiment scorer. # Optional: if this fails or is skipped, the app falls back to VADER. print("\nDownloading CryptoBERT sentiment model (~500MB, one-time)...") try: from huggingface_hub import snapshot_download snapshot_download("ElKulako/cryptobert", max_workers=2) print("CryptoBERT downloaded.") except Exception as exc: print(f"[!] CryptoBERT download skipped ({exc}). App will use VADER fallback.") # NLTK data (used by TextBlob / NLTK internally) print("\nDownloading NLTK punkt tokenizer...") import nltk nltk.download("punkt", quiet=True) nltk.download("stopwords", quiet=True) print("\n" + "=" * 60) print(" Installation complete!") print(" Next steps:") print(" 1. Copy .env.example to .env") print(" 2. Add your free Reddit app credentials") print(" 3. Run: python main.py") print("=" * 60) if __name__ == "__main__": main()