import os import gradio as gr from huggingface_hub import InferenceClient # ── Model (ücretsiz HF Inference API) ───────────────────────────────────────── # HF_TOKEN ortam değişkeni Space'in Secrets kısmına eklenir (ücretsiz) client = InferenceClient( api_key=os.environ.get("HF_TOKEN"), ) # ── Prompt ───────────────────────────────────────────────────────────────────── def build_messages(niche: str, audience: str) -> list: audience_line = f"Target audience: {audience}" if audience.strip() else "Target audience: General TikTok users" return [ { "role": "system", "content": "You are a TikTok viral content analyst AI. Your task is to identify viral video opportunities based on patterns, not random ideas. Always use clear formatting with emojis." }, { "role": "user", "content": f"""INPUT: - Niche: {niche} - {audience_line} - Platform: TikTok STEP 1: Briefly analyze what makes content go viral in this niche: - Best hook styles - Key emotional triggers - Video structure patterns STEP 2: Generate 10 viral video ideas. For each idea provide: 1. 🎬 Title 2. 🪝 Hook (first sentence spoken in the video) 3. 💡 Concept (what happens) 4. 🔥 Why it can go viral 5. ⭐ Virality Score: X/10 STEP 3: Give 3 specific improvements to boost virality in this niche. Rules: - Be specific and creative, avoid generic ideas - Think like the TikTok algorithm - Focus on scroll-stopping content - Use clear formatting with emojis""" } ] # ── Inference (streaming) ────────────────────────────────────────────────────── def analyze(niche: str, audience: str): if not niche.strip(): yield "⚠️ Lütfen bir niche (konu) girin." return messages = build_messages(niche.strip(), audience.strip()) output = "" try: stream = client.chat.completions.create( model="meta-llama/Meta-Llama-3.1-8B-Instruct", messages=messages, max_tokens=2500, temperature=0.8, stream=True, ) for chunk in stream: delta = chunk.choices[0].delta.content or "" output += delta yield output except Exception as e: yield f"❌ Hata oluştu: {str(e)}\n\nHF_TOKEN'ınızı Space Secrets'a eklediğinizden emin olun." # ── CSS ──────────────────────────────────────────────────────────────────────── CSS = """ @import url('https://fonts.googleapis.com/css2?family=Bebas+Neue&family=Plus+Jakarta+Sans:wght@300;400;500;600&display=swap'); :root { --bg: #0a0a0a; --card: #161616; --border: #222; --red: #fe2c55; --cyan: #25f4ee; --white: #f0f0f0; --muted: #555; --font-d: 'Bebas Neue', sans-serif; --font-b: 'Plus Jakarta Sans', sans-serif; --r: 12px; } body, .gradio-container { background: var(--bg) !important; color: var(--white) !important; font-family: var(--font-b) !important; } #hdr { padding: 44px 24px 24px; text-align: center; } #hdr .logo { font-family: var(--font-d); font-size: clamp(3rem, 10vw, 5.5rem); letter-spacing: 3px; background: linear-gradient(135deg, var(--red) 0%, #ff6b8a 45%, var(--cyan) 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; animation: glow 3s ease-in-out infinite; } @keyframes glow { 0%,100% { filter: drop-shadow(0 0 18px rgba(254,44,85,.45)); } 50% { filter: drop-shadow(0 0 35px rgba(37,244,238,.45)); } } #hdr .sub { color: var(--muted); font-size:.82rem; letter-spacing:.14em; text-transform:uppercase; margin-top:6px; } #hdr .badge { display:inline-block; margin-top:12px; padding:4px 16px; border:1px solid var(--red); border-radius:100px; font-size:.68rem; letter-spacing:.1em; color:var(--red); text-transform:uppercase; } #stats { display:flex; justify-content:center; gap:48px; padding:22px 0 26px; border-bottom:1px solid var(--border); margin-bottom:26px; } #stats .val { font-family:var(--font-d); font-size:2.2rem; background:linear-gradient(135deg,var(--red),var(--cyan)); -webkit-background-clip:text; -webkit-text-fill-color:transparent; } #stats .lbl { font-size:.66rem; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); margin-top:2px; } #tips { display:flex; gap:10px; flex-wrap:wrap; justify-content:center; padding:0 0 26px; } #tips .tip { background:var(--card); border:1px solid var(--border); border-radius:100px; padding:5px 14px; font-size:.7rem; color:var(--muted); } label span { color:var(--muted) !important; font-size:.7rem !important; letter-spacing:.1em !important; text-transform:uppercase !important; } textarea, input[type="text"] { background:var(--card) !important; border:1px solid var(--border) !important; border-radius:var(--r) !important; color:var(--white) !important; font-family:var(--font-b) !important; font-size:.95rem !important; transition:border-color .2s, box-shadow .2s !important; } textarea:focus, input[type="text"]:focus { border-color:var(--red) !important; box-shadow:0 0 0 3px rgba(254,44,85,.12) !important; } button.primary { background:var(--red) !important; border:none !important; border-radius:var(--r) !important; color:#fff !important; font-family:var(--font-d) !important; font-size:1.1rem !important; letter-spacing:.15em !important; padding:13px 32px !important; transition:transform .15s, box-shadow .15s !important; } button.primary:hover { transform:translateY(-2px) !important; box-shadow:0 8px 28px rgba(254,44,85,.45) !important; } button.secondary { background:transparent !important; border:1px solid var(--border) !important; border-radius:var(--r) !important; color:var(--muted) !important; font-family:var(--font-b) !important; transition:border-color .2s, color .2s !important; } button.secondary:hover { border-color:var(--cyan) !important; color:var(--cyan) !important; } .gr-markdown { background:var(--card) !important; border:1px solid var(--border) !important; border-radius:var(--r) !important; padding:24px !important; font-size:.88rem !important; line-height:1.8 !important; color:#bbb !important; min-height:340px; } .gr-markdown h1,.gr-markdown h2 { font-family:var(--font-d) !important; letter-spacing:.06em !important; color:var(--white) !important; } .gr-markdown h3 { color:var(--cyan) !important; font-size:.82rem !important; text-transform:uppercase !important; } .gr-markdown strong { color:var(--red) !important; } .gr-markdown code { background:#1a1a1a !important; border-radius:4px !important; padding:2px 7px !important; color:var(--cyan) !important; } .gr-group, .gr-box { background:#111 !important; border:1px solid var(--border) !important; border-radius:var(--r) !important; } #footer { text-align:center; padding:20px; color:var(--muted); font-size:.7rem; letter-spacing:.08em; border-top:1px solid var(--border); margin-top:32px; } ::-webkit-scrollbar { width:4px; } ::-webkit-scrollbar-track { background:var(--bg); } ::-webkit-scrollbar-thumb { background:#2a2a2a; border-radius:4px; } """ HEADER = """
HF_TOKEN ekle (ücretsiz)