Skip to content

Commit d7537b7

Browse files
authored
feat: Refactor GPT-Image client to support multiple models and enhance deployment tracking (#41)
1 parent 112e38d commit d7537b7

File tree

10 files changed

+314
-81
lines changed

10 files changed

+314
-81
lines changed

backend/core/__init__.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,17 @@
2525
logger.error(f"Failed to initialize Sora 2 client: {str(e)}")
2626
sora_client = None
2727

28-
# Initialize GPT-Image-1 client
28+
# Initialize GPT-Image client (using default model)
2929
try:
30-
# Using OpenAI API directly for GPT-Image-1
30+
# Using OpenAI API directly for GPT-Image
3131
dalle_client = GPTImageClient(
3232
api_key=settings.OPENAI_API_KEY,
33-
organization_id=settings.OPENAI_ORG_ID if settings.OPENAI_ORG_ID else None
33+
organization_id=settings.OPENAI_ORG_ID if settings.OPENAI_ORG_ID else None,
34+
model=settings.DEFAULT_IMAGE_MODEL
3435
)
35-
logger.info("Initialized GPT-Image-1 client using OpenAI API.")
36+
logger.info(f"Initialized GPT-Image client using OpenAI API with default model: {settings.DEFAULT_IMAGE_MODEL}")
3637
except Exception as e:
37-
logger.error(f"Failed to initialize GPT-Image-1 client: {str(e)}")
38+
logger.error(f"Failed to initialize GPT-Image client: {str(e)}")
3839
dalle_client = None
3940

4041
# Initialize LLM client (sync)

backend/core/config.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,16 @@ class Settings(BaseSettings):
2525
# Azure OpenAI for Image Generation
2626
# The Azure OpenAI resource name for image generation
2727
IMAGEGEN_AOAI_RESOURCE: Optional[str] = None
28-
# The image generation deployment name
28+
# The image generation deployment name (gpt-image-1)
2929
IMAGEGEN_DEPLOYMENT: Optional[str] = None
30+
# The gpt-image-1.5 deployment name
31+
IMAGEGEN_15_DEPLOYMENT: Optional[str] = None
32+
# The gpt-image-1-mini deployment name
33+
IMAGEGEN_1_MINI_DEPLOYMENT: Optional[str] = None
3034
# The Azure OpenAI API key for image generation
3135
IMAGEGEN_AOAI_API_KEY: Optional[str] = None
36+
# Default image generation model
37+
DEFAULT_IMAGE_MODEL: str = "gpt-image-1"
3238

3339
# OpenAI API for Image Generation with GPT-Image-1
3440
OPENAI_API_KEY: Optional[str] = None

backend/core/gpt_image.py

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,19 @@ class GPTImageClient:
2323
Client for GPT-Image-1 generation and editing using the official OpenAI or Azure OpenAI Python client.
2424
"""
2525

26-
def __init__(self, api_key: Optional[str] = None, organization_id: Optional[str] = None, provider: Optional[str] = None):
26+
def __init__(self, api_key: Optional[str] = None, organization_id: Optional[str] = None, provider: Optional[str] = None, deployment_name: Optional[str] = None, model: Optional[str] = None):
2727
"""
2828
Initialize the GPT Image client with either OpenAI or Azure OpenAI client
2929
3030
Args:
3131
api_key: The API key to use (optional, will use from settings if not provided)
3232
organization_id: The organization ID for OpenAI (optional)
3333
provider: The provider to use ('openai' or 'azure', defaults to settings.MODEL_PROVIDER)
34+
deployment_name: Specific deployment name to use (for Azure, optional)
35+
model: Model name to use (gpt-image-1, gpt-image-1.5, gpt-image-1.5-mini)
3436
"""
3537
provider = provider or settings.MODEL_PROVIDER
38+
self.model = model or settings.DEFAULT_IMAGE_MODEL
3639

3740
if provider.lower() == "azure":
3841
# Use Azure OpenAI
@@ -46,11 +49,11 @@ def __init__(self, api_key: Optional[str] = None, organization_id: Optional[str]
4649
api_key=self.api_key,
4750
api_version=settings.AOAI_API_VERSION
4851
)
49-
# Set deployment name for later use
50-
self.deployment_name = settings.IMAGEGEN_DEPLOYMENT
52+
# Set deployment name: use provided or map from model
53+
self.deployment_name = deployment_name or self._get_deployment_for_model(self.model)
5154
self.provider = "azure"
5255
logger.info(
53-
"Initialized GPT-Image-1 client with Azure OpenAI Python SDK")
56+
f"Initialized GPT Image client with Azure OpenAI Python SDK (model: {self.model}, deployment: {self.deployment_name})")
5457
else:
5558
# Use direct OpenAI
5659
self.api_key = api_key or settings.OPENAI_API_KEY
@@ -62,8 +65,32 @@ def __init__(self, api_key: Optional[str] = None, organization_id: Optional[str]
6265
organization=organization_id or settings.OPENAI_ORG_ID
6366
)
6467
self.provider = "openai"
68+
self.deployment_name = None # Not used for OpenAI
6569
logger.info(
66-
"Initialized GPT-Image-1 client with OpenAI Python SDK")
70+
f"Initialized GPT Image client with OpenAI Python SDK (model: {self.model})")
71+
72+
def _get_deployment_for_model(self, model: str) -> str:
73+
"""
74+
Map model name to Azure deployment name
75+
76+
Args:
77+
model: Model identifier (gpt-image-1, gpt-image-1.5, gpt-image-1-mini)
78+
79+
Returns:
80+
Deployment name from settings
81+
"""
82+
mapping = {
83+
"gpt-image-1": settings.IMAGEGEN_DEPLOYMENT,
84+
"gpt-image-1.5": settings.IMAGEGEN_15_DEPLOYMENT,
85+
"gpt-image-1-mini": settings.IMAGEGEN_1_MINI_DEPLOYMENT,
86+
}
87+
deployment = mapping.get(model)
88+
89+
if not deployment:
90+
logger.warning(f"No deployment configured for model {model}, falling back to default")
91+
deployment = settings.IMAGEGEN_DEPLOYMENT
92+
93+
return deployment
6794

6895
def generate_image(self, prompt: str, model: str = None, n: int = 1,
6996
size: str = "auto", response_format: str = "b64_json",
@@ -168,6 +195,10 @@ def generate_image(self, prompt: str, model: str = None, n: int = 1,
168195

169196
formatted_response["data"].append(image_data)
170197

198+
# Add deployment metadata for tracking
199+
formatted_response["_deployment_name"] = self.deployment_name
200+
formatted_response["_model"] = self.model
201+
171202
return formatted_response
172203

173204
except Exception as e:
@@ -257,8 +288,11 @@ def edit_image(self, **kwargs):
257288
url, headers=headers, files=files, data=data)
258289
response.raise_for_status()
259290

260-
# Parse the response
261-
return response.json()
291+
# Parse the response and add deployment metadata
292+
result = response.json()
293+
result["_deployment_name"] = self.deployment_name
294+
result["_model"] = self.model
295+
return result
262296
else:
263297
# Handle model parameter for OpenAI provider
264298
if "model" not in kwargs:
@@ -277,7 +311,11 @@ def edit_image(self, **kwargs):
277311

278312
# Call the OpenAI API to edit the image
279313
response = self.client.images.edit(**kwargs)
280-
return response.model_dump()
314+
result = response.model_dump()
315+
# Add deployment metadata
316+
result["_deployment_name"] = self.deployment_name
317+
result["_model"] = self.model
318+
return result
281319

282320
except Exception as e:
283321
logger.error(f"Error editing image: {str(e)}")
@@ -455,7 +493,11 @@ async def process_edit_image_upload(self, prompt: str, model: str = None, n: int
455493
def _sync_post():
456494
resp = requests.post(url, headers=headers, files=files, data=data)
457495
resp.raise_for_status()
458-
return resp.json()
496+
result = resp.json()
497+
# Add deployment metadata
498+
result["_deployment_name"] = self.deployment_name
499+
result["_model"] = self.model
500+
return result
459501

460502
return await asyncio.to_thread(_sync_post)
461503
finally:

0 commit comments

Comments
 (0)