""" scripts/resolve_youtube_api_official.py Queries the official YouTube Data API v3 to fetch verified channel subscriber counts for remaining unverified cohort artists and writes directly to SQLite. """ import os import sys import time from pathlib import Path import pandas as pd import requests from dotenv import load_dotenv ROOT_DIR = Path(__file__).resolve().parent.parent if str(ROOT_DIR) not in sys.path: sys.path.insert(0, str(ROOT_DIR)) load_dotenv(ROOT_DIR / ".env") from core.database import get_connection API_KEY = os.getenv("YOUTUBE_API_KEY") def get_channel_id_and_subs(artist_name): """Searches YouTube API for the top channel match and fetches subscriber count.""" search_url = "https://www.googleapis.com/youtube/v3/search" search_params = { "part": "snippet", "q": f"{artist_name} official channel", "type": "channel", "maxResults": 1, "key": API_KEY, } try: r = requests.get(search_url, params=search_params, timeout=10) if r.status_code != 200: return None, 0 items = r.json().get("items", []) if not items: return None, 0 channel_id = items[0]["id"]["channelId"] stats_url = "https://www.googleapis.com/youtube/v3/channels" stats_params = { "part": "statistics", "id": channel_id, "key": API_KEY, } r_stats = requests.get(stats_url, params=stats_params, timeout=10) if r_stats.status_code == 200: stat_items = r_stats.json().get("items", []) if stat_items: subs = int( stat_items[0].get("statistics", {}).get("subscriberCount", 0) ) return channel_id, subs except Exception: pass return None, 0 def main(): print("=" * 65) print("HIFFI INTELLIGENCE: OFFICIAL YOUTUBE API RESOLUTION") print("=" * 65) if not API_KEY: print("[!] ERROR: YOUTUBE_API_KEY is not configured in .env.") return df500 = pd.read_csv(ROOT_DIR / "data" / "hiffi_multiplatform_500.csv") cohort_names = [n.strip() for n in df500["name"]] conn = get_connection() cur = conn.cursor() # Target cohort artists with 0 or low placeholder subscriber counts (< 1000) cur.execute(""" SELECT a.artist_name, COALESCE(t.subscribers_count, 0) FROM artists a JOIN telemetry_metrics t ON a.artist_id = t.artist_id WHERE t.subscribers_count IS NULL OR t.subscribers_count < 1000 """) rows = cur.fetchall() targets = [r[0] for r in rows if r[0] in cohort_names] print(f"Targeting {len(targets)} unresolved cohort artists via official API...\n") updated = 0 for idx, name in enumerate(targets, 1): channel_id, subs = get_channel_id_and_subs(name) if subs > 0: updated += 1 cur.execute(""" UPDATE telemetry_metrics SET subscribers_count = ? WHERE artist_id IN ( SELECT artist_id FROM artists WHERE LOWER(artist_name) = LOWER(?) ) """, (subs, name)) print(f"[{idx:>3}/{len(targets)}] {name:<25} -> {subs:,} subs (ID: {channel_id})") else: print(f"[{idx:>3}/{len(targets)}] {name:<25} -> No channel resolved") # Sleep briefly to respect API rate limits time.sleep(0.1) conn.commit() conn.close() print("\n" + "=" * 65) print(f"Completed: Successfully verified and updated {updated} / {len(targets)} artists.") print("=" * 65) if __name__ == "__main__": main()