Hello people. I’m trying to use the image variations API but I don’t know how the image should be. Currently I have a base64 string as image and it’s not working and giving me the error 415 “Unsupported Media Type”.
I triple checked that the image is square, PNG and less than 4MB.
I tried by making first a RGB image and sending those bytes but it gave me the error 500. I did that by replacing the payload to { image : image} in the code below.
Hopefully somebody has an idea.
import os
import json
import boto3
import urllib.request
import urllib.parse
from PIL import Image
import base64
import io
def base64_to_rgb_image(base64_string):
# Decode the base64 string
image_data = base64.b64decode(base64_string)
# Create a BytesIO object to work with PIL
image_buffer = io.BytesIO(image_data)
# Open the image using PIL
image = Image.open(image_buffer)
# Convert the image to RGB mode
image = image.convert("RGB")
return image
def lambda_handler(event, context):
api_key = os.environ['YOUR_API_KEY']
try:
# Parse the incoming HTTP request
request_body = json.loads(event["body"])
image_base64 = request_body["image"]
print(f"Got image ")
# Convert base64 images to RGB mode
print("Will covert to RGB...")
image = base64_to_rgb_image(image_base64)
print("Coverted to RGB...")
# Create a request payload for OpenAI's image editing API
payload = {
"image": image_base64,
}
# Encode the payload as JSON
payload_data = json.dumps(payload).encode('utf-8')
# Create a request object with the appropriate headers
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
}
request = urllib.request.Request(
url="https://api.openai.com/v1/images/variations",
data=payload_data,
headers=headers,
method="POST"
)
print("Making request to OpenAI...")
# Make the POST request using urllib and handle exceptions
try:
with urllib.request.urlopen(request) as response:
response_data = response.read()
response_code = response.getcode()
parsed_response = json.loads(response_data)
print(f"Received response: {parsed_response}")
except Exception as request_error:
print(f"Error making the request: {str(request_error)}")
raise request_error
if response_code == 200:
result = json.loads(response_data.decode('utf-8'))
# Extract the generated image URL from the result
generated_image_url = result.get("url", "")
return {
"statusCode": 200,
"body": json.dumps({"generated_image_url": generated_image_url}),
}
else:
return {
"statusCode": response_code,
"body": response_data.decode('utf-8'),
}
except Exception as e:
return {
"statusCode": 500,
"body": str(e),
}
Given the documentation you provided, it seems you’re trying to use OpenAI’s Python client to interact with the Image Variations API. You seem to have used urllib to make a POST request manually in your original code. However, if you decide to use OpenAI’s Python client, it should simplify the process.
Let’s create a more concise version using the OpenAI Python client:
import os
import openai
from PIL import Image
import base64
import io
def base64_to_rgb_image(base64_string):
# Decode the base64 string
image_data = base64.b64decode(base64_string)
# Create a BytesIO object to work with PIL
image_buffer = io.BytesIO(image_data)
# Open the image using PIL
image = Image.open(image_buffer)
# Convert the image to RGB mode
image = image.convert("RGB")
return image
def create_image_variation(image_base64):
# Convert the base64 string to an RGB image
image = base64_to_rgb_image(image_base64)
# Save the image to a temporary file
image.save('temp_image.png', 'PNG')
# Set the API key
openai.api_key = os.getenv("YOUR_API_KEY")
# Use the OpenAI Python client to create image variations
response = openai.Image.create_variation(
image=open("temp_image.png", "rb"),
n=2, # number of images to generate
size="1024x1024" # size of the generated images
)
# Optional: Remove the temporary file
os.remove('temp_image.png')
return response.data # This will be a list of image objects with URLs
def lambda_handler(event, context):
try:
request_body = json.loads(event["body"])
image_base64 = request_body["image"]
generated_images = create_image_variation(image_base64)
return {
"statusCode": 200,
"body": json.dumps({"generated_images": generated_images}),
}
except Exception as e:
return {
"statusCode": 500,
"body": str(e),
}
This code does the following:
It decodes the base64 image string you provide into an RGB image using the base64_to_rgb_image function.
It saves this RGB image to a temporary file named temp_image.png.
Using the OpenAI Python client, it then sends this image file to OpenAI’s Image Variations API to generate variations of the image.
It finally returns the generated image URLs as a response.
Note: Make sure to install the required libraries (openai and PIL) in your lambda environment.
No problem. You could also peek at the OpenAI library code to see how they’re doing it then just replicate in your function. Good luck. Let us know how it goes.
Now it’s working perfectly. The code had a couple of issues, but here it is corrected.
import os
import openai
from PIL import Image
import base64
import io
import json
def base64_to_rgb_image(base64_string):
# Decode the base64 string
image_data = base64.b64decode(base64_string)
# Create a BytesIO object to work with PIL
image_buffer = io.BytesIO(image_data)
# Open the image using PIL
image = Image.open(image_buffer)
# Convert the image to RGB mode
image = image.convert("RGB")
return image
def create_image_variation(image_base64):
# Convert the base64 string to an RGB image
image = base64_to_rgb_image(image_base64)
# Save the image to a temporary file in the /tmp directory
temp_file_path = '/tmp/temp_image.png'
image.save(temp_file_path, 'PNG')
# Set the API key
openai.api_key = os.getenv("YOUR_API_KEY")
# Use the OpenAI Python client to create image variations
try:
with open(temp_file_path, "rb") as image_file:
response = openai.Image.create_variation(
image=image_file,
n=1, # number of images to generate
size="1024x1024" # size of the generated images
)
finally:
# Optional: Remove the temporary file
os.remove(temp_file_path)
return response.data # This will be a list of image objects with URLs
def lambda_handler(event, context):
try:
request_body = json.loads(event["body"])
image_base64 = request_body["image"]
generated_images = create_image_variation(image_base64)
return {
"statusCode": 200,
"body": json.dumps({"generated_images": generated_images}),
}
except Exception as e:
return {
"statusCode": 500,
"body": str(e),
}