cngsm commited on
Commit
5b3113e
·
verified ·
1 Parent(s): da076f9

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +268 -0
  2. requirements.txt +1 -0
app.py ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import random
4
+ import json
5
+ import os
6
+ from together import Together
7
+ import base64
8
+ from PIL import Image
9
+ import io
10
+
11
+ # --- Environment Variable for Together API Key ---
12
+ TOGETHER_API_KEY = os.environ.get('TOGETHER_API_KEY')
13
+
14
+ # --- Together API Client Configuration ---
15
+ # Initialize the Together client only if the API key is available
16
+ client = Together(api_key=TOGETHER_API_KEY) if TOGETHER_API_KEY else None
17
+
18
+ # --- Pixabay API Configuration ---
19
+ PIXABAY_API_KEY = os.environ.get('PIXABAY_API_KEY')
20
+ IMAGE_API_URL = 'https://pixabay.com/api/'
21
+ VIDEO_API_URL = 'https://pixabay.com/api/videos/'
22
+ PER_PAGE = 5
23
+
24
+ # --- Function to search Pixabay ---
25
+ def search_pixabay(query: str, media_type: str, image_type: str, orientation: str, video_type: str):
26
+ """
27
+ Searches the Pixabay API for royalty-free stock images or videos based on user query and filters.
28
+ Args:
29
+ query (str): The search term for finding media. If empty, an error is returned.
30
+ media_type (str): Specifies the type of media to search for.
31
+ Accepted values are "Image" or "Video".
32
+ image_type (str): Filter results by image type (used only if media_type is "Image").
33
+ Accepted values: "all", "photo", "illustration", "vector".
34
+ orientation (str): Filter results by image orientation (used only if media_type is "Image").
35
+ Accepted values: "all", "horizontal", "vertical".
36
+ video_type (str): Filter results by video type (used only if media_type is "Video").
37
+ Accepted values: "all", "film", "animation".
38
+ """
39
+ if not query:
40
+ return None, None, "Please enter a search query."
41
+
42
+ if not PIXABAY_API_KEY:
43
+ return None, None, "Pixabay API Key not found. Please set the PIXABAY_API_KEY environment variable."
44
+
45
+ params = {
46
+ 'key': PIXABAY_API_KEY,
47
+ 'q': query,
48
+ 'per_page': PER_PAGE,
49
+ 'page': 1,
50
+ 'safesearch': 'true'
51
+ }
52
+
53
+ if media_type == "Image":
54
+ api_url = IMAGE_API_URL
55
+ params['image_type'] = image_type
56
+ params['orientation'] = orientation
57
+ elif media_type == "Video":
58
+ api_url = VIDEO_API_URL
59
+ params['video_type'] = video_type
60
+ else:
61
+ # This case should not be reachable with the Gradio Radio component
62
+ return None, None, "Invalid media type selected."
63
+
64
+ try:
65
+ response = requests.get(api_url, params=params)
66
+ response.raise_for_status()
67
+ data = response.json()
68
+
69
+ if data.get('totalHits', 0) == 0:
70
+ return None, None, f"No results found for '{query}'."
71
+
72
+ hits = data.get('hits', [])
73
+ if not hits:
74
+ return None, None, f"No results found for '{query}'."
75
+
76
+ selected_hit = random.choice(hits)
77
+
78
+ if media_type == "Image":
79
+ image_url = selected_hit.get('largeImageURL')
80
+ if image_url:
81
+ # Return the image URL, None for video, and an empty status message
82
+ return image_url, None, ""
83
+ else:
84
+ return None, None, "Could not retrieve large image URL."
85
+
86
+ elif media_type == "Video":
87
+ video_urls = selected_hit.get('videos', {})
88
+ large_video = video_urls.get('large', {})
89
+ video_url = large_video.get('url')
90
+
91
+ if video_url:
92
+ # Return None for image, the video URL, and an empty status message
93
+ return None, video_url, ""
94
+ else:
95
+ # Fallback to medium quality if large is not available
96
+ medium_video = video_urls.get('medium', {})
97
+ video_url = medium_video.get('url')
98
+ if video_url:
99
+ return None, video_url, "Using medium quality video."
100
+ else:
101
+ return None, None, "Could not retrieve video URL."
102
+
103
+ except requests.exceptions.RequestException as e:
104
+ return None, None, f"API request error: {e}"
105
+ except json.JSONDecodeError:
106
+ return None, None, "Error decoding API response."
107
+ except Exception as e:
108
+ # Catch any other unexpected errors
109
+ return None, None, f"An unexpected error occurred: {e}"
110
+
111
+ # --- Together AI Image Generation Functions ---
112
+ def together_text_to_image(prompt: str):
113
+ """
114
+ Generates an image from text using the Together AI API.
115
+ Args:
116
+ prompt (str): The text prompt for image generation.
117
+ Returns:
118
+ str: The URL of the generated image, or an error message.
119
+ """
120
+ if not client:
121
+ return "Together AI client not initialized. Please set the TOGETHER_API_KEY environment variable."
122
+ if not prompt:
123
+ return "Please enter a prompt for text-to-image generation."
124
+
125
+ try:
126
+ image_completion = client.images.generate(
127
+ model="black-forest-labs/FLUX.1.1-pro", # Hardcoded model as requested
128
+ width=1024,
129
+ height=768,
130
+ steps=40,
131
+ prompt=prompt,
132
+ )
133
+ return image_completion.data[0].url
134
+ except Exception as e:
135
+ return f"Error generating image from text: {e}"
136
+
137
+ def image_to_url(image_path):
138
+ try:
139
+ url = 'https://uguu.se/upload'
140
+
141
+ with open(image_path, 'rb') as f:
142
+ files = {'files[]': (image_path, f)}
143
+ response = requests.post(url, files=files)
144
+ response_json = response.json()
145
+ return response_json['files'][0]['url']
146
+ except FileNotFoundError:
147
+ return "Error: File not found. Please check the image path."
148
+ except Exception as e:
149
+ return f"An error occurred: {e}"
150
+
151
+ def together_image_to_image(image_numpy, prompt: str):
152
+ """
153
+ Transforms an image based on a text prompt using the Together AI API.
154
+ Args:
155
+ image_numpy (numpy.ndarray): The input image as a NumPy array (provided by Gradio).
156
+ prompt (str): The text prompt for image transformation.
157
+ Returns:
158
+ str: The URL of the transformed image, or an error message.
159
+ """
160
+ if not client:
161
+ return "Together AI client not initialized. Please set the TOGETHER_API_KEY environment variable."
162
+ if image_numpy is None:
163
+ return "Please upload or paste an image for image-to-image transformation."
164
+ if not prompt:
165
+ return "Please enter a prompt for image transformation."
166
+
167
+ try:
168
+
169
+ print(image_numpy)
170
+
171
+ image_completion = client.images.generate(
172
+ model="black-forest-labs/FLUX.1-kontext-max", # Hardcoded model as requested
173
+ steps=40, # Hardcoded steps as requested
174
+ prompt=prompt,
175
+ image_url=image_to_url(image_numpy)
176
+ )
177
+ return image_completion.data[0].url
178
+ except Exception as e:
179
+ return f"Error transforming image: {e}"
180
+
181
+
182
+ # --- Gradio Blocks Interface Definition ---
183
+ with gr.Blocks(title="Media Generation and Search Explorer") as demo:
184
+ gr.Markdown("## Media Generation and Search Explorer")
185
+ gr.Markdown("Explore royalty-free media from Pixabay and generate/transform images using Together AI.")
186
+
187
+ with gr.Tab("Pixabay Search"):
188
+ gr.Markdown("Search for royalty-free images and videos on Pixabay.")
189
+ gr.Warning("This requires setting the PIXABAY_API_KEY environment variable.")
190
+ with gr.Row():
191
+ pixabay_query_input = gr.Textbox(label="Search Query", placeholder="e.g., yellow flowers", scale=2)
192
+ pixabay_media_type_radio = gr.Radio(["Image", "Video"], label="Media Type", value="Image", scale=1)
193
+ pixabay_search_button = gr.Button("Search")
194
+
195
+ with gr.Column(visible=True) as pixabay_image_options_col:
196
+ pixabay_image_type_input = gr.Radio(["all", "photo", "illustration", "vector"], label="Image Type", value="all")
197
+ pixabay_orientation_input = gr.Radio(["all", "horizontal", "vertical"], label="Orientation", value="all")
198
+
199
+ with gr.Column(visible=False) as pixabay_video_options_col:
200
+ pixabay_video_type_input = gr.Radio(["all", "film", "animation"], label="Video Type", value="all")
201
+
202
+ pixabay_status_output = gr.Textbox(label="Status", interactive=False)
203
+
204
+ with gr.Row():
205
+ pixabay_image_output = gr.Image(label="Result Image (URL)", interactive=False)
206
+ pixabay_video_output = gr.Video(label="Result Video (URL)", interactive=False)
207
+
208
+ # Logic to toggle visibility of input columns and output components based on media type selection
209
+ def update_pixabay_inputs_blocks(media_type):
210
+ if media_type == "Image":
211
+ return gr.update(visible=True), gr.update(visible=False), gr.update(visible=True), gr.update(visible=False)
212
+ elif media_type == "Video":
213
+ return gr.update(visible=False), gr.update(visible=True), gr.update(visible=False), gr.update(visible=True)
214
+ else:
215
+ return gr.update(visible=True), gr.update(visible=False), gr.update(visible=True), gr.update(visible=False)
216
+
217
+ # Trigger the update_pixabay_inputs_blocks function when media_type_radio changes
218
+ pixabay_media_type_radio.change(
219
+ fn=update_pixabay_inputs_blocks,
220
+ inputs=pixabay_media_type_radio,
221
+ outputs=[pixabay_image_options_col, pixabay_video_options_col, pixabay_image_output, pixabay_video_output]
222
+ )
223
+
224
+ # Trigger the search_pixabay function when the search button is clicked
225
+ pixabay_search_button.click(
226
+ fn=search_pixabay,
227
+ inputs=[
228
+ pixabay_query_input,
229
+ pixabay_media_type_radio,
230
+ pixabay_image_type_input,
231
+ pixabay_orientation_input,
232
+ pixabay_video_type_input
233
+ ],
234
+ outputs=[pixabay_image_output, pixabay_video_output, pixabay_status_output]
235
+ )
236
+
237
+ with gr.Tab("Together AI - Text to Image"):
238
+ gr.Markdown("Generate an image from a text prompt using Together AI.")
239
+ gr.Warning("This requires setting the TOGETHER_API_KEY environment variable.")
240
+ with gr.Row():
241
+ together_text_to_image_prompt = gr.Textbox(label="Enter your prompt", scale=2)
242
+ together_text_to_image_button = gr.Button("Generate Image", scale=1)
243
+ together_text_to_image_output = gr.Image(label="Generated Image (URL)", type="filepath", interactive=False)
244
+
245
+ together_text_to_image_button.click(
246
+ fn=together_text_to_image,
247
+ inputs=together_text_to_image_prompt,
248
+ outputs=together_text_to_image_output,
249
+ )
250
+
251
+ with gr.Tab("Together AI - Image to Image"):
252
+ gr.Markdown("Transform an uploaded image based on a text prompt using Together AI.")
253
+ gr.Warning("This requires setting the TOGETHER_API_KEY environment variable.")
254
+ with gr.Row():
255
+ together_image_input = gr.Image(label="Upload or paste an image", type="filepath", scale=2)
256
+ together_image_to_image_prompt = gr.Textbox(label="Enter your transformation prompt", scale=2)
257
+ together_image_to_image_button = gr.Button("Transform Image", scale=1)
258
+ together_image_to_image_output = gr.Image(label="Transformed Image (URL)", type="filepath", interactive=False)
259
+
260
+ together_image_to_image_button.click(
261
+ fn=together_image_to_image,
262
+ inputs=[together_image_input, together_image_to_image_prompt],
263
+ outputs=together_image_to_image_output,
264
+ )
265
+
266
+ # --- Launch the Gradio app ---
267
+ if __name__ == "__main__":
268
+ demo.launch(mcp_server=True)
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ together