I finally have it working !!!
This MODEL works for me out of the box.
I added a very simple GUI to the python script, which also lets you save and load your inputs, just to make it a bit more user friendly and ofc I am sharing it with you:
import requests
import json
import base64
from google.auth import default
from google.auth.transport.requests import Request
from PIL import Image
from io import BytesIO
import tkinter as tk
from tkinter import ttk, scrolledtext, Scale, HORIZONTAL, messagebox
import configparser
import os
import datetime
# --- Configuration File ---
CONFIG_FILE = "config.ini"
config = configparser.ConfigParser()
# --- Image Output Directory ---
IMG_DIR = "img"
os.makedirs(IMG_DIR, exist_ok=True)
class InferenceOutputError(Exception):
def __init__(self, message):
self.message = message
def text_to_image(api_url: str, access_token: str, inputs: str, parameters: dict = None, options: dict = None) -> bytes:
"""
Generates an image from text using a Vertex AI endpoint.
"""
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
payload = {
"instances": [inputs],
"parameters": parameters or {}
}
response = requests.post(api_url, headers=headers, data=json.dumps(payload))
print("Status Code:", response.status_code)
if response.status_code == 200:
result = response.json()
print("Result:", result)
image_data_base64 = result['predictions'][0]
image_data = base64.b64decode(image_data_base64)
if isinstance(image_data, bytes) and len(image_data) > 0:
return image_data
else:
raise InferenceOutputError("Expected bytes (image data)")
else:
print("Error:", response.status_code, response.text)
raise InferenceOutputError(f"HTTP Error: {response.status_code}")
def load_config():
"""Loads configuration from the config file."""
config.read(CONFIG_FILE)
if "settings" in config:
prompt_text.insert(tk.END, config.get("settings", "prompt", fallback=""))
negative_prompt_text.insert(tk.END, config.get("settings", "negative_prompt", fallback=""))
inference_steps_slider.set(config.getint("settings", "inference_steps", fallback=30))
guidance_scale_slider.set(config.getint("settings", "guidance_scale", fallback=8))
resolution_var.set(config.get("settings", "resolution", fallback="512x512"))
else:
# Set default values if the config file does not have settings
inference_steps_slider.set(30)
guidance_scale_slider.set(5)
resolution_var.set("512x512")
def save_config():
"""Saves the current input values to the config file."""
config["settings"] = {
"prompt": prompt_text.get("1.0", tk.END).strip(),
"negative_prompt": negative_prompt_text.get("1.0", tk.END).strip(),
"inference_steps": inference_steps_slider.get(),
"guidance_scale": guidance_scale_slider.get(),
"resolution": resolution_var.get(),
}
with open(CONFIG_FILE, "w") as configfile:
config.write(configfile)
messagebox.showinfo("Info", "Configuration saved!")
def generate_image():
global access_token
inputs = prompt_text.get("1.0", tk.END).strip()
negative_prompt = negative_prompt_text.get("1.0", tk.END).strip()
try:
num_inference_steps = int(inference_steps_slider.get())
guidance_scale = int(guidance_scale_slider.get())
except ValueError:
messagebox.showerror("Error", "Inference steps and guidance scale must be integers.")
return
resolution = resolution_var.get()
width, height = map(int, resolution.split("x"))
parameters = {
"negative_prompt": negative_prompt,
"num_inference_steps": num_inference_steps,
"guidance_scale": guidance_scale,
"width": width,
"height": height,
"seed": 12345
}
try:
image_bytes = text_to_image(api_url, access_token, inputs, parameters)
# --- Save Image ---
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
image_filename = f"image_{timestamp}.png"
image_path = os.path.join(IMG_DIR, image_filename)
image = Image.open(BytesIO(image_bytes))
image.save(image_path)
print(f"Image saved to: {image_path}")
# --- Display Image ---
image.show()
except InferenceOutputError as e:
messagebox.showerror("Error", f"Inference Error: {e.message}")
except Exception as e:
messagebox.showerror("Error", f"An unexpected error occurred: {e}")
# --- GUI Setup ---
window = tk.Tk()
window.title("Stable Diffusion Image Generator")
# --- Credentials ---
# Use Application Default Credentials (ADC)
credentials, project = default()
credentials.refresh(Request())
access_token = credentials.token
# --- API URL ---
# Replace with your endpoint URL
api_url = "REPLACE_WITH_YOUR_ENDPOINT_URL"
# --- Prompt ---
prompt_label = ttk.Label(window, text="Prompt:")
prompt_label.grid(column=0, row=0, sticky=tk.W, padx=5, pady=5)
prompt_text = scrolledtext.ScrolledText(window, wrap=tk.WORD, height=5)
prompt_text.grid(column=0, row=1, padx=5, pady=5, columnspan=2, sticky="nsew")
# --- Negative Prompt ---
negative_prompt_label = ttk.Label(window, text="Negative Prompt:")
negative_prompt_label.grid(column=0, row=2, sticky=tk.W, padx=5, pady=5)
negative_prompt_text = scrolledtext.ScrolledText(window, wrap=tk.WORD, height=5)
negative_prompt_text.grid(column=0, row=3, padx=5, pady=5, columnspan=2, sticky="nsew")
# --- Inference Steps ---
inference_steps_label = ttk.Label(window, text="Inference Steps (0-200):")
inference_steps_label.grid(column=0, row=4, sticky=tk.W, padx=5, pady=5)
inference_steps_slider = Scale(window, from_=0, to=200, orient=HORIZONTAL)
inference_steps_slider.set(30) # Default value
inference_steps_slider.grid(column=1, row=4, padx=5, pady=5, sticky="ew")
# --- Resolution ---
resolution_label = ttk.Label(window, text="Resolution:")
resolution_label.grid(column=0, row=5, sticky=tk.W, padx=5, pady=5)
resolution_var = tk.StringVar(window)
resolutions = ["512x512", "768x512", "512x768", "1024x768", "768x1024", "1216x832", "832x1216", "1024x1024"]
resolution_var.set(resolutions[0]) # Default value
resolution_dropdown = ttk.Combobox(window, textvariable=resolution_var, values=resolutions)
resolution_dropdown.grid(column=1, row=5, padx=5, pady=5, sticky="ew")
# --- Guidance Scale ---
guidance_scale_label = ttk.Label(window, text="Guidance Scale (0-20):")
guidance_scale_label.grid(column=0, row=6, sticky=tk.W, padx=5, pady=5)
guidance_scale_slider = Scale(window, from_=0, to=20, orient=HORIZONTAL)
guidance_scale_slider.set(5) # Default value
guidance_scale_slider.grid(column=1, row=6, padx=5, pady=5, sticky="ew")
# --- Load Configuration ---
load_button = ttk.Button(window, text="Load Configuration", command=load_config)
load_button.grid(column=0, row=8, padx=5, pady=10)
# --- Save Configuration ---
save_button = ttk.Button(window, text="Save Configuration", command=save_config)
save_button.grid(column=1, row=8, padx=5, pady=10)
# --- Generate Button ---
generate_button = ttk.Button(window, text="Generate Image", command=generate_image)
generate_button.grid(column=0, row=7, padx=5, pady=10, columnspan=2)
# --- Configure grid weights ---
window.columnconfigure(0, weight=1)
window.columnconfigure(1, weight=1)
for i in range(9):
window.rowconfigure(i, weight=1)
# --- Load initial configuration ---
load_config()
# --- Run the GUI ---
window.mainloop()
@John6666 please know that I am deeply grateful for your help getting this to run!!
Since I was not able to find any resources on this secific set of issues I hope it is okay to do some search engine optimization:
Vertex AI Stable Diffusion XL inference error, Python Vertex AI endpoint huggingface issues, SDXL Vertex AI deployment troubleshooting, Stable Diffusion XL prompt formatting Vertex AI, Vertex AI image generation errors, Python requests to Vertex AI endpoint, Base64 decoding error Vertex AI, Vertex AI prediction response format, Stable Diffusion XL custom container handling, Authentication error Vertex AI, HTTP 400 error Vertex AI, TypeError: string indices must be integers Vertex AI, ācan only concatenate tuple (not ādictā) to tupleā Vertex AI error, Vertex AI prediction timeout, Vertex AI SDK Stable Diffusion XL example, google-cloud-aiplatform Stable Diffusion, diffusers on Vertex AI, Stable Diffusion XL inference request Python, Vertex AI endpoint input format, Vertex AI endpoint output format, Troubleshooting Vertex AI online prediction, Vertex AI custom model input validation, Vertex AI pre-built container Stable Diffusion, Vertex AI prediction request payload, Vertex AI Python client library, GUI for stable diffusion model Vertex AI, Vertex AI Stable Diffusion XL tutorial, Vertex AI Stable Diffusion XL guide, Configuring Vertex AI endpoint for Stable Diffusion XL, Vertex AI model expects string or list, Vertex AI model expects dictionary, InferenceOutputError Vertex AI, TypeError Vertex AI, HTTP Error Vertex AI, image generation from Vertex AI returning static