codelion commited on
Commit
f756321
Β·
verified Β·
1 Parent(s): 86ea854

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -22
app.py CHANGED
@@ -6,6 +6,7 @@ from io import BytesIO
6
  import base64
7
  import os
8
  import json
 
9
 
10
  # Initialize the Google Generative AI client with the API key from environment variables
11
  try:
@@ -14,38 +15,61 @@ except KeyError:
14
  raise ValueError("Please set the GEMINI_API_KEY environment variable.")
15
  client = genai.Client(api_key=api_key)
16
 
17
- def generate_item(tag):
18
  """
19
- Generate a single feed item consisting of text from Gemini LLM and an image from Imagen.
20
 
21
  Args:
22
  tag (str): The tag to base the content on.
 
23
 
24
  Returns:
25
  dict: A dictionary with 'text' (str) and 'image_base64' (str).
26
  """
27
- # Generate text using Gemini LLM with JSON output
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  prompt = f"""
29
  Generate a short, engaging TikTok-style caption about {tag}.
30
  Return the response as a JSON object with a single key 'caption' containing the caption text.
31
  Example: {{"caption": "Craving this yummy treat! 😍 #foodie"}}
32
  Do not include additional commentary or options.
 
33
  """
34
  text_response = client.models.generate_content(
35
  model='gemini-2.5-flash-preview-04-17',
36
- contents=[prompt]
 
37
  )
38
  # Parse JSON response to extract the caption
39
  try:
40
  response_json = json.loads(text_response.text.strip())
41
  text = response_json['caption']
42
  except (json.JSONDecodeError, KeyError):
43
- text = f"Wow, {tag} is amazing! 😍 #{tag}" # Fallback caption
44
 
45
- # Generate an image based on the tag, avoiding text
46
  image_prompt = f"""
47
- A vivid, high-quality visual scene representing {tag}, designed for a TikTok video.
48
- The image should be colorful and engaging, with no text or letters included.
 
49
  """
