openfree commited on
Commit
fb5884e
ยท
verified ยท
1 Parent(s): e8350a7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +106 -103
app.py CHANGED
@@ -14,133 +14,137 @@ os.environ['REPLICATE_API_TOKEN'] = os.getenv('REPLICATE_API_TOKEN')
14
  def upload_to_imgur(image):
15
  """
16
  Upload image to Imgur and return URL
17
- Alternative: You can use other services like Cloudinary, imgbb, etc.
18
  """
19
- import base64
20
- import json
21
-
22
- # Convert PIL image to base64
23
- buffered = BytesIO()
24
- image.save(buffered, format="PNG")
25
- img_base64 = base64.b64encode(buffered.getvalue()).decode()
26
-
27
- # Imgur API (anonymous upload)
28
- headers = {
29
- 'Authorization': 'Client-ID 0d90e8a3e7d8b4e' # Public client ID for anonymous uploads
30
- }
31
-
32
- response = requests.post(
33
- 'https://api.imgur.com/3/image',
34
- headers=headers,
35
- data={'image': img_base64}
36
- )
37
-
38
- if response.status_code == 200:
39
- data = response.json()
40
- return data['data']['link']
41
- else:
42
- raise Exception(f"Failed to upload to Imgur: {response.status_code}")
 
 
 
 
 
 
 
 
43
 
44
  def process_images(prompt, image1, image2=None):
45
  """
46
  Process uploaded images with Replicate API
47
  """
48
  if not image1:
49
- return None, "Please upload at least one image"
50
 
51
  # Check if API token is set
52
  if not os.getenv('REPLICATE_API_TOKEN'):
53
  return None, "โš ๏ธ Please set REPLICATE_API_TOKEN environment variable"
54
 
55
  try:
56
- status_message = "๐Ÿ“ค Uploading images..."
57
-
58
- # Upload images to get public URLs
59
  image_urls = []
60
 
61
- try:
62
- # Try to upload to Imgur (or your preferred service)
63
- url1 = upload_to_imgur(image1)
64
  image_urls.append(url1)
65
-
66
- if image2:
67
- url2 = upload_to_imgur(image2)
68
- image_urls.append(url2)
69
-
70
- except Exception as upload_error:
71
- # Fallback: Convert to base64 data URIs
72
- buffered1 = BytesIO()
73
- image1.save(buffered1, format="PNG")
74
- img_base64_1 = base64.b64encode(buffered1.getvalue()).decode()
75
- image_urls.append(f"data:image/png;base64,{img_base64_1}")
76
-
77
- if image2:
78
- buffered2 = BytesIO()
79
- image2.save(buffered2, format="PNG")
80
- img_base64_2 = base64.b64encode(buffered2.getvalue()).decode()
81
- image_urls.append(f"data:image/png;base64,{img_base64_2}")
82
 
83
- status_message = "๐ŸŽจ Processing with nano-banana model..."
 
 
 
84
 
85
- # Prepare input matching the exact format from your example
86
  input_data = {
87
  "prompt": prompt,
88
  "image_input": image_urls
89
  }
90
 
91
- # Run the model
 
 
92
  output = replicate.run(
93
  "google/nano-banana",
94
  input=input_data
95
  )
96
 
97
- # Handle various output formats
98
- output_url = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
- # Check different possible output formats
101
- if hasattr(output, 'url'):
102
- output_url = output.url()
103
- elif isinstance(output, str):
104
  output_url = output
105
  elif isinstance(output, list) and len(output) > 0:
106
  output_url = output[0]
107
- elif hasattr(output, '__iter__'):
108
- try:
109
- for item in output:
110
- if isinstance(item, str) and item.startswith('http'):
111
- output_url = item
112
- break
113
- except:
114
- pass
115
 
116
- if not output_url:
117
- return None, f"โŒ Error: No valid output URL found. Response type: {type(output)}"
118
-
119
- # Download the generated image
120
- if hasattr(output, 'read'):
121
- # If output has a read method, use it
122
- img_data = output.read()
123
- img = Image.open(BytesIO(img_data))
124
- else:
125
- # Otherwise, download from URL
126
- response = requests.get(output_url)
127
  if response.status_code == 200:
128
  img = Image.open(BytesIO(response.content))
129
- else:
130
- return None, f"โŒ Error: Failed to download image (Status: {response.status_code})"
131
 
132
- return img, f"โœ… Image generated successfully! Output URL: {output_url[:50]}..."
133
 
134
- except replicate.exceptions.ModelError as e:
135
- return None, f"โŒ Model Error: {str(e)}\n\nMake sure 'google/nano-banana' exists and is accessible."
136
- except Exception as e:
137
  error_msg = str(e)
