import os
from openai import OpenAI
from typing import Optional, Dict, Any
from PIL import Image
import requests
from io import BytesIO
from dotenv import load_dotenv
import base64
load_dotenv()
Interior design styles and their prompts
INTERIOR_STYLES = {
“modern”: {
“prompt”: “modern interior design, clean lines, minimalist, neutral colors, sleek furniture”,
“negative_prompt”: “cluttered, vintage, rustic, ornate decorations”
},
“scandinavian”: {
“prompt”: “scandinavian design, light woods, white walls, natural light, minimal decor”,
“negative_prompt”: “dark colors, heavy furniture, cluttered spaces”
},
“industrial”: {
“prompt”: “industrial style, exposed brick, metal fixtures, raw materials, open space”,
“negative_prompt”: “traditional furniture, floral patterns, pastel colors”
},
“traditional”: {
“prompt”: “traditional interior, classic furniture, warm colors, elegant details”,
“negative_prompt”: “ultra-modern, minimalist, industrial elements”
},
“bohemian”: {
“prompt”: “bohemian style, eclectic decor, rich patterns, plants, natural materials”,
“negative_prompt”: “minimal decoration, monochromatic, formal arrangement”
}
}
class StagingService:
def init(self):
self.client = OpenAI(api_key=os.getenv(‘OPENAI_API_KEY’))
async def detect_room_type(self, image_url: str) -> str:
"""
Detect the room type from the image using OpenAI's Vision API.
"""
try:
# Handle local file paths
if image_url.startswith('file://'):
image_path = image_url.replace('file://', '')
with open(image_path, 'rb') as image_file:
image_data = base64.b64encode(image_file.read()).decode('utf-8')
image_url = f"data:image/jpeg;base64,{image_data}"
response = self.client.chat.completions.create(
model="gpt-4-vision-preview",
messages=[
{
"role": "user",
"content": [
{
"type": "text",
"text": "What type of room is this? Just respond with one word: living-room, bedroom, kitchen, bathroom, dining-room, or office."
},
{
"type": "image_url",
"url": image_url
}
]
}
],
max_tokens=10
)
room_type = response.choices[0].message.content.strip().lower()
return room_type if room_type in ["living-room", "bedroom", "kitchen", "bathroom", "dining-room", "office"] else "living-room"
except Exception as e:
print(f"Room detection error: {str(e)}")
return "living-room"
async def generate_staged_image(
self,
image_url: str,
style: str,
room_type: Optional[str] = None
) -> Dict[str, Any]:
"""
Generate a staged image using OpenAI's DALL-E API.
"""
try:
if not room_type:
room_type = await self.detect_room_type(image_url)
style_config = INTERIOR_STYLES.get(style, INTERIOR_STYLES["modern"])
# Construct the prompt
prompt = f"Transform this {room_type} into a {style_config['prompt']}, maintain the room's layout and architectural features, photorealistic, professional interior design photography style"
try:
# Generate the staged image using DALL-E
response = self.client.images.generate(
model="dall-e-3",
prompt=prompt,
n=1,
size="1024x1024",
quality="standard",
response_format="url" # Explicitly request URL format
)
# Get the URL of the generated image
staged_image_url = response.data[0].url
return {
"success": True,
"staged_image_url": staged_image_url,
"room_type": room_type,
"style": style,
"prompt": prompt
}
except Exception as e:
print(f"DALL-E generation error: {str(e)}")
return {
"success": False,
"error": str(e),
"room_type": room_type,
"style": style
}
except Exception as e:
return {
"success": False,
"error": str(e),
"room_type": room_type,
"style": style
}
async def process_image(
self,
image_url: str,
style: str,
room_type: Optional[str] = None
) -> Dict[str, Any]:
"""
Process an image through the staging pipeline.
"""
try:
# Generate the staged image
result = await self.generate_staged_image(image_url, style, room_type)
if not result["success"]:
return {
"success": False,
"error": result["error"]
}
return {
"success": True,
"original_image": image_url,
"staged_image": result["staged_image_url"],
"room_type": result["room_type"],
"style": style
}
except Exception as e:
return {
"success": False,
"error": str(e)
}