Created
July 29, 2025 06:08
-
-
Save owainlewis/e9567df0588164f76f53f37d12ef1de2 to your computer and use it in GitHub Desktop.
Parallel Image Requests (Python, OpenAI)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import aiohttp | |
import asyncio | |
import os | |
import time | |
import base64 | |
import aiofiles | |
from pathlib import Path | |
class SimpleImageGenerator: | |
def __init__(self, output_dir="output/images"): | |
self.api_key = os.getenv("OPENAI_API_KEY") | |
self.output_dir = Path(output_dir) | |
self.output_dir.mkdir(parents=True, exist_ok=True) | |
if not self.api_key: | |
raise ValueError("OPENAI_API_KEY environment variable required") | |
async def generate_single_image(self, session, prompt): | |
"""Make a single API call to generate an image""" | |
payload = { | |
"model": "gpt-image-1", | |
"prompt": prompt, | |
"size": "1024x1536", | |
"quality": "high", | |
} | |
headers = { | |
"Authorization": f"Bearer {self.api_key}", | |
"Content-Type": "application/json", | |
} | |
try: | |
async with session.post( | |
"https://api.openai.com/v1/images/generations", | |
json=payload, | |
headers=headers, | |
) as response: | |
if response.status == 200: | |
base64_data = (await response.json())["data"][0]["b64_json"] | |
return await self._save_base64_image(base64_data) | |
print(f"API error {response.status}") | |
return None | |
except Exception as e: | |
print(f"Failed to generate image: {e}") | |
return None | |
async def _save_base64_image(self, base64_data): | |
"""Save base64 image data to output directory""" | |
timestamp = str(time.time_ns()) | |
filepath = self.output_dir / f"{timestamp}.png" | |
try: | |
image_bytes = base64.b64decode(base64_data) | |
async with aiofiles.open(filepath, "wb") as f: | |
await f.write(image_bytes) | |
return str(filepath) | |
except Exception as e: | |
print(f"Failed to save image: {e}") | |
return None | |
async def generate_images_parallel(self, prompts): | |
"""Generate multiple images in parallel using asyncio.gather()""" | |
async with aiohttp.ClientSession() as session: | |
# Create tasks for all prompts - this is the key parallel part! | |
tasks = [self.generate_single_image(session, prompt) for prompt in prompts] | |
# Execute all tasks concurrently | |
results = await asyncio.gather(*tasks, return_exceptions=True) | |
# Filter out failed requests | |
successful_files = [ | |
filepath | |
for filepath in results | |
if filepath and isinstance(filepath, str) | |
] | |
print(f"Generated {len(successful_files)}/{len(prompts)} images") | |
return successful_files | |
# Usage example | |
async def main(): | |
generator = SimpleImageGenerator() | |
prompts = [ | |
"A red cat sitting on a blue chair", | |
"A sunset over mountains", | |
"A robot reading a book", | |
] | |
# This will make all 3 API calls simultaneously! | |
saved_files = await generator.generate_images_parallel(prompts) | |
for i, filepath in enumerate(saved_files): | |
print(f"Image {i + 1} saved to: {filepath}") | |
# Run the example | |
if __name__ == "__main__": | |
asyncio.run(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment