DrystanGovender/crs-competitive-intelligence
0
1#!/usr/bin/env python32"""3make_secrets.py — bridge HF Spaces "Secrets" (env vars) into a Streamlit4secrets.toml, so the existing app's st.secrets.get(...) calls need no changes.5 6Runs once at container startup (see entrypoint.sh). Only keys that are actually7set in the environment are written; missing keys are simply skipped, exactly8like an optional secret in Streamlit Cloud.9 10Add a key to ALLOWED_KEYS if the app ever reads a new st.secrets value, or set11EXTRA_SECRET_KEYS="FOO,BAR" in the Space to pass extras without editing this file.12"""13 14import os15import json16import pathlib17 18# Every key the CRS app reads via st.secrets, across all tabs/modules.19ALLOWED_KEYS = [20 # Core21 "SUPABASE_URL", "SUPABASE_KEY",22 "MONDAY_API_KEY",23 # AI providers (cascade)24 "GEMINI_API_KEY", "GROQ_API_KEY", "CEREBRAS_API_KEY", "OPENROUTER_API_KEY",25 "GITHUB_TOKEN", "GH_PAT", "NVIDIA_API_KEY", "DEEPSEEK_API_KEY", "HF_TOKEN",26 # Lead enrichment / verification27 "APOLLO_API_KEY", "APOLLO_MCP_TOKEN", "HUNTER_API_KEY", "APOLLO_WEBHOOK_SECRET",28 # Threat intel / news29 "FLARE_API_KEY", "FLARE_TENANT_ID", "NEWSAPI_KEY",30 # Search / dorking31 "GOOGLE_API_KEY", "GOOGLE_CSE_ID", "SERPER_API_KEY", "SERPAPI_API_KEY",32 # Optional in-app password gate33 "APP_PASSWORD",34]35 36extra = os.environ.get("EXTRA_SECRET_KEYS", "")37keys = list(dict.fromkeys(ALLOWED_KEYS + [k.strip() for k in extra.split(",") if k.strip()]))38 39 40def _toml_escape(value: str) -> str:41 # json.dumps uses the same escape sequences as TOML basic strings42 # (handles \n, \r, \t, \b, \f, \\, \" and all control chars correctly).43 # Strip the surrounding double-quotes that json.dumps adds.44 return json.dumps(value)[1:-1]45 46 47def main():48 lines, written = [], 049 for k in keys:50 v = os.environ.get(k)51 if v is None or v == "":52 continue53 lines.append(f'{k} = "{_toml_escape(v)}"')54 written += 155 56 dest = pathlib.Path.home() / ".streamlit" / "secrets.toml"57 dest.parent.mkdir(parents=True, exist_ok=True)58 dest.write_text("\n".join(lines) + "\n", encoding="utf-8")59 # Don't print values — just the count and which keys were found.60 found = [k for k in keys if os.environ.get(k)]61 print(f"make_secrets: wrote {written} secret(s) to {dest}: {', '.join(found)}")62 63 64if __name__ == "__main__":65 main()