50
  image_response = client.models.generate_images(
51
  model='imagen-3.0-generate-002',
@@ -63,7 +87,7 @@ def generate_item(tag):
63
  image = Image.open(BytesIO(generated_image.image.image_bytes))
64
  else:
65
  # Fallback to a placeholder image
66
- image = Image.new('RGB', (300, 533), color='gray') # 9:16 aspect ratio
67
 
68
  # Convert the image to base64
69
  buffered = BytesIO()
@@ -83,15 +107,15 @@ def start_feed(tag):
83
  tuple: (current_tag, feed_items, html_content)
84
  """
85
  if not tag.strip():
86
- tag = "trending" # Default tag if empty
87
- item = generate_item(tag)
88
  feed_items = [item]
89
  html_content = generate_html(feed_items)
90
  return tag, feed_items, html_content
91
 
92
  def load_more(current_tag, feed_items):
93
  """
94
- Append a new item to the existing feed using the current tag.
95
 
96
  Args:
97
  current_tag (str): The tag currently being used for the feed.
@@ -100,23 +124,24 @@ def load_more(current_tag, feed_items):
100
  Returns:
101
  tuple: (current_tag, updated_feed_items, updated_html_content)
102
  """
103
- new_item = generate_item(current_tag)
104
  feed_items.append(new_item)
105
- html_content = generate_html(feed_items)
106
  return current_tag, feed_items, html_content
107
 
108
- def generate_html(feed_items):
109
  """
110
- Generate an HTML string to display the feed items in a TikTok-like vertical layout.
111
 
112
  Args:
113
  feed_items (list): List of dictionaries containing 'text' and 'image_base64'.
 
114
 
115
  Returns:
116
  str: HTML string representing the feed.
117
  """
118
  html_str = """
119
- <div style="
120
  display: flex;
121
  flex-direction: column;
122
  align-items: center;
@@ -124,24 +149,28 @@ def generate_html(feed_items):
124
  margin: 0 auto;
125
  background-color: #000;
126
  height: 640px;
127
- overflow-y: auto;
 
128
  scrollbar-width: none;
129
  -ms-overflow-style: none;
130
  border: 1px solid #333;
131
  border-radius: 10px;
132
  ">
133
  """
134
- # Hide scrollbar for a cleaner look
135
  html_str += """
136
  <style>
137
- div::-webkit-scrollbar {
138
  display: none;
139
  }
 
 
 
140
  </style>
141
  """
142
- for item in feed_items:
143
  html_str += f"""
144
- <div style="
145
  width: 100%;
146
  height: 640px;
147
  position: relative;
@@ -175,6 +204,15 @@ def generate_html(feed_items):
175
  </div>
176
  """
177
  html_str += "</div>"
 
 
 
 
 
 
 
 
 
178
  return html_str
179
 
180
  # Define the Gradio interface
 
6
  import base64
7
  import os
8
  import json
9
+ import random
10
 
11
  # Initialize the Google Generative AI client with the API key from environment variables
12
  try:
 
15
  raise ValueError("Please set the GEMINI_API_KEY environment variable.")
16
  client = genai.Client(api_key=api_key)
17
 
18
+ def generate_item(tag, item_index):
19
  """
20
+ Generate a single feed item with diverse text and image.
21
 
22
  Args:
23
  tag (str): The tag to base the content on.
24
+ item_index (int): Index of the item to ensure diversity.
25
 
26
  Returns:
27
  dict: A dictionary with 'text' (str) and 'image_base64' (str).
28
  """
29
+ # Define varied styles for diversity in image generation
30
+ styles = [
31
+ "futuristic neon lighting",
32
+ "soft pastel tones with a dreamy vibe",
33
+ "vibrant and colorful pop art style",
34
+ "minimalist black and white aesthetic",
35
+ "retro 80s synthwave look",
36
+ "golden hour sunlight with warm tones"
37
+ ]
38
+ perspectives = [
39
+ "a close-up view",
40
+ "a wide-angle shot",
41
+ "an aerial perspective",
42
+ "a side profile",
43
+ "a dynamic angled shot"
44
+ ]
45
+ style = random.choice(styles)
46
+ perspective = random.choice(perspectives)
47
+
48
+ # Generate text with high temperature for diversity
49
  prompt = f"""
50
  Generate a short, engaging TikTok-style caption about {tag}.
51
  Return the response as a JSON object with a single key 'caption' containing the caption text.
52
  Example: {{"caption": "Craving this yummy treat! 😍 #foodie"}}
53
  Do not include additional commentary or options.
54
+ Use creative and varied language to ensure uniqueness.
55
  """
56
  text_response = client.models.generate_content(
57
  model='gemini-2.5-flash-preview-04-17',
58
+ contents=[prompt],
59
+ generation_config={"temperature": 1.2} # High temperature for diversity
60
  )
61
  # Parse JSON response to extract the caption
62
  try:
63
  response_json = json.loads(text_response.text.strip())
64
  text = response_json['caption']
65
  except (json.JSONDecodeError, KeyError):
66
+ text = f"Obsessed with {tag}! πŸ”₯ #{tag}" # Fallback caption
67
 
68
+ # Generate a diverse image based on the tag
69
  image_prompt = f"""
70
+ A high-quality visual scene representing {tag}, designed for a TikTok video.
71
+ The image should be {perspective} with a {style}.
72
+ Ensure the image is colorful, engaging, and has no text or letters.
73
  """
74
  image_response = client.models.generate_images(
75
  model='imagen-3.0-generate-002',
 
87
  image = Image.open(BytesIO(generated_image.image.image_bytes))
88
  else:
89
  # Fallback to a placeholder image
90
+ image = Image.new('RGB', (360, 640), color='gray') # 9:16 aspect ratio
91
 
92
  # Convert the image to base64
93
  buffered = BytesIO()
 
107
  tuple: (current_tag, feed_items, html_content)
108
  """
109
  if not tag.strip():
110
+ tag = "trending"
111
+ item = generate_item(tag, 0)
112
  feed_items = [item]
113
  html_content = generate_html(feed_items)
114
  return tag, feed_items, html_content
115
 
116
  def load_more(current_tag, feed_items):
117
  """
118
+ Append a new item to the existing feed and scroll to the latest item.
119
 
120
  Args:
121
  current_tag (str): The tag currently being used for the feed.
 
124
  Returns:
125
  tuple: (current_tag, updated_feed_items, updated_html_content)
126
  """
127
+ new_item = generate_item(current_tag, len(feed_items))
128
  feed_items.append(new_item)
129
+ html_content = generate_html(feed_items, scroll_to_latest=True)
130
  return current_tag, feed_items, html_content
131
 
132
+ def generate_html(feed_items, scroll_to_latest=False):
133
  """
134
+ Generate an HTML string to display the feed items in a TikTok-like carousel.
135
 
136
  Args:
137
  feed_items (list): List of dictionaries containing 'text' and 'image_base64'.
138
+ scroll_to_latest (bool): Whether to auto-scroll to the latest item.
139
 
140
  Returns:
141
  str: HTML string representing the feed.
142
  """
143
  html_str = """
144
+ <div id="feed-container" style="
145
  display: flex;
146
  flex-direction: column;
147
  align-items: center;
 
149
  margin: 0 auto;
150
  background-color: #000;
151
  height: 640px;
152
+ overflow-y: scroll;
153
+ scroll-snap-type: y mandatory;
154
  scrollbar-width: none;
155
  -ms-overflow-style: none;
156
  border: 1px solid #333;
157
  border-radius: 10px;
158
  ">
159
  """
160
+ # Hide scrollbar
161
  html_str += """
162
  <style>
163
+ #feed-container::-webkit-scrollbar {
164
  display: none;
165
  }
166
+ .feed-item {
167
+ scroll-snap-align: start;
168
+ }
169
  </style>
170
  """
171
+ for idx, item in enumerate(feed_items):
172
  html_str += f"""
173
+ <div class="feed-item" id="item-{idx}" style="
174
  width: 100%;
175
  height: 640px;
176
  position: relative;
 
204
  </div>
205
  """
206
  html_str += "</div>"
207
+
208
+ # Auto-scroll to the latest item if requested
209
+ if scroll_to_latest and feed_items:
210
+ html_str += f"""
211
+ <script>
212
+ document.getElementById('item-{len(feed_items) - 1}').scrollIntoView({{ behavior: 'smooth' }});
213
+ </script>
214
+ """
215
+
216
  return html_str
217
 
218
  # Define the Gradio interface