import gradio as gr from google import genai from google.genai import types from PIL import Image from io import BytesIO import base64 import os import json import random # Initialize the Google Generative AI client with the API key from environment variables try: api_key = os.environ['GEMINI_API_KEY'] except KeyError: raise ValueError("Please set the GEMINI_API_KEY environment variable.") client = genai.Client(api_key=api_key) def generate_ideas(tag): """ Generate a diverse set of ideas related to the tag using the LLM. Args: tag (str): The tag to base the ideas on. Returns: list: A list of ideas as strings. """ prompt = f""" Generate a list of 5 diverse and creative ideas related to {tag} that can be used for a TikTok video. Each idea should be a short sentence describing a specific scene or concept. Return the response as a JSON object with a single key 'ideas' containing a list of 5 ideas. Ensure the response is strictly in JSON format. Example: {{"ideas": ["A neon-lit gaming setup with RGB lights flashing", "A futuristic robot assembling a gadget"]}} """ try: response = client.models.generate_content( model='gemini-2.0-flash', # Updated to a potentially supported model contents=[prompt], config=types.GenerateContentConfig(temperature=1.2) ) print(f"Raw response for ideas: {response.text}") # Debugging if not response.text or response.text.isspace(): raise ValueError("Empty response from API") response_json = json.loads(response.text.strip()) if 'ideas' not in response_json or not isinstance(response_json['ideas'], list): raise ValueError("Invalid JSON format: 'ideas' key missing or not a list") return response_json['ideas'] except Exception as e: print(f"Error generating ideas: {e}") return [ f"A vibrant {tag} scene at sunset", f"A close-up of {tag} with neon lights", f"A futuristic take on {tag} with holograms", f"A cozy {tag} moment with warm lighting", f"An action-packed {tag} scene with dynamic colors" ] def generate_item(tag, ideas): """ Generate a single feed item using one of the ideas. Args: tag (str): The tag to base the content on. ideas (list): List of ideas to choose from. Returns: dict: A dictionary with 'text' (str) and 'image_base64' (str). """ selected_idea = random.choice(ideas) prompt = f""" Based on the idea "{selected_idea}", create content for a TikTok video about {tag}. Return a JSON object with two keys: - 'caption': A short, viral TikTok-style caption with hashtags. - 'image_prompt': A detailed image prompt for generating a high-quality visual scene. The image prompt should describe the scene vividly, specify a perspective and style, and ensure no text or letters are included. Ensure the response is strictly in JSON format. Example: {{"caption": "Neon vibes only! 🌌 #tech", "image_prompt": "A close-up view of a neon-lit gaming setup with RGB lights flashing, in a futuristic style, no text or letters"}} """ try: response = client.models.generate_content( model='gemini-2.0-flash', # Updated to a potentially supported model contents=[prompt], config=types.GenerateContentConfig(temperature=1.2) ) print(f"Raw response for item: {response.text}") # Debugging if not response.text or response.text.isspace(): raise ValueError("Empty response from API") response_json = json.loads(response.text.strip()) if 'caption' not in response_json or 'image_prompt' not in response_json: raise ValueError("Invalid JSON format: 'caption' or 'image_prompt' key missing") text = response_json['caption'] image_prompt = response_json['image_prompt'] except Exception as e: print(f"Error generating item: {e}") text = f"Obsessed with {tag}! 🔥 #{tag}" image_prompt = f"A vivid scene of {selected_idea}, in a vibrant pop art style, no text or letters" try: image_response = client.models.generate_images( model='imagen-3.0-generate-002', prompt=image_prompt, config=types.GenerateImagesConfig( number_of_images=1, aspect_ratio="9:16", person_generation="DONT_ALLOW" ) ) if image_response.generated_images and len(image_response.generated_images) > 0: generated_image = image_response.generated_images[0] image = Image.open(BytesIO(generated_image.image.image_bytes)) else: image = Image.new('RGB', (360, 640), color='gray') except Exception as e: print(f"Error generating image: {e}") image = Image.new('RGB', (360, 640), color='gray') buffered = BytesIO() image.save(buffered, format="PNG") img_str = base64.b64encode(buffered.getvalue()).decode() return {'text': text, 'image_base64': img_str, 'ideas': ideas} def start_feed(tag, current_index, feed_items): """ Start or update the feed based on the tag. Args: tag (str): The tag to generate content for. current_index (int): The current item index. feed_items (list): The current list of feed items. Returns: tuple: (current_tag, current_index, feed_items, html_content, is_loading) """ if not tag.strip(): tag = "trending" # Set loading state is_loading = True html_content = generate_html([], False, 0, tag, is_loading) try: ideas = generate_ideas(tag) item = generate_item(tag, ideas) feed_items = [item] current_index = 0 except Exception as e: print(f"Error in start_feed: {e}") feed_items = [] current_index = 0 html_content = """
Error generating content. Please try again!
Error generating content. Please try again!
Select a tag to start your feed!