feat: finalize root api.py with X-Auth-Secret auth security and clean pure sales cohort
This commit is contained in:
1 parent
85e6395770
commit
78a46a8dbe
629 files changed
+123965
-755
No files matched your search
@@ -0,0 +1,89 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sqlite3
|
||||
import time
|
||||
import requests
|
||||
from dotenv import load_dotenv
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parent.parent
|
||||
load_dotenv(PROJECT_ROOT / ".env")
|
||||
|
||||
YOUTUBE_API_KEY = os.getenv("YOUTUBE_API_KEY", "").strip()
|
||||
DB_PATH = PROJECT_ROOT / "data" / "hiffi_catalog.db"
|
||||
|
||||
if not YOUTUBE_API_KEY:
|
||||
print("Error: YOUTUBE_API_KEY not found in .env")
|
||||
exit(1)
|
||||
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
cur = conn.cursor()
|
||||
|
||||
# Query all artists with search fallback URLs
|
||||
cur.execute("""
|
||||
SELECT a.artist_id, a.artist_name, a.youtube_url
|
||||
FROM artists a
|
||||
WHERE a.youtube_url LIKE '%results?search_query%' AND a.image_verified_flag = 1
|
||||
""")
|
||||
rows = cur.fetchall()
|
||||
print(f"Targeting {len(rows)} artists needing canonical YouTube Channel URLs and subscriber counts...\n")
|
||||
|
||||
resolved = 0
|
||||
for artist_id, name, old_url in rows:
|
||||
clean_name = name.strip()
|
||||
try:
|
||||
# 1. Search for verified channel
|
||||
search_resp = requests.get(
|
||||
"https://www.googleapis.com/youtube/v3/search",
|
||||
params={
|
||||
"part": "snippet",
|
||||
"q": f"{clean_name} Official Artist Channel",
|
||||
"type": "channel",
|
||||
"maxResults": 1,
|
||||
"key": YOUTUBE_API_KEY
|
||||
},
|
||||
timeout=10
|
||||
)
|
||||
|
||||
channel_id = None
|
||||
if search_resp.status_code == 200:
|
||||
items = search_resp.json().get("items", [])
|
||||
if items:
|
||||
channel_id = items[0]["snippet"]["channelId"]
|
||||
|
||||
if channel_id:
|
||||
# 2. Get accurate subscriber count
|
||||
chan_resp = requests.get(
|
||||
"https://www.googleapis.com/youtube/v3/channels",
|
||||
params={
|
||||
"part": "statistics",
|
||||
"id": channel_id,
|
||||
"key": YOUTUBE_API_KEY
|
||||
},
|
||||
timeout=10
|
||||
)
|
||||
|
||||
subs = 0
|
||||
if chan_resp.status_code == 200:
|
||||
stats = chan_resp.json().get("items", [{}])[0].get("statistics", {})
|
||||
subs = int(stats.get("subscriberCount", 0))
|
||||
|
||||
canonical_url = f"https://www.youtube.com/channel/{channel_id}"
|
||||
|
||||
# 3. Update artists and telemetry_metrics
|
||||
cur.execute("UPDATE artists SET youtube_url = ? WHERE artist_id = ?", (canonical_url, artist_id))
|
||||
if subs > 0:
|
||||
cur.execute("UPDATE telemetry_metrics SET subscribers_count = ? WHERE artist_id = ?", (subs, artist_id))
|
||||
|
||||
conn.commit()
|
||||
resolved += 1
|
||||
print(f"[{resolved}/{len(rows)}] {clean_name} -> {canonical_url} (Subs: {subs:,})")
|
||||
else:
|
||||
print(f"[NO CHANNEL FOUND] {clean_name}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"[ERR] {clean_name}: {e}")
|
||||
|
||||
time.sleep(0.1)
|
||||
|
||||
conn.close()
|
||||
print(f"\nYouTube canonicalization complete: {resolved}/{len(rows)} resolved.")
|
||||
Reference in new issue
Block a user