# music-lab/app/market.py import os from collections import Counter, defaultdict from typing import Any, Dict, List, Optional from .db import ( get_latest_trend_report, get_trend_reports, insert_market_trends, upsert_trend_report, ) GENRE_PROMPTS: Dict[str, str] = { "lo-fi": "lo-fi hip hop, chill, relaxing beats, study music, 85 BPM, jazzy chords", "phonk": "dark phonk, aggressive 808 bass, Memphis trap, distorted synths, 140 BPM", "ambient": "ambient, atmospheric, ethereal pads, slow evolving textures, no percussion", "pop": "upbeat pop, catchy melody, modern production, 120 BPM", "funk": "baile funk, Brazilian funk, energetic, 150 BPM", "latin": "reggaeton, latin pop, dembow rhythm, 100 BPM", "general": "music, modern production, wide appeal", } def ingest_trends(trends: List[Dict[str, Any]], report_date: str) -> Dict[str, Any]: """agent-office 트렌드 수신 → 저장 + 리포트 생성.""" insert_market_trends(trends) report = _build_report(trends, report_date) upsert_trend_report(report) return report def _build_report(trends: List[Dict[str, Any]], report_date: str) -> Dict[str, Any]: genre_scores: Dict[str, float] = defaultdict(float) genre_countries: Dict[str, set] = defaultdict(set) keywords: List[str] = [] for t in trends: g = t.get("genre") or "general" genre_scores[g] += t.get("score", 0.0) genre_countries[g].add(t.get("country", "")) kw = t.get("keyword", "") if kw: keywords.append(kw) top_genres = sorted( [{"genre": g, "score": round(s, 3), "countries": list(genre_countries[g])} for g, s in genre_scores.items()], key=lambda x: x["score"], reverse=True, )[:10] kw_counts = Counter(keywords) top_keywords = [kw for kw, _ in kw_counts.most_common(15)] recommended_styles = [ { "genre": g["genre"], "suno_prompt": GENRE_PROMPTS.get(g["genre"], GENRE_PROMPTS["general"]), "target_countries": g["countries"][:3], "reason": f"트렌딩 score {g['score']:.2f}", } for g in top_genres[:5] ] return { "report_date": report_date, "top_genres": top_genres, "top_keywords": top_keywords, "recommended_styles": recommended_styles, "insights": _generate_insights(top_genres, top_keywords), } def _generate_insights(top_genres: list, top_keywords: list) -> str: api_key = os.getenv("ANTHROPIC_API_KEY", "") if not top_genres: return "아직 수집된 트렌드 데이터가 없습니다." if not api_key: names = ", ".join(g["genre"] for g in top_genres[:3]) return f"이번 주 인기 장르: {names}. 해당 장르 중심 제작을 추천합니다." import anthropic client = anthropic.Anthropic(api_key=api_key) genre_str = ", ".join(f"{g['genre']}({g['score']:.1f})" for g in top_genres[:5]) kw_str = ", ".join(top_keywords[:10]) try: msg = client.messages.create( model="claude-haiku-4-5-20251001", max_tokens=300, messages=[{"role": "user", "content": f"YouTube 음악 트렌드 인사이트를 2-3문장으로 요약.\n" f"인기 장르: {genre_str}\n인기 키워드: {kw_str}"}], ) return msg.content[0].text.strip() except Exception: names = ", ".join(g["genre"] for g in top_genres[:3]) return f"인기 장르: {names}." def get_suggestions(limit: int = 5) -> List[Dict[str, Any]]: report = get_latest_trend_report() if not report: return [] return report.get("recommended_styles", [])[:limit]