mgbam commited on
Commit
f7f6fe3
·
verified ·
1 Parent(s): b22fc56

Create image_services.py

Browse files
Files changed (1) hide show
  1. core/image_services.py +132 -0
core/image_services.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # storyverse_weaver/core/image_services.py
2
+ import os
3
+ import requests # For generic API calls
4
+ import base64
5
+ from io import BytesIO
6
+ from PIL import Image
7
+ # from dotenv import load_dotenv
8
+ # load_dotenv()
9
+
10
+ # --- API Key Configuration (Use specific names for StoryVerse) ---
11
+ STABILITY_API_KEY = os.getenv("STORYVERSE_STABILITY_API_KEY")
12
+ OPENAI_API_KEY = os.getenv("STORYVERSE_OPENAI_API_KEY") # For DALL-E
13
+ # HUGGINGFACE_TOKEN also used by llm_services, can be reused if using HF image models
14
+
15
+ STABILITY_API_CONFIGURED = bool(STABILITY_API_KEY and STABILITY_API_KEY.strip())
16
+ OPENAI_DALLE_CONFIGURED = bool(OPENAI_API_KEY and OPENAI_API_KEY.strip())
17
+ # HF_IMAGE_CONFIGURED = bool(HF_TOKEN and HF_TOKEN.strip()) # Assuming HF_TOKEN is also for image models
18
+
19
+ class ImageGenResponse:
20
+ def __init__(self, image: Image.Image = None, image_url: str = None, error: str = None, success: bool = True, provider: str = "unknown"):
21
+ self.image = image # PIL Image object
22
+ self.image_url = image_url # If API returns a URL
23
+ self.error = error
24
+ self.success = success
25
+ self.provider = provider
26
+
27
+ def initialize_image_llms(): # Simple function to print status
28
+ print("INFO: image_services.py - Initializing Image Generation services...")
29
+ if STABILITY_API_CONFIGURED: print("SUCCESS: image_services.py - Stability AI API Key detected.")
30
+ else: print("WARNING: image_services.py - STORYVERSE_STABILITY_API_KEY not found. Stability AI disabled.")
31
+ if OPENAI_DALLE_CONFIGURED: print("SUCCESS: image_services.py - OpenAI API Key detected (for DALL-E).")
32
+ else: print("WARNING: image_services.py - STORYVERSE_OPENAI_API_KEY not found. DALL-E disabled.")
33
+ # if HF_IMAGE_CONFIGURED: print("INFO: image_services.py - Hugging Face Token detected (can be used for HF image models).")
34
+ print("INFO: image_services.py - Image LLM Init complete.")
35
+
36
+
37
+ # --- Stability AI (Example) ---
38
+ def generate_image_stabilityai(prompt: str, style_preset: str = None, negative_prompt: str = None,
39
+ engine_id: str = "stable-diffusion-xl-1024-v1-0",
40
+ steps: int = 30, cfg_scale: float = 7.0,
41
+ width: int = 1024, height: int = 1024) -> ImageGenResponse:
42
+ if not STABILITY_API_CONFIGURED:
43
+ return ImageGenResponse(error="Stability AI API key not configured.", success=False, provider="StabilityAI")
44
+
45
+ api_host = os.getenv('API_HOST', 'https://api.stability.ai')
46
+ request_url = f"{api_host}/v1/generation/{engine_id}/text-to-image"
47
+
48
+ payload = {
49
+ "text_prompts": [{"text": prompt}],
50
+ "cfg_scale": cfg_scale,
51
+ "height": height,
52
+ "width": width,
53
+ "steps": steps,
54
+ "samples": 1,
55
+ }
56
+ if style_preset: payload["style_preset"] = style_preset
57
+ if negative_prompt: payload["text_prompts"].append({"text": negative_prompt, "weight": -1.0})
58
+
59
+ headers = {
60
+ "Accept": "application/json",
61
+ "Content-Type": "application/json",
62
+ "Authorization": f"Bearer {STABILITY_API_KEY}"
63
+ }
64
+ print(f"DEBUG: image_services.py - Calling Stability AI with prompt: {prompt[:50]}...")
65
+ try:
66
+ response = requests.post(request_url, headers=headers, json=payload, timeout=60) # Increased timeout
67
+ response.raise_for_status() # Will raise an HTTPError if the HTTP request returned an unsuccessful status code
68
+
69
+ artifacts = response.json().get("artifacts")
70
+ if not artifacts:
71
+ return ImageGenResponse(error="No image artifacts found in Stability AI response.", success=False, provider="StabilityAI", raw_response=response.text)
72
+
73
+ image_data = base64.b64decode(artifacts[0]["base64"])
74
+ image = Image.open(BytesIO(image_data))
75
+ print("DEBUG: image_services.py - Stability AI image generated successfully.")
76
+ return ImageGenResponse(image=image, provider="StabilityAI")
77
+ except requests.exceptions.RequestException as e:
78
+ error_msg = f"Stability AI API request failed: {type(e).__name__} - {str(e)}"
79
+ if hasattr(e, 'response') and e.response is not None: error_msg += f" - Response: {e.response.text[:200]}"
80
+ print(f"ERROR: image_services.py - {error_msg}")
81
+ return ImageGenResponse(error=error_msg, success=False, provider="StabilityAI", raw_response=e)
82
+ except Exception as e: # Catch other potential errors like JSON decoding
83
+ error_msg = f"Error processing Stability AI response: {type(e).__name__} - {str(e)}"
84
+ print(f"ERROR: image_services.py - {error_msg}")
85
+ return ImageGenResponse(error=error_msg, success=False, provider="StabilityAI", raw_response=e)
86
+
87
+
88
+ # --- DALL-E (Conceptual - you'd need 'openai' library and setup) ---
89
+ def generate_image_dalle(prompt: str, size="1024x1024", quality="standard", n=1) -> ImageGenResponse:
90
+ if not OPENAI_DALLE_CONFIGURED:
91
+ return ImageGenResponse(error="OpenAI DALL-E API key not configured.", success=False, provider="DALL-E")
92
+ try:
93
+ # from openai import OpenAI # Would be imported at top level
94
+ # client = OpenAI(api_key=OPENAI_API_KEY)
95
+ # response = client.images.generate(
96
+ # model="dall-e-3", # or "dall-e-2"
97
+ # prompt=prompt,
98
+ # size=size,
99
+ # quality=quality,
100
+ # n=n,
101
+ # response_format="url" # or "b64_json"
102
+ # )
103
+ # image_url = response.data[0].url
104
+ # image_content = requests.get(image_url).content
105
+ # image = Image.open(BytesIO(image_content))
106
+ # return ImageGenResponse(image=image, image_url=image_url, provider="DALL-E")
107
+ print("DEBUG: image_services.py - DALL-E call placeholder.") # Placeholder
108
+ # Simulate an image for now
109
+ dummy_image = Image.new('RGB', (512, 512), color = 'skyblue')
110
+ return ImageGenResponse(image=dummy_image, provider="DALL-E (Simulated)")
111
+ except Exception as e:
112
+ return ImageGenResponse(error=f"DALL-E API Error: {type(e).__name__} - {str(e)}", success=False, provider="DALL-E")
113
+
114
+
115
+ # --- Hugging Face Image Model (Conceptual - via Inference API or local Diffusers) ---
116
+ # def generate_image_hf_model(prompt: str, model_id="stabilityai/stable-diffusion-xl-base-1.0") -> ImageGenResponse:
117
+ # if not HF_IMAGE_CONFIGURED:
118
+ # return ImageGenResponse(error="HF Token not configured for image models.", success=False, provider="HF")
119
+ # try:
120
+ # You might use a client similar to hf_inference_text_client but for image generation task
121
+ # Or if it's a diffusers pipeline, you'd load and run it.
122
+ # This requires the `diffusers` library and often significant compute.
123
+ # response_bytes = hf_some_image_client.text_to_image(prompt, model=model_id) # Hypothetical client method
124
+ # image = Image.open(BytesIO(response_bytes))
125
+ # return ImageGenResponse(image=image, provider=f"HF ({model_id})")
126
+ # print("DEBUG: image_services.py - HF Image Model call placeholder.")
127
+ # dummy_image = Image.new('RGB', (512, 512), color = 'lightgreen')
128
+ # return ImageGenResponse(image=dummy_image, provider=f"HF ({model_id} - Simulated)")
129
+ # except Exception as e:
130
+ # return ImageGenResponse(error=f"HF Image Model Error: {type(e).__name__} - {str(e)}", success=False, provider=f"HF ({model_id})")
131
+
132
+ print("DEBUG: core.image_services (for StoryVerseWeaver) - Module defined.")