Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -30,28 +30,30 @@ def call_openai_image_api(prompt: str, api_key: str, input_image: Image.Image |
|
|
| 30 |
|
| 31 |
headers = {"Authorization": f"Bearer {api_key}"}
|
| 32 |
# Hypothetical model name from the original code. Replace with "dall-e-2" or "dall-e-3" if needed.
|
| 33 |
-
model = "gpt-image-1"
|
| 34 |
size = "1024x1024"
|
|
|
|
| 35 |
|
| 36 |
-
|
| 37 |
if input_image:
|
| 38 |
# --- Image Editing ---
|
| 39 |
if not isinstance(input_image, Image.Image):
|
| 40 |
-
|
| 41 |
|
| 42 |
-
# CORRECTED INDENTATION for this block:
|
| 43 |
# Convert PIL Image to bytes for the API request
|
| 44 |
byte_stream = io.BytesIO()
|
| 45 |
-
input_image.save(byte_stream, format="PNG") # Save PIL image to bytes buffer
|
| 46 |
byte_stream.seek(0) # Rewind buffer to the beginning
|
| 47 |
|
| 48 |
files = {
|
| 49 |
"image": ("input_image.png", byte_stream, "image/png"),
|
| 50 |
}
|
|
|
|
| 51 |
data = {
|
| 52 |
"prompt": prompt,
|
| 53 |
"model": model,
|
| 54 |
"size": size,
|
|
|
|
| 55 |
}
|
| 56 |
api_url = "https://api.openai.com/v1/images/edits"
|
| 57 |
print("Calling OpenAI Image Edit API...") # Debug print
|
|
@@ -59,14 +61,14 @@ def call_openai_image_api(prompt: str, api_key: str, input_image: Image.Image |
|
|
| 59 |
|
| 60 |
else:
|
| 61 |
# --- Image Generation ---
|
| 62 |
-
# (This part remains the same)
|
| 63 |
headers["Content-Type"] = "application/json"
|
| 64 |
payload = {
|
| 65 |
"prompt": prompt,
|
| 66 |
"model": model,
|
| 67 |
"response_format": "b64_json", # Keep this for generation
|
| 68 |
"size": size,
|
| 69 |
-
"n": 1,
|
| 70 |
}
|
| 71 |
api_url = "https://api.openai.com/v1/images/generations"
|
| 72 |
print("Calling OpenAI Image Generation API...") # Debug print
|
|
@@ -77,25 +79,31 @@ def call_openai_image_api(prompt: str, api_key: str, input_image: Image.Image |
|
|
| 77 |
|
| 78 |
# Process successful response
|
| 79 |
response_data = response.json()
|
| 80 |
-
|
| 81 |
-
|
|
|
|
|
|
|
|
|
|
| 82 |
|
| 83 |
img_b64 = response_data["data"][0]["b64_json"]
|
| 84 |
-
img_bytes = base64.b64decode(img_b64)
|
| 85 |
-
result_image = Image.open(io.BytesIO(img_bytes))
|
| 86 |
print("Image processed successfully.") # Debug print
|
| 87 |
return input_image, result_image, "Success!"
|
| 88 |
|
| 89 |
except requests.exceptions.RequestException as e:
|
| 90 |
error_message = f"API Request Error: {e}"
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
|
|
|
|
|
|
|
|
|
| 99 |
print(error_message) # Debug print
|
| 100 |
return input_image, None, error_message
|
| 101 |
except Exception as e:
|
|
@@ -106,7 +114,7 @@ def call_openai_image_api(prompt: str, api_key: str, input_image: Image.Image |
|
|
| 106 |
|
| 107 |
# --- Gradio Interface Setup ---
|
| 108 |
|
| 109 |
-
# Check for API key in environment variables
|
| 110 |
api_key_env = os.environ.get("OPENAI_API_KEY")
|
| 111 |
api_key_present_info = "OpenAI API Key found in environment variables." if api_key_env else "OpenAI API Key not found in environment variables. Please enter it below."
|
| 112 |
|
|
@@ -128,23 +136,23 @@ def process_image_request(prompt_input, api_key_input, uploaded_image):
|
|
| 128 |
return original_img, result_img, status
|
| 129 |
|
| 130 |
|
| 131 |
-
# Build the Gradio interface using Blocks for more layout control
|
| 132 |
with gr.Blocks() as demo:
|
| 133 |
-
gr.Markdown("# OpenAI GPT-Image-1 Text-to-Image Demo") # App title
|
| 134 |
gr.Markdown("Enter a prompt to generate an image, or upload an image and enter a prompt to edit it.")
|
| 135 |
|
| 136 |
with gr.Row():
|
| 137 |
with gr.Column(scale=1):
|
| 138 |
-
prompt_input = gr.Textbox(label="Image Description (Prompt)", lines=3, placeholder="e.g., A futuristic cityscape at sunset") # Text input for prompt
|
| 139 |
gr.Markdown(f"*{api_key_present_info}*")
|
| 140 |
-
api_key_input = gr.Textbox(label="OpenAI API Key", type="password", placeholder="Enter your key if not set in environment") # Password input for API key
|
| 141 |
-
uploaded_image_input = gr.Image(type="pil", label="Upload Image to Edit (Optional)") # Image upload [[
|
| 142 |
submit_button = gr.Button("Generate / Edit Image")
|
| 143 |
with gr.Column(scale=2):
|
| 144 |
status_output = gr.Textbox(label="Status", interactive=False)
|
| 145 |
with gr.Row():
|
| 146 |
original_image_output = gr.Image(label="Original Image", interactive=False)
|
| 147 |
-
result_image_output = gr.Image(label="Generated / Edited Image", interactive=False) # Display output image
|
| 148 |
|
| 149 |
# Connect the button click event to the processing function
|
| 150 |
submit_button.click(
|
|
@@ -153,6 +161,6 @@ with gr.Blocks() as demo:
|
|
| 153 |
outputs=[original_image_output, result_image_output, status_output]
|
| 154 |
)
|
| 155 |
|
| 156 |
-
# Launch the Gradio app
|
| 157 |
if __name__ == "__main__":
|
| 158 |
demo.launch()
|
|
|
|
| 30 |
|
| 31 |
headers = {"Authorization": f"Bearer {api_key}"}
|
| 32 |
# Hypothetical model name from the original code. Replace with "dall-e-2" or "dall-e-3" if needed.
|
| 33 |
+
model = "gpt-image-1" # Using the model specified in the original code
|
| 34 |
size = "1024x1024"
|
| 35 |
+
response = None # Initialize response variable
|
| 36 |
|
| 37 |
+
try:
|
| 38 |
if input_image:
|
| 39 |
# --- Image Editing ---
|
| 40 |
if not isinstance(input_image, Image.Image):
|
| 41 |
+
return None, None, "Error: Invalid image provided for editing."
|
| 42 |
|
|
|
|
| 43 |
# Convert PIL Image to bytes for the API request
|
| 44 |
byte_stream = io.BytesIO()
|
| 45 |
+
input_image.save(byte_stream, format="PNG") # Save PIL image to bytes buffer [[1]]
|
| 46 |
byte_stream.seek(0) # Rewind buffer to the beginning
|
| 47 |
|
| 48 |
files = {
|
| 49 |
"image": ("input_image.png", byte_stream, "image/png"),
|
| 50 |
}
|
| 51 |
+
# CORRECTED data dictionary: removed 'response_format'
|
| 52 |
data = {
|
| 53 |
"prompt": prompt,
|
| 54 |
"model": model,
|
| 55 |
"size": size,
|
| 56 |
+
# "response_format": "b64_json", # <-- THIS LINE IS REMOVED
|
| 57 |
}
|
| 58 |
api_url = "https://api.openai.com/v1/images/edits"
|
| 59 |
print("Calling OpenAI Image Edit API...") # Debug print
|
|
|
|
| 61 |
|
| 62 |
else:
|
| 63 |
# --- Image Generation ---
|
| 64 |
+
# (This part remains the same as it uses response_format correctly via json payload)
|
| 65 |
headers["Content-Type"] = "application/json"
|
| 66 |
payload = {
|
| 67 |
"prompt": prompt,
|
| 68 |
"model": model,
|
| 69 |
"response_format": "b64_json", # Keep this for generation
|
| 70 |
"size": size,
|
| 71 |
+
"n": 1, # Generate one image
|
| 72 |
}
|
| 73 |
api_url = "https://api.openai.com/v1/images/generations"
|
| 74 |
print("Calling OpenAI Image Generation API...") # Debug print
|
|
|
|
| 79 |
|
| 80 |
# Process successful response
|
| 81 |
response_data = response.json()
|
| 82 |
+
# Ensure the expected data structure is present
|
| 83 |
+
if not response_data.get("data") or not isinstance(response_data["data"], list) or len(response_data["data"]) == 0:
|
| 84 |
+
return input_image, None, f"Error: Unexpected API response format - 'data' array missing or empty: {response_data}"
|
| 85 |
+
if not response_data["data"][0].get("b64_json"):
|
| 86 |
+
return input_image, None, f"Error: Unexpected API response format - 'b64_json' key missing: {response_data}"
|
| 87 |
|
| 88 |
img_b64 = response_data["data"][0]["b64_json"]
|
| 89 |
+
img_bytes = base64.b64decode(img_b64) # Decode base64 string [[1]]
|
| 90 |
+
result_image = Image.open(io.BytesIO(img_bytes)) # Convert bytes to PIL Image [[1]]
|
| 91 |
print("Image processed successfully.") # Debug print
|
| 92 |
return input_image, result_image, "Success!"
|
| 93 |
|
| 94 |
except requests.exceptions.RequestException as e:
|
| 95 |
error_message = f"API Request Error: {e}"
|
| 96 |
+
# Check if response exists before trying to access its attributes/methods
|
| 97 |
+
if response is not None:
|
| 98 |
+
try:
|
| 99 |
+
# Attempt to get more specific error from OpenAI response
|
| 100 |
+
error_detail = response.json()
|
| 101 |
+
error_message += f"\nAPI Error Details: {error_detail}"
|
| 102 |
+
except requests.exceptions.JSONDecodeError:
|
| 103 |
+
# Fallback if response is not JSON
|
| 104 |
+
error_message += f"\nRaw Response Text: {response.text}"
|
| 105 |
+
except Exception as json_e:
|
| 106 |
+
error_message += f"\nError parsing JSON response: {json_e}\nRaw Response Text: {response.text}"
|
| 107 |
print(error_message) # Debug print
|
| 108 |
return input_image, None, error_message
|
| 109 |
except Exception as e:
|
|
|
|
| 114 |
|
| 115 |
# --- Gradio Interface Setup ---
|
| 116 |
|
| 117 |
+
# Check for API key in environment variables
|
| 118 |
api_key_env = os.environ.get("OPENAI_API_KEY")
|
| 119 |
api_key_present_info = "OpenAI API Key found in environment variables." if api_key_env else "OpenAI API Key not found in environment variables. Please enter it below."
|
| 120 |
|
|
|
|
| 136 |
return original_img, result_img, status
|
| 137 |
|
| 138 |
|
| 139 |
+
# Build the Gradio interface using Blocks for more layout control [[7]]
|
| 140 |
with gr.Blocks() as demo:
|
| 141 |
+
gr.Markdown("# OpenAI GPT-Image-1 Text-to-Image Demo") # App title
|
| 142 |
gr.Markdown("Enter a prompt to generate an image, or upload an image and enter a prompt to edit it.")
|
| 143 |
|
| 144 |
with gr.Row():
|
| 145 |
with gr.Column(scale=1):
|
| 146 |
+
prompt_input = gr.Textbox(label="Image Description (Prompt)", lines=3, placeholder="e.g., A futuristic cityscape at sunset") # Text input for prompt
|
| 147 |
gr.Markdown(f"*{api_key_present_info}*")
|
| 148 |
+
api_key_input = gr.Textbox(label="OpenAI API Key", type="password", placeholder="Enter your key if not set in environment") # Password input for API key
|
| 149 |
+
uploaded_image_input = gr.Image(type="pil", label="Upload Image to Edit (Optional)") # Image upload [[4]]
|
| 150 |
submit_button = gr.Button("Generate / Edit Image")
|
| 151 |
with gr.Column(scale=2):
|
| 152 |
status_output = gr.Textbox(label="Status", interactive=False)
|
| 153 |
with gr.Row():
|
| 154 |
original_image_output = gr.Image(label="Original Image", interactive=False)
|
| 155 |
+
result_image_output = gr.Image(label="Generated / Edited Image", interactive=False) # Display output image
|
| 156 |
|
| 157 |
# Connect the button click event to the processing function
|
| 158 |
submit_button.click(
|
|
|
|
| 161 |
outputs=[original_image_output, result_image_output, status_output]
|
| 162 |
)
|
| 163 |
|
| 164 |
+
# Launch the Gradio app [[2]]
|
| 165 |
if __name__ == "__main__":
|
| 166 |
demo.launch()
|