138
- if "not found" in error_msg.lower():
139
- return None, "โŒ Model 'google/nano-banana' not found. Please check:\n1. Model name is correct\n2. Model is public or you have access\n3. Try format: 'owner/model-name'"
140
- elif "authentication" in error_msg.lower():
141
- return None, "โŒ Authentication failed. Please check your REPLICATE_API_TOKEN."
 
 
 
 
142
  else:
143
- return None, f"โŒ Error: {error_msg}"
 
 
144
 
145
  # Create Gradio interface with gradient theme
146
  css = """
@@ -189,7 +193,7 @@ with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
189
  <div class="header-text">๐ŸŽจ AI Image Style Transfer Studio</div>
190
  <div class="description-text">
191
  Upload 1-2 images and describe how you want them styled.
192
- The AI will create a beautiful transformation!
193
  </div>
194
  """)
195
 
@@ -226,7 +230,7 @@ with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
226
  #### ๐Ÿ’ก Tips:
227
  - Upload high-quality images for best results
228
  - Be specific in your style description
229
- - Experiment with different prompts!
230
  """)
231
 
232
  with gr.Column(scale=1):
@@ -248,10 +252,10 @@ with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
248
  with gr.Row():
249
  gr.Examples(
250
  examples=[
 
251
  ["Transform into watercolor painting style", None, None],
252
  ["Make it look like a vintage photograph", None, None],
253
  ["Apply cyberpunk neon style", None, None],
254
- ["Convert to minimalist line art", None, None],
255
  ],
256
  inputs=[prompt, image1, image2],
257
  label="Example Prompts"
@@ -272,7 +276,7 @@ with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
272
 
273
  1. **Set Environment Variable:**
274
  ```bash
275
- export REPLICATE_API_TOKEN="your_api_token_here"
276
  ```
277
  Get your token from: https://replicate.com/account/api-tokens
278
 
@@ -281,22 +285,21 @@ with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
281
  pip install gradio replicate pillow requests
282
  ```
283
 
284
- 3. **Image Hosting Options:**
285
- - **Option A**: Uses Imgur for free image hosting (default)
286
- - **Option B**: Falls back to base64 data URIs if upload fails
287
- - **Option C**: Use your own image hosting service (Cloudinary, S3, etc.)
 
 
288
 
289
- 4. **Model Notes:**
290
- - Using: `google/nano-banana` model
291
- - If this model doesn't exist, try:
292
- - `stability-ai/stable-diffusion`
293
- - `pharmapsychotic/clip-interrogator`
294
- - Check available models at: https://replicate.com/explore
295
 
296
  ### ๐Ÿ”’ Security:
297
  - API keys are managed through environment variables
298
  - Never commit API keys to version control
299
- - Consider implementing user authentication for production
300
  """)
301
 
302
  # Launch the app
 
14
  def upload_to_imgur(image):
15
  """
16
  Upload image to Imgur and return URL
 
17
  """
18
+ try:
19
+ # Convert PIL image to base64
20
+ buffered = BytesIO()
21
+ image.save(buffered, format="PNG")
22
+ buffered.seek(0)
23
+ img_base64 = base64.b64encode(buffered.getvalue()).decode()
24
+
25
+ # Imgur API (anonymous upload)
26
+ headers = {
27
+ 'Authorization': 'Client-ID 0d90e8a3e7d8b4e' # Public client ID
28
+ }
29
+
30
+ response = requests.post(
31
+ 'https://api.imgur.com/3/image',
32
+ headers=headers,
33
+ data={'image': img_base64}
34
+ )
35
+
36
+ if response.status_code == 200:
37
+ data = response.json()
38
+ return data['data']['link']
39
+ except:
40
+ pass
41
+ return None
42
+
43
+ def save_temp_image(image):
44
+ """
45
+ Save image temporarily and return file path
46
+ """
47
+ with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as tmp:
48
+ image.save(tmp.name, 'PNG')
49
+ return tmp.name
50
 
51
  def process_images(prompt, image1, image2=None):
52
  """
53
  Process uploaded images with Replicate API
54
  """
55
  if not image1:
56
+ return None, "โŒ Please upload at least one image"
57
 
58
  # Check if API token is set
59
  if not os.getenv('REPLICATE_API_TOKEN'):
60
  return None, "โš ๏ธ Please set REPLICATE_API_TOKEN environment variable"
61
 
62
  try:
63
+ # Prepare image URLs list
 
 
64
  image_urls = []
65
 
66
+ # Try to upload images to Imgur to get public URLs
67
+ url1 = upload_to_imgur(image1)
68
+ if url1:
69
  image_urls.append(url1)
70
+ else:
71
+ # If Imgur fails, you need to use another service or local server
72
+ # For now, we'll save locally (note: this won't work with Replicate)
73
+ return None, "โš ๏ธ Image hosting failed. Please try again or use a different hosting service."
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
+ if image2:
76
+ url2 = upload_to_imgur(image2)
77
+ if url2:
78
+ image_urls.append(url2)
79
 
80
+ # Prepare input exactly as shown in your example
81
  input_data = {
82
  "prompt": prompt,
83
  "image_input": image_urls
84
  }
85
 
86
+ print(f"Sending to Replicate: {input_data}")
87
+
88
+ # Run the model exactly as in your example
89
  output = replicate.run(
90
  "google/nano-banana",
91
  input=input_data
92
  )
93
 
94
+ # Process output - based on your example, output should have url() and read() methods
95
+ if output is None:
96
+ return None, "โŒ No output received from model"
97
+
98
+ # Try different methods to get the image
99
+ try:
100
+ # Method 1: Using read() method as in your example
101
+ if hasattr(output, 'read'):
102
+ img_data = output.read()
103
+ img = Image.open(BytesIO(img_data))
104
+ return img, "โœ… Image generated successfully using nano-banana!"
105
+ except:
106
+ pass
107
+
108
+ try:
109
+ # Method 2: Using url() method and downloading
110
+ if hasattr(output, 'url'):
111
+ output_url = output.url()
112
+ response = requests.get(output_url, timeout=30)
113
+ if response.status_code == 200:
114
+ img = Image.open(BytesIO(response.content))
115
+ return img, "โœ… Image generated successfully using nano-banana!"
116
+ except:
117
+ pass
118
 
119
+ # Method 3: If output is a URL string or list
120
+ output_url = None
121
+ if isinstance(output, str):
 
122
  output_url = output
123
  elif isinstance(output, list) and len(output) > 0:
124
  output_url = output[0]
 
 
 
 
 
 
 
 
125
 
126
+ if output_url:
127
+ response = requests.get(output_url, timeout=30)
 
 
 
 
 
 
 
 
 
128
  if response.status_code == 200:
129
  img = Image.open(BytesIO(response.content))
130
+ return img, "โœ… Image generated successfully using nano-banana!"
 
131
 
132
+ return None, f"โŒ Could not process output. Output type: {type(output)}"
133
 
134
+ except replicate.exceptions.ReplicateError as e:
 
 
135
  error_msg = str(e)
136
+ if "502" in error_msg:
137
+ return None, "โŒ Server error (502). The model might be unavailable. Please try again later."
138
+ elif "404" in error_msg:
139
+ return None, "โŒ Model 'google/nano-banana' not found. Please verify the model exists."
140
+ elif "401" in error_msg or "403" in error_msg:
141
+ return None, "โŒ Authentication error. Please check your REPLICATE_API_TOKEN."
142
+ elif "402" in error_msg:
143
+ return None, "โŒ Payment required. Please check your Replicate billing status."
144
  else:
145
+ return None, f"โŒ Replicate Error: {error_msg}"
146
+ except Exception as e:
147
+ return None, f"โŒ Error: {str(e)}"
148
 
149
  # Create Gradio interface with gradient theme
150
  css = """
 
193
  <div class="header-text">๐ŸŽจ AI Image Style Transfer Studio</div>
194
  <div class="description-text">
195
  Upload 1-2 images and describe how you want them styled.
196
+ The AI will create a beautiful transformation using nano-banana model!
197
  </div>
198
  """)
199
 
 
230
  #### ๐Ÿ’ก Tips:
231
  - Upload high-quality images for best results
232
  - Be specific in your style description
233
+ - Model: google/nano-banana
234
  """)
235
 
236
  with gr.Column(scale=1):
 
252
  with gr.Row():
253
  gr.Examples(
254
  examples=[
255
+ ["Make the sheets in the style of the logo. Make the scene natural.", None, None],
256
  ["Transform into watercolor painting style", None, None],
257
  ["Make it look like a vintage photograph", None, None],
258
  ["Apply cyberpunk neon style", None, None],
 
259
  ],
260
  inputs=[prompt, image1, image2],
261
  label="Example Prompts"
 
276
 
277
  1. **Set Environment Variable:**
278
  ```bash
279
+ export REPLICATE_API_TOKEN="r8_your_token_here"
280
  ```
281
  Get your token from: https://replicate.com/account/api-tokens
282
 
 
285
  pip install gradio replicate pillow requests
286
  ```
287
 
288
+ 3. **Model Information:**
289
+ - Model: `google/nano-banana`
290
+ - Input format:
291
+ - `prompt`: Text description
292
+ - `image_input`: List of image URLs
293
+ - Output: Generated/styled image
294
 
295
+ 4. **Important Notes:**
296
+ - Images must be hosted with public URLs
297
+ - Currently using Imgur for free image hosting
298
+ - If model returns 502 error, it may be temporarily unavailable
 
 
299
 
300
  ### ๐Ÿ”’ Security:
301
  - API keys are managed through environment variables
302
  - Never commit API keys to version control
 
303
  """)
304
 
305
  # Launch the app