indoxrouter 0.1.19__tar.gz → 0.1.21__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/PKG-INFO +1 -1
- indoxrouter-0.1.21/examples/provider_specific_image_generation.py +163 -0
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/indoxrouter/client.py +24 -8
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/indoxrouter.egg-info/PKG-INFO +1 -1
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/indoxrouter.egg-info/SOURCES.txt +1 -0
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/pyproject.toml +1 -1
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/MANIFEST.in +0 -0
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/README.md +0 -0
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/cookbook/README.md +0 -0
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/cookbook/indoxRouter_cookbook.ipynb +0 -0
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/examples/google_image_generation.py +0 -0
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/examples/image_generation.py +0 -0
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/indoxrouter/__init__.py +0 -0
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/indoxrouter/constants.py +0 -0
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/indoxrouter/exceptions.py +0 -0
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/indoxrouter.egg-info/dependency_links.txt +0 -0
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/indoxrouter.egg-info/requires.txt +0 -0
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/indoxrouter.egg-info/top_level.txt +0 -0
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/setup.cfg +0 -0
- {indoxrouter-0.1.19 → indoxrouter-0.1.21}/tests/test_image.py +0 -0
@@ -0,0 +1,163 @@
|
|
1
|
+
"""
|
2
|
+
Example script demonstrating image generation with different providers through indoxRouter.
|
3
|
+
|
4
|
+
This script shows how to generate images using different providers (OpenAI, Google, xAI)
|
5
|
+
with their provider-specific parameters and handling.
|
6
|
+
|
7
|
+
Requirements:
|
8
|
+
- Install indoxRouter: pip install indoxrouter
|
9
|
+
- Set INDOX_ROUTER_API_KEY environment variable with your API key
|
10
|
+
"""
|
11
|
+
|
12
|
+
import os
|
13
|
+
import base64
|
14
|
+
from io import BytesIO
|
15
|
+
import requests
|
16
|
+
from datetime import datetime
|
17
|
+
|
18
|
+
from indoxrouter import Client
|
19
|
+
|
20
|
+
# For displaying images in notebooks
|
21
|
+
try:
|
22
|
+
from IPython.display import Image, display
|
23
|
+
|
24
|
+
in_notebook = True
|
25
|
+
except ImportError:
|
26
|
+
in_notebook = False
|
27
|
+
|
28
|
+
# Initialize client with API key from environment variable
|
29
|
+
api_key = os.environ.get("INDOX_ROUTER_API_KEY")
|
30
|
+
if not api_key:
|
31
|
+
print("Please set the INDOX_ROUTER_API_KEY environment variable")
|
32
|
+
exit(1)
|
33
|
+
|
34
|
+
client = Client(api_key=api_key)
|
35
|
+
|
36
|
+
|
37
|
+
def save_image_from_url(url, filename):
|
38
|
+
"""Download and save an image from a URL."""
|
39
|
+
response = requests.get(url)
|
40
|
+
if response.status_code == 200:
|
41
|
+
with open(filename, "wb") as f:
|
42
|
+
f.write(response.content)
|
43
|
+
print(f"Image saved to {filename}")
|
44
|
+
else:
|
45
|
+
print(f"Failed to download image: {response.status_code}")
|
46
|
+
|
47
|
+
|
48
|
+
def save_image_from_b64(b64_data, filename):
|
49
|
+
"""Save an image from base64 data."""
|
50
|
+
image_data = base64.b64decode(b64_data)
|
51
|
+
with open(filename, "wb") as f:
|
52
|
+
f.write(image_data)
|
53
|
+
print(f"Image saved to {filename}")
|
54
|
+
|
55
|
+
|
56
|
+
def display_response_image(response, provider, model):
|
57
|
+
"""Display image from response and save it."""
|
58
|
+
try:
|
59
|
+
if "data" in response and response["data"]:
|
60
|
+
image_data = response["data"][0]
|
61
|
+
|
62
|
+
# Create a timestamp for unique filenames
|
63
|
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
64
|
+
|
65
|
+
if "url" in image_data and image_data["url"]:
|
66
|
+
filename = f"{provider}_{model}_{timestamp}.png"
|
67
|
+
save_image_from_url(image_data["url"], filename)
|
68
|
+
|
69
|
+
# Display in notebook if possible
|
70
|
+
if in_notebook:
|
71
|
+
display(Image(url=image_data["url"]))
|
72
|
+
|
73
|
+
elif "b64_json" in image_data and image_data["b64_json"]:
|
74
|
+
filename = f"{provider}_{model}_{timestamp}.png"
|
75
|
+
save_image_from_b64(image_data["b64_json"], filename)
|
76
|
+
|
77
|
+
# Display in notebook if possible
|
78
|
+
if in_notebook:
|
79
|
+
display(Image(data=base64.b64decode(image_data["b64_json"])))
|
80
|
+
|
81
|
+
# Check for revised prompt (DALL-E 3 often revises prompts)
|
82
|
+
if "revised_prompt" in image_data and image_data["revised_prompt"]:
|
83
|
+
print(f"Revised prompt: {image_data['revised_prompt']}")
|
84
|
+
else:
|
85
|
+
print("No image data found in response")
|
86
|
+
except Exception as e:
|
87
|
+
print(f"Error displaying/saving image: {str(e)}")
|
88
|
+
|
89
|
+
|
90
|
+
def main():
|
91
|
+
"""Main function demonstrating image generation with different providers."""
|
92
|
+
|
93
|
+
# Example prompt for all providers
|
94
|
+
prompt = "A tranquil zen garden with cherry blossoms and a small pond"
|
95
|
+
|
96
|
+
print("\n=== OpenAI (DALL-E 2) ===")
|
97
|
+
print("Uses pixel dimensions (e.g., '1024x1024')")
|
98
|
+
try:
|
99
|
+
openai_response = client.images(
|
100
|
+
prompt=prompt,
|
101
|
+
model="openai/dall-e-2",
|
102
|
+
size="1024x1024", # OpenAI uses pixel dimensions
|
103
|
+
)
|
104
|
+
print(f"Response received - Success: {openai_response.get('success', False)}")
|
105
|
+
print(f"Cost: ${openai_response.get('usage', {}).get('cost', 0):.4f}")
|
106
|
+
display_response_image(openai_response, "openai", "dall-e-2")
|
107
|
+
except Exception as e:
|
108
|
+
print(f"Error with OpenAI: {str(e)}")
|
109
|
+
|
110
|
+
print("\n=== Google (Imagen) ===")
|
111
|
+
print("Uses aspect ratios (e.g., '1:1', '16:9') instead of pixel dimensions")
|
112
|
+
try:
|
113
|
+
google_response = client.images(
|
114
|
+
prompt=prompt,
|
115
|
+
model="google/imagen-3.0-generate-002",
|
116
|
+
# Note: Use 'aspect_ratio' instead of 'size' for Google
|
117
|
+
aspect_ratio="1:1", # Google uses aspect ratios
|
118
|
+
negative_prompt="cartoon, illustration, drawing, painting",
|
119
|
+
)
|
120
|
+
print(f"Response received - Success: {google_response.get('success', False)}")
|
121
|
+
print(f"Cost: ${google_response.get('usage', {}).get('cost', 0):.4f}")
|
122
|
+
display_response_image(google_response, "google", "imagen")
|
123
|
+
except Exception as e:
|
124
|
+
print(f"Error with Google: {str(e)}")
|
125
|
+
|
126
|
+
print("\n=== xAI (Grok) ===")
|
127
|
+
print("Does not use size parameter, only supports specific parameters")
|
128
|
+
try:
|
129
|
+
xai_response = client.images(
|
130
|
+
prompt=prompt,
|
131
|
+
model="xai/grok-2-image",
|
132
|
+
# Note: xAI doesn't support size parameter, so we don't include it
|
133
|
+
response_format="url", # xAI supports response_format
|
134
|
+
)
|
135
|
+
print(f"Response received - Success: {xai_response.get('success', False)}")
|
136
|
+
print(f"Cost: ${xai_response.get('usage', {}).get('cost', 0):.4f}")
|
137
|
+
display_response_image(xai_response, "xai", "grok-2-image")
|
138
|
+
except Exception as e:
|
139
|
+
print(f"Error with xAI: {str(e)}")
|
140
|
+
|
141
|
+
# Advanced example with DALL-E 3
|
142
|
+
print("\n=== OpenAI (DALL-E 3) with Advanced Parameters ===")
|
143
|
+
try:
|
144
|
+
dalle3_response = client.images(
|
145
|
+
prompt="A beautiful underwater scene with coral reef and tropical fish",
|
146
|
+
model="openai/dall-e-3",
|
147
|
+
size="1024x1024",
|
148
|
+
quality="standard", # 'standard' or 'hd'
|
149
|
+
style="vivid", # 'vivid' or 'natural'
|
150
|
+
response_format="url",
|
151
|
+
)
|
152
|
+
print(f"Response received - Success: {dalle3_response.get('success', False)}")
|
153
|
+
print(f"Cost: ${dalle3_response.get('usage', {}).get('cost', 0):.4f}")
|
154
|
+
display_response_image(dalle3_response, "openai", "dall-e-3")
|
155
|
+
except Exception as e:
|
156
|
+
print(f"Error with DALL-E 3: {str(e)}")
|
157
|
+
|
158
|
+
# Close the client when done
|
159
|
+
client.close()
|
160
|
+
|
161
|
+
|
162
|
+
if __name__ == "__main__":
|
163
|
+
main()
|
@@ -597,6 +597,8 @@ class Client:
|
|
597
597
|
output_mime_type: Optional[str] = None,
|
598
598
|
add_watermark: Optional[bool] = None,
|
599
599
|
enhance_prompt: Optional[bool] = None,
|
600
|
+
# Google-specific direct parameters
|
601
|
+
aspect_ratio: Optional[str] = None,
|
600
602
|
**kwargs,
|
601
603
|
) -> Dict[str, Any]:
|
602
604
|
"""
|
@@ -608,7 +610,7 @@ class Client:
|
|
608
610
|
|
609
611
|
# Provider-specific parameters - will only be included if explicitly provided
|
610
612
|
# Note: Different providers support different parameters
|
611
|
-
size: Image size - For OpenAI: "1024x1024", "512x512", etc. For Google:
|
613
|
+
size: Image size - For OpenAI: "1024x1024", "512x512", etc. For Google: use aspect_ratio instead
|
612
614
|
n: Number of images to generate
|
613
615
|
quality: Image quality (e.g., "standard", "hd") - supported by some providers
|
614
616
|
style: Image style (e.g., "vivid", "natural") - supported by some providers
|
@@ -635,6 +637,7 @@ class Client:
|
|
635
637
|
output_mime_type: MIME type of the generated image
|
636
638
|
add_watermark: Whether to add a watermark to the generated images
|
637
639
|
enhance_prompt: Whether to use prompt rewriting logic
|
640
|
+
aspect_ratio: Aspect ratio for Google models (e.g., "1:1", "16:9") - preferred over size
|
638
641
|
|
639
642
|
**kwargs: Additional parameters to pass to the API
|
640
643
|
|
@@ -665,13 +668,26 @@ class Client:
|
|
665
668
|
if n is not None:
|
666
669
|
data["n"] = n
|
667
670
|
|
668
|
-
# Handle size
|
669
|
-
if
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
671
|
+
# Handle size/aspect_ratio parameters based on provider
|
672
|
+
if provider.lower() == "google":
|
673
|
+
# For Google, use aspect_ratio instead of size
|
674
|
+
if aspect_ratio is not None:
|
675
|
+
data["aspect_ratio"] = aspect_ratio
|
676
|
+
elif size is not None:
|
677
|
+
# Convert size to aspect_ratio
|
678
|
+
formatted_size = self._format_image_size_for_provider(
|
679
|
+
size, provider, model
|
680
|
+
)
|
681
|
+
data["aspect_ratio"] = formatted_size
|
682
|
+
else:
|
683
|
+
# Default aspect_ratio for Google
|
684
|
+
data["aspect_ratio"] = "1:1"
|
685
|
+
elif provider.lower() == "xai":
|
686
|
+
# xAI doesn't support size parameter
|
687
|
+
pass
|
688
|
+
elif size is not None:
|
689
|
+
# For other providers (like OpenAI), use size as is
|
690
|
+
data["size"] = size
|
675
691
|
|
676
692
|
if quality is not None:
|
677
693
|
data["quality"] = quality
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|