# Entrypoint for all fetchers import sys import os sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) # project root sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) # src sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "fetchers"))) # fetchers import asyncio def run_advisorai_data(): # print("[DEBUG] sys.path:") # for p in sys.path: # print(" ", p) try: from advisorai_data.advisorai_data_fetcher import main as advisorai_data_main advisorai_data_main() except ModuleNotFoundError as e: print("[WARN] advisorai_data import failed, trying importlib fallback...") import importlib.util fetcher_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "advisorai_data", "advisorai_data_fetcher.py")) spec = importlib.util.spec_from_file_location("advisorai_data_fetcher", fetcher_path) advisorai_data_fetcher = importlib.util.module_from_spec(spec) spec.loader.exec_module(advisorai_data_fetcher) advisorai_data_fetcher.main() # def run_crawl_news(): # import importlib.util # import os # import asyncio # crawl_news_path = os.path.join(os.path.dirname(__file__), "crawl4ai", "crawl_news.py") # spec = importlib.util.spec_from_file_location("crawl_news", crawl_news_path) # crawl_news = importlib.util.module_from_spec(spec) # spec.loader.exec_module(crawl_news) # asyncio.run(crawl_news.main()) def run_crypto_bubbles(): from crypto_bubbles.fetch_crypto_bubbles import main as crypto_bubbles_main crypto_bubbles_main() def run_finnhub(): # Use the installed finnhub package, not the local finnhub module import importlib.util import os finnhub_main_path = os.path.join(os.path.dirname(__file__), "finnhub", "main.py") spec = importlib.util.spec_from_file_location("finnhub_main", finnhub_main_path) finnhub_main = importlib.util.module_from_spec(spec) spec.loader.exec_module(finnhub_main) finnhub_main.main() def run_alpaca_features(): import importlib import os alpaca_path = os.path.join(os.path.dirname(__file__), "alpaca_api", "main.py") spec = importlib.util.spec_from_file_location("alpaca_features", alpaca_path) alpaca_features = importlib.util.module_from_spec(spec) spec.loader.exec_module(alpaca_features) alpaca_features.main() def run_marketaux_news(): import importlib.util import os marketaux_news_path = os.path.join(os.path.dirname(__file__), "marketaux", "news.py") spec = importlib.util.spec_from_file_location("marketaux_news", marketaux_news_path) marketaux_news = importlib.util.module_from_spec(spec) spec.loader.exec_module(marketaux_news) marketaux_news.main() def run_finviz_sentiment(): import importlib.util finviz_path = os.path.join(os.path.dirname(__file__), "finviz_sentiment", "app.py") spec = importlib.util.spec_from_file_location("finviz_sentiment_app", finviz_path) finviz_sentiment_app = importlib.util.module_from_spec(spec) spec.loader.exec_module(finviz_sentiment_app) finviz_sentiment_app.main() def run_santiment(): """Run Santiment with frequency control to preserve API limits""" # Import frequency controller import sys import os controller_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "santiment_frequency_controller.py")) sys.path.insert(0, os.path.dirname(controller_path)) try: from santiment_frequency_controller import SantimentFrequencyController # Check if Santiment should run controller = SantimentFrequencyController() if not controller.should_run_santiment(max_runs_per_day=2): print("[SANTIMENT] Skipping run due to frequency control") status = controller.get_status() print(f"[SANTIMENT] Runs today: {status['runs_today']}/2") print(f"[SANTIMENT] Last run: {status['last_run']}") return print("[SANTIMENT] Frequency control allows run - proceeding...") # Run Santiment import importlib.util santiment_path = os.path.join(os.path.dirname(__file__), "santiment", "main.py") spec = importlib.util.spec_from_file_location("santiment_main", santiment_path) santiment_main = importlib.util.module_from_spec(spec) spec.loader.exec_module(santiment_main) santiment_main.main() # Record the run controller.record_run() print("[SANTIMENT] Run completed and recorded") except Exception as e: print(f"[SANTIMENT] Error in frequency control: {e}") print("[SANTIMENT] Falling back to direct run...") # Fallback to direct run if frequency control fails import importlib.util santiment_path = os.path.join(os.path.dirname(__file__), "santiment", "main.py") spec = importlib.util.spec_from_file_location("santiment_main", santiment_path) santiment_main = importlib.util.module_from_spec(spec) spec.loader.exec_module(santiment_main) santiment_main.main() def run_all(): run_advisorai_data() # run_crawl_news() run_crypto_bubbles() run_finnhub() run_alpaca_features() run_marketaux_news() run_finviz_sentiment() run_santiment() print("[OK] All fetchers completed successfully.") def main(): # Simple CLI: python main.py [advisorai|crawl_news|crypto_bubbles|finnhub|alpaca_features|marketaux_news|finviz_sentiment|santiment|all] [TICKERS...] if len(sys.argv) < 2 or sys.argv[1] == "all": run_all() elif sys.argv[1] == "advisorai": run_advisorai_data() # elif sys.argv[1] == "crawl_news": # run_crawl_news() elif sys.argv[1] == "crypto_bubbles": run_crypto_bubbles() elif sys.argv[1] == "finnhub": run_finnhub() elif sys.argv[1] == "alpaca_features": run_alpaca_features() elif sys.argv[1] == "marketaux_news": run_marketaux_news() elif sys.argv[1] == "finviz_sentiment": run_finviz_sentiment() elif sys.argv[1] == "santiment": run_santiment() else: print("Usage: python main.py [advisorai|crawl_news|crypto_bubbles|finnhub|alpaca_features|marketaux_news|finviz_sentiment|santiment|all] [TICKERS...]") sys.exit(1) if __name__ == "__main__": main()