Update app.py
Browse files
app.py
CHANGED
@@ -31,16 +31,16 @@ def generate_ideas(tag):
|
|
31 |
Return the response as a JSON object with a single key 'ideas' containing a list of 5 ideas.
|
32 |
Example: {{"ideas": ["A neon-lit gaming setup with RGB lights flashing", "A futuristic robot assembling a gadget"]}}
|
33 |
"""
|
34 |
-
response = client.models.generate_content(
|
35 |
-
model='gemini-2.5-flash-preview-04-17',
|
36 |
-
contents=[prompt],
|
37 |
-
config=types.GenerateContentConfig(temperature=1.2)
|
38 |
-
)
|
39 |
try:
|
|
|
|
|
|
|
|
|
|
|
40 |
response_json = json.loads(response.text.strip())
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
return [
|
45 |
f"A vibrant {tag} scene at sunset",
|
46 |
f"A close-up of {tag} with neon lights",
|
@@ -69,33 +69,37 @@ def generate_item(tag, ideas):
|
|
69 |
The image prompt should describe the scene vividly, specify a perspective and style, and ensure no text or letters are included.
|
70 |
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"}}
|
71 |
"""
|
72 |
-
response = client.models.generate_content(
|
73 |
-
model='gemini-2.5-flash-preview-04-17',
|
74 |
-
contents=[prompt],
|
75 |
-
config=types.GenerateContentConfig(temperature=1.2)
|
76 |
-
)
|
77 |
try:
|
|
|
|
|
|
|
|
|
|
|
78 |
response_json = json.loads(response.text.strip())
|
79 |
text = response_json['caption']
|
80 |
image_prompt = response_json['image_prompt']
|
81 |
-
except
|
|
|
82 |
text = f"Obsessed with {tag}! π₯ #{tag}"
|
83 |
image_prompt = f"A vivid scene of {selected_idea}, in a vibrant pop art style, no text or letters"
|
84 |
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
|
|
|
|
92 |
)
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
|
|
99 |
image = Image.new('RGB', (360, 640), color='gray')
|
100 |
|
101 |
buffered = BytesIO()
|
@@ -104,7 +108,7 @@ def generate_item(tag, ideas):
|
|
104 |
|
105 |
return {'text': text, 'image_base64': img_str, 'ideas': ideas}
|
106 |
|
107 |
-
def start_feed(tag, current_index, feed_items
|
108 |
"""
|
109 |
Start or update the feed based on the tag.
|
110 |
|
@@ -112,7 +116,6 @@ def start_feed(tag, current_index, feed_items, is_loading):
|
|
112 |
tag (str): The tag to generate content for.
|
113 |
current_index (int): The current item index.
|
114 |
feed_items (list): The current list of feed items.
|
115 |
-
is_loading (bool): Whether the feed is currently loading.
|
116 |
|
117 |
Returns:
|
118 |
tuple: (current_tag, current_index, feed_items, html_content, is_loading)
|
@@ -120,18 +123,25 @@ def start_feed(tag, current_index, feed_items, is_loading):
|
|
120 |
if not tag.strip():
|
121 |
tag = "trending"
|
122 |
|
|
|
123 |
is_loading = True
|
124 |
yield tag, current_index, feed_items, generate_html([], False, 0, tag, is_loading), is_loading
|
125 |
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
|
|
|
|
|
|
|
|
|
|
130 |
|
|
|
131 |
is_loading = False
|
132 |
return tag, current_index, feed_items, generate_html(feed_items, False, current_index, tag, is_loading), is_loading
|
133 |
|
134 |
-
def load_next(tag, current_index, feed_items
|
135 |
"""
|
136 |
Load the next item in the feed.
|
137 |
|
@@ -139,7 +149,6 @@ def load_next(tag, current_index, feed_items, is_loading):
|
|
139 |
tag (str): The tag to generate content for.
|
140 |
current_index (int): The current item index.
|
141 |
feed_items (list): The current list of feed items.
|
142 |
-
is_loading (bool): Whether the feed is currently loading.
|
143 |
|
144 |
Returns:
|
145 |
tuple: (current_tag, current_index, feed_items, html_content, is_loading)
|
@@ -147,18 +156,22 @@ def load_next(tag, current_index, feed_items, is_loading):
|
|
147 |
is_loading = True
|
148 |
yield tag, current_index, feed_items, generate_html(feed_items, False, current_index, tag, is_loading), is_loading
|
149 |
|
150 |
-
|
151 |
-
current_index
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
|
|
|
|
|
|
|
|
157 |
|
158 |
is_loading = False
|
159 |
return tag, current_index, feed_items, generate_html(feed_items, False, current_index, tag, is_loading), is_loading
|
160 |
|
161 |
-
def load_previous(tag, current_index, feed_items
|
162 |
"""
|
163 |
Load the previous item in the feed.
|
164 |
|
@@ -166,14 +179,13 @@ def load_previous(tag, current_index, feed_items, is_loading):
|
|
166 |
tag (str): The tag to generate content for.
|
167 |
current_index (int): The current item index.
|
168 |
feed_items (list): The current list of feed items.
|
169 |
-
is_loading (bool): Whether the feed is currently loading.
|
170 |
|
171 |
Returns:
|
172 |
tuple: (current_tag, current_index, feed_items, html_content, is_loading)
|
173 |
"""
|
174 |
if current_index > 0:
|
175 |
current_index -= 1
|
176 |
-
return tag, current_index, feed_items, generate_html(feed_items, False, current_index, tag,
|
177 |
|
178 |
def generate_html(feed_items, scroll_to_latest=False, current_index=0, tag="", is_loading=False):
|
179 |
"""
|
@@ -189,7 +201,6 @@ def generate_html(feed_items, scroll_to_latest=False, current_index=0, tag="", i
|
|
189 |
Returns:
|
190 |
str: HTML string representing the feed.
|
191 |
"""
|
192 |
-
# Define loading messages based on the tag
|
193 |
loading_messages = [
|
194 |
f"Cooking up a {tag} masterpiece... π³",
|
195 |
f"Snapping a vibrant {tag} moment... πΈ",
|
@@ -392,34 +403,33 @@ with gr.Blocks(
|
|
392 |
outputs=tag_input
|
393 |
).then(
|
394 |
fn=start_feed,
|
395 |
-
inputs=[tag_input, current_index, feed_items
|
396 |
outputs=[current_tag, current_index, feed_items, feed_html, is_loading]
|
397 |
)
|
398 |
|
399 |
# Handle Enter keypress in the custom tag input
|
400 |
tag_input.submit(
|
401 |
fn=start_feed,
|
402 |
-
inputs=[tag_input, current_index, feed_items
|
403 |
outputs=[current_tag, current_index, feed_items, feed_html, is_loading]
|
404 |
)
|
405 |
|
406 |
-
# Hidden
|
407 |
next_button = gr.Button("Next", elem_id="next-button", visible=False)
|
408 |
previous_button = gr.Button("Previous", elem_id="previous-button", visible=False)
|
409 |
|
410 |
# Handle click to go to next item
|
411 |
next_button.click(
|
412 |
fn=load_next,
|
413 |
-
inputs=[current_tag, current_index, feed_items
|
414 |
outputs=[current_tag, current_index, feed_items, feed_html, is_loading]
|
415 |
)
|
416 |
|
417 |
# Handle click to go to previous item
|
418 |
previous_button.click(
|
419 |
fn=load_previous,
|
420 |
-
inputs=[current_tag, current_index, feed_items
|
421 |
outputs=[current_tag, current_index, feed_items, feed_html, is_loading]
|
422 |
)
|
423 |
|
424 |
-
|
425 |
-
demo.launch(share=True)
|
|
|
31 |
Return the response as a JSON object with a single key 'ideas' containing a list of 5 ideas.
|
32 |
Example: {{"ideas": ["A neon-lit gaming setup with RGB lights flashing", "A futuristic robot assembling a gadget"]}}
|
33 |
"""
|
|
|
|
|
|
|
|
|
|
|
34 |
try:
|
35 |
+
response = client.models.generate_content(
|
36 |
+
model='gemini-2.5-flash-preview-04-17',
|
37 |
+
contents=[prompt],
|
38 |
+
config=types.GenerateContentConfig(temperature=1.2)
|
39 |
+
)
|
40 |
response_json = json.loads(response.text.strip())
|
41 |
+
return response_json['ideas']
|
42 |
+
except Exception as e:
|
43 |
+
print(f"Error generating ideas: {e}")
|
44 |
return [
|
45 |
f"A vibrant {tag} scene at sunset",
|
46 |
f"A close-up of {tag} with neon lights",
|
|
|
69 |
The image prompt should describe the scene vividly, specify a perspective and style, and ensure no text or letters are included.
|
70 |
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"}}
|
71 |
"""
|
|
|
|
|
|
|
|
|
|
|
72 |
try:
|
73 |
+
response = client.models.generate_content(
|
74 |
+
model='gemini-2.5-flash-preview-04-17',
|
75 |
+
contents=[prompt],
|
76 |
+
config=types.GenerateContentConfig(temperature=1.2)
|
77 |
+
)
|
78 |
response_json = json.loads(response.text.strip())
|
79 |
text = response_json['caption']
|
80 |
image_prompt = response_json['image_prompt']
|
81 |
+
except Exception as e:
|
82 |
+
print(f"Error generating item: {e}")
|
83 |
text = f"Obsessed with {tag}! π₯ #{tag}"
|
84 |
image_prompt = f"A vivid scene of {selected_idea}, in a vibrant pop art style, no text or letters"
|
85 |
|
86 |
+
try:
|
87 |
+
image_response = client.models.generate_images(
|
88 |
+
model='imagen-3.0-generate-002',
|
89 |
+
prompt=image_prompt,
|
90 |
+
config=types.GenerateImagesConfig(
|
91 |
+
number_of_images=1,
|
92 |
+
aspect_ratio="9:16",
|
93 |
+
person_generation="DONT_ALLOW"
|
94 |
+
)
|
95 |
)
|
96 |
+
if image_response.generated_images and len(image_response.generated_images) > 0:
|
97 |
+
generated_image = image_response.generated_images[0]
|
98 |
+
image = Image.open(BytesIO(generated_image.image.image_bytes))
|
99 |
+
else:
|
100 |
+
image = Image.new('RGB', (360, 640), color='gray')
|
101 |
+
except Exception as e:
|
102 |
+
print(f"Error generating image: {e}")
|
103 |
image = Image.new('RGB', (360, 640), color='gray')
|
104 |
|
105 |
buffered = BytesIO()
|
|
|
108 |
|
109 |
return {'text': text, 'image_base64': img_str, 'ideas': ideas}
|
110 |
|
111 |
+
def start_feed(tag, current_index, feed_items):
|
112 |
"""
|
113 |
Start or update the feed based on the tag.
|
114 |
|
|
|
116 |
tag (str): The tag to generate content for.
|
117 |
current_index (int): The current item index.
|
118 |
feed_items (list): The current list of feed items.
|
|
|
119 |
|
120 |
Returns:
|
121 |
tuple: (current_tag, current_index, feed_items, html_content, is_loading)
|
|
|
123 |
if not tag.strip():
|
124 |
tag = "trending"
|
125 |
|
126 |
+
# Set loading state
|
127 |
is_loading = True
|
128 |
yield tag, current_index, feed_items, generate_html([], False, 0, tag, is_loading), is_loading
|
129 |
|
130 |
+
try:
|
131 |
+
ideas = generate_ideas(tag)
|
132 |
+
item = generate_item(tag, ideas)
|
133 |
+
feed_items = [item]
|
134 |
+
current_index = 0
|
135 |
+
except Exception as e:
|
136 |
+
print(f"Error in start_feed: {e}")
|
137 |
+
feed_items = []
|
138 |
+
current_index = 0
|
139 |
|
140 |
+
# Set loading state to False and update UI
|
141 |
is_loading = False
|
142 |
return tag, current_index, feed_items, generate_html(feed_items, False, current_index, tag, is_loading), is_loading
|
143 |
|
144 |
+
def load_next(tag, current_index, feed_items):
|
145 |
"""
|
146 |
Load the next item in the feed.
|
147 |
|
|
|
149 |
tag (str): The tag to generate content for.
|
150 |
current_index (int): The current item index.
|
151 |
feed_items (list): The current list of feed items.
|
|
|
152 |
|
153 |
Returns:
|
154 |
tuple: (current_tag, current_index, feed_items, html_content, is_loading)
|
|
|
156 |
is_loading = True
|
157 |
yield tag, current_index, feed_items, generate_html(feed_items, False, current_index, tag, is_loading), is_loading
|
158 |
|
159 |
+
try:
|
160 |
+
if current_index + 1 < len(feed_items):
|
161 |
+
current_index += 1
|
162 |
+
else:
|
163 |
+
ideas = feed_items[-1]['ideas'] if feed_items else generate_ideas(tag)
|
164 |
+
new_item = generate_item(tag, ideas)
|
165 |
+
feed_items.append(new_item)
|
166 |
+
current_index = len(feed_items) - 1
|
167 |
+
except Exception as e:
|
168 |
+
print(f"Error in load_next: {e}")
|
169 |
+
current_index = max(0, current_index)
|
170 |
|
171 |
is_loading = False
|
172 |
return tag, current_index, feed_items, generate_html(feed_items, False, current_index, tag, is_loading), is_loading
|
173 |
|
174 |
+
def load_previous(tag, current_index, feed_items):
|
175 |
"""
|
176 |
Load the previous item in the feed.
|
177 |
|
|
|
179 |
tag (str): The tag to generate content for.
|
180 |
current_index (int): The current item index.
|
181 |
feed_items (list): The current list of feed items.
|
|
|
182 |
|
183 |
Returns:
|
184 |
tuple: (current_tag, current_index, feed_items, html_content, is_loading)
|
185 |
"""
|
186 |
if current_index > 0:
|
187 |
current_index -= 1
|
188 |
+
return tag, current_index, feed_items, generate_html(feed_items, False, current_index, tag, False), False
|
189 |
|
190 |
def generate_html(feed_items, scroll_to_latest=False, current_index=0, tag="", is_loading=False):
|
191 |
"""
|
|
|
201 |
Returns:
|
202 |
str: HTML string representing the feed.
|
203 |
"""
|
|
|
204 |
loading_messages = [
|
205 |
f"Cooking up a {tag} masterpiece... π³",
|
206 |
f"Snapping a vibrant {tag} moment... πΈ",
|
|
|
403 |
outputs=tag_input
|
404 |
).then(
|
405 |
fn=start_feed,
|
406 |
+
inputs=[tag_input, current_index, feed_items],
|
407 |
outputs=[current_tag, current_index, feed_items, feed_html, is_loading]
|
408 |
)
|
409 |
|
410 |
# Handle Enter keypress in the custom tag input
|
411 |
tag_input.submit(
|
412 |
fn=start_feed,
|
413 |
+
inputs=[tag_input, current_index, feed_items],
|
414 |
outputs=[current_tag, current_index, feed_items, feed_html, is_loading]
|
415 |
)
|
416 |
|
417 |
+
# Hidden buttons for navigation
|
418 |
next_button = gr.Button("Next", elem_id="next-button", visible=False)
|
419 |
previous_button = gr.Button("Previous", elem_id="previous-button", visible=False)
|
420 |
|
421 |
# Handle click to go to next item
|
422 |
next_button.click(
|
423 |
fn=load_next,
|
424 |
+
inputs=[current_tag, current_index, feed_items],
|
425 |
outputs=[current_tag, current_index, feed_items, feed_html, is_loading]
|
426 |
)
|
427 |
|
428 |
# Handle click to go to previous item
|
429 |
previous_button.click(
|
430 |
fn=load_previous,
|
431 |
+
inputs=[current_tag, current_index, feed_items],
|
432 |
outputs=[current_tag, current_index, feed_items, feed_html, is_loading]
|
433 |
)
|
434 |
|
435 |
+
demo.launch()
|
|