This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
streamlit run app.pypip install -r requirements.txt
playwright installPut these in .env:
GEMINI_API_KEY=... # Google Gemini (required)
MS_TOKEN=... # TikTok msToken cookie (can be pasted in the UI instead)
msToken expires every few hours. A stale token causes Playwright to time out on wait_for_load_state("networkidle") because TikTok serves an auth page with continuous background pings.
The data flow is linear:
scraper.py → agent.py → app.py (renders results) → report.py (optional export)
TikTokScraper.get_video_data(url)is the public entry point. Returns a dict withurl,caption,hashtags,view_count,like_count,comment_count,comments._run_async()always creates a freshasyncio.ProactorEventLoop()— required on Windows because the defaultSelectorEventLoopcannot spawn subprocesses (which Playwright needs). Do not change this toasyncio.new_event_loop().create_sessionsruns withheadless=Falseandtimeout=600000(10 min). Headless mode triggers TikTok bot detection. The long timeout is intentional for slow/rate-limited sessions.- Comments are capped at 100 and filtered for length by
_clean_comments()before being returned.
GeminiAgent.analyze_content(data)takes the scraper dict and returns a structured analysis dict._PROMPT_TEMPLATEprints the exact required JSON schema verbatim before any instructions, then demands Gemini start with{and end with}. This is intentional — Gemini was returning its own schema structure without this._safe_parse_json()validates thatlanguage_analysisis present after parsing. If missing, raisesValueErrorsoanalyze_content's retry loop (3 attempts) fires again.- The full parse chain: direct
json.loads→ regex extraction → brace-matching fallback →_ensure_schema()which guarantees all 7 top-level keys exist. - Uses
gemini-2.5-flashattemperature=0.2. Comments are truncated to 4000 chars before being inserted into the prompt.
- Single
main()function. Sidebar holdsms_tokeninput and API key status. Main area has URL input + Analyze button. - On submit:
TikTokScraper→get_video_data→GeminiAgent→analyze_content→_build_strategy_recommendations()(local, no AI) → render. - Two-column layout: left col has demographic profile, virality factors, strategy recommendations; right col has stats, quick insights, AI deep analysis.
- Exceptions are displayed via
st.exception().
ReportFormatterexists but templates are unpopulated and not wired intoapp.py.