1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
| import random import urllib.request import urllib.error import json import os import ssl import base64 import argparse import sys from datetime import datetime
def save_image(image_entry, output_filename): """ Parses various image structures (OpenRouter image_url or OpenAI URL/B64). """ try: if isinstance(image_entry, dict): if "image_url" in image_entry: image_data = image_entry["image_url"]["url"] else: image_data = image_entry.get("url") or image_entry.get("b64_json") else: image_data = image_entry
if not image_data: print( "Error: Could not find image URL or Base64 data in the response entry." ) return False
if image_data.startswith("http"): print("Downloading image...") ctx = ssl._create_unverified_context() with urllib.request.urlopen( image_data, context=ctx, timeout=30 ) as response: with open(output_filename, "wb") as f: f.write(response.read()) else: print("Decoding Base64 data...") if "," in image_data: image_data = image_data.split(",")[1] binary_data = base64.b64decode(image_data) with open(output_filename, "wb") as f: f.write(binary_data)
print(f"Successfully saved to: {output_filename}") return True
except Exception as e: print(f"File saving failed: {e}") return False
def call_drawing_api(prompt, model, base_url, extra_params=None): """ Universal caller that adapts payload based on the endpoint path. """ api_key = os.getenv("API_KEY") if not api_key: print("Error: API_KEY environment variable is not set.") sys.exit(1)
payload = { "model": model, "messages": [{"role": "user", "content": prompt}], "modalities": ["image"], }
if extra_params: payload.update(extra_params)
headers = { "Content-Type": "application/json", "Authorization": f"Bearer {api_key}", }
req = urllib.request.Request( base_url, data=json.dumps(payload).encode("utf-8"), headers=headers )
ctx = ssl._create_unverified_context()
try: print(f"Sending request to: {base_url}") with urllib.request.urlopen(req, context=ctx, timeout=120) as response: res_json = json.loads(response.read().decode("utf-8"))
message = res_json["choices"][0]["message"] if "images" in message: return message["images"][0]
print("No image data found. Full response:") print(json.dumps(res_json, indent=2)) return None
except urllib.error.HTTPError as e: error_body = e.read().decode() print(f"HTTP Error {e.code}: {error_body}") except Exception as e: print(f"API Connection Error: {e}") return None
def get_valid_prompt(file_path): """ Handles prompt acquisition with a confirmation loop. """ prompt_content = ""
if file_path: try: with open(file_path, "r", encoding="utf-8") as f: prompt_content = f.read().strip()
if prompt_content: print(f"\n--- Read from file [{file_path}] ---") print(f"Content: {prompt_content}") print("-" * 30)
confirm = ( input("Use this prompt? (Y/n, or enter 'm' to input manually): ") .strip() .lower() ) if confirm in ["y", ""]: return prompt_content else: print(f"Warning: File [{file_path}] is empty.") except Exception as e: print(f"Error reading file: {e}")
while True: prompt_content = input("\nPlease enter your prompt manually: ").strip() if not prompt_content: print("Error: Prompt cannot be empty. Please try again.") continue
print(f"\nYour input: {prompt_content}") confirm = input("Confirm this prompt? (Y/n): ").strip().lower() if confirm in ["y", ""]: return prompt_content
def main(): parser = argparse.ArgumentParser( description="Professional Universal Image Gen Script" ) parser.add_argument("--model", required=True, help="Model") parser.add_argument( "--base-url", default="https://openrouter.ai/api/v1", help="Base API URL" ) parser.add_argument("--prompt", help="Path to prompt file") parser.add_argument("--output", help="Output filename") parser.add_argument("--seed", type=int, help="Seed for generation") parser.add_argument( "--extra", help='Extra params as JSON string (e.g. \'{"size":"1024x1024"}\')' )
args = parser.parse_args()
final_prompt = get_valid_prompt(args.prompt)
base_url = args.base_url.rstrip("/") if "chat/completions" not in base_url: base_url += "/chat/completions"
extra_dict = None if args.extra: try: extra_dict = json.loads(args.extra) except json.JSONDecodeError: print("Error: --extra must be a valid JSON string.") sys.exit(1)
if args.seed is not None: current_seed = args.seed else: current_seed = random.randint(0, 10**9) print(f"No seed provided. Generated random seed: {current_seed}")
extra_dict = json.loads(args.extra) if args.extra else {} extra_dict["seed"] = current_seed
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") out_file = args.output or f"IMG_{timestamp}_S{current_seed}.png"
result = call_drawing_api(final_prompt, args.model, base_url, extra_dict) if result: save_image(result, out_file)
if __name__ == "__main__": main()
|