Skip to content

Commit 79ef877

Browse files
authored
Merge pull request #39 from JigsawStack/pysdk/updates
2 parents d9e5b87 + 723587d commit 79ef877

File tree

7 files changed

+198
-142
lines changed

7 files changed

+198
-142
lines changed

biome.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
3+
"files": {
4+
"ignoreUnknown": false,
5+
"ignore": []
6+
},
7+
"formatter": {
8+
"enabled": true,
9+
"useEditorconfig": true,
10+
"formatWithErrors": false,
11+
"indentStyle": "space",
12+
"indentWidth": 2,
13+
"lineEnding": "lf",
14+
"lineWidth": 150,
15+
"attributePosition": "auto",
16+
"bracketSpacing": true
17+
},
18+
"organizeImports": {
19+
"enabled": true
20+
},
21+
"linter": {
22+
"enabled": false
23+
},
24+
"javascript": {
25+
"formatter": {
26+
"jsxQuoteStyle": "double",
27+
"quoteProperties": "asNeeded",
28+
"trailingCommas": "es5",
29+
"semicolons": "always",
30+
"arrowParentheses": "always",
31+
"bracketSameLine": false,
32+
"quoteStyle": "double",
33+
"attributePosition": "auto",
34+
"bracketSpacing": true
35+
}
36+
}
37+
}

jigsawstack/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
from .prompt_engine import PromptEngine, AsyncPromptEngine
1616
from .embedding import Embedding, AsyncEmbedding
1717
from .exceptions import JigsawStackError
18+
from .image_generation import ImageGeneration, AsyncImageGeneration
1819

1920

2021
class JigsawStack:
2122
audio: Audio
2223
vision: Vision
24+
image_generation: ImageGeneration
2325
file: Store
2426
web: Web
2527
search: Search
@@ -116,6 +118,11 @@ def __init__(
116118
api_url=api_url,
117119
disable_request_logging=disable_request_logging,
118120
).execute
121+
self.image_generation = ImageGeneration(
122+
api_key=api_key,
123+
api_url=api_url,
124+
disable_request_logging=disable_request_logging,
125+
).image_generation
119126

120127

121128
class AsyncJigsawStack:
@@ -124,6 +131,7 @@ class AsyncJigsawStack:
124131
web: AsyncWeb
125132
audio: AsyncAudio
126133
vision: AsyncVision
134+
image_generation: AsyncImageGeneration
127135
store: AsyncStore
128136
prompt_engine: AsyncPromptEngine
129137
api_key: str
@@ -227,6 +235,12 @@ def __init__(
227235
disable_request_logging=disable_request_logging,
228236
).execute
229237

238+
self.image_generation = AsyncImageGeneration(
239+
api_key=api_key,
240+
api_url=api_url,
241+
disable_request_logging=disable_request_logging,
242+
).image_generation
243+
230244

231245
# Create a global instance of the Web class
232246
__all__ = ["JigsawStack", "Search", "JigsawStackError", "AsyncJigsawStack"]

jigsawstack/image_generation.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
from typing import Any, Dict, List, Union, cast
2+
from typing_extensions import NotRequired, TypedDict, Literal, Required
3+
from .request import Request, RequestConfig
4+
from .async_request import AsyncRequest
5+
6+
from typing import List, Union
7+
from ._config import ClientConfig
8+
9+
class ImageGenerationParams(TypedDict):
10+
prompt: Required[str]
11+
""""
12+
The text to generate the image from."
13+
"""
14+
aspect_ratio: NotRequired[Literal["1:1", "16:9", "21:9", "3:2", "2:3", "4:5", "5:4", "3:4", "4:3", "9:16", "9:21"]]
15+
"""
16+
The aspect ratio of the image. The default is 1:1.
17+
"""
18+
width: NotRequired[int]
19+
""""
20+
The width of the image. The default is 512."
21+
"""
22+
height: NotRequired[int]
23+
"""
24+
The height of the image. The default is 512."
25+
"""
26+
steps: NotRequired[int]
27+
""""
28+
The number of steps to generate the image.""
29+
"""
30+
advance_config: NotRequired[Dict[str, Union[int, str]]]
31+
"""
32+
The advance configuration for the image generation. The default is None.
33+
You can pass the following:
34+
- `seed`: The seed for the image generation. The default is None.
35+
- `guidance`: The guidance for the image generation. The default is None.
36+
- `negative_prompt`: The negative prompt for the image generation. The default is None.
37+
"""
38+
39+
class ImageGenerationResponse(TypedDict):
40+
success: bool
41+
"""
42+
Indicates whether the image generation was successful.
43+
"""
44+
image: bytes
45+
"""
46+
The generated image as a blob.
47+
"""
48+
49+
class ImageGeneration(ClientConfig):
50+
config: RequestConfig
51+
52+
def __init__(
53+
self,
54+
api_key: str,
55+
api_url: str,
56+
disable_request_logging: Union[bool, None] = False,
57+
):
58+
super().__init__(api_key, api_url, disable_request_logging=disable_request_logging)
59+
self.config = RequestConfig(
60+
api_url=api_url,
61+
api_key=api_key,
62+
disable_request_logging=disable_request_logging,
63+
)
64+
65+
def image_generation(self, params: ImageGenerationParams) -> ImageGenerationResponse:
66+
path = "/ai/image_generation"
67+
resp = Request(
68+
config=self.config,
69+
path=path,
70+
params=cast(Dict[Any, Any], params), # type: ignore
71+
verb="post",
72+
).perform()
73+
return resp
74+
75+
class AsyncImageGeneration(ClientConfig):
76+
config: RequestConfig
77+
78+
def __init__(
79+
self,
80+
api_key: str,
81+
api_url: str,
82+
disable_request_logging: Union[bool, None] = False,
83+
):
84+
super().__init__(api_key, api_url, disable_request_logging=disable_request_logging)
85+
self.config = RequestConfig(
86+
api_url=api_url,
87+
api_key=api_key,
88+
disable_request_logging=disable_request_logging,
89+
)
90+
91+
async def image_generation(self, params: ImageGenerationParams) -> ImageGenerationResponse:
92+
path = "/ai/image_generation"
93+
resp = await AsyncRequest(
94+
config=self.config,
95+
path=path,
96+
params=cast(Dict[Any, Any], params), # type: ignore
97+
verb="post",
98+
).perform()
99+
return resp
100+
101+
102+
103+

jigsawstack/request.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ def perform(self) -> Union[T, None]:
5656

5757
# this is a safety net, if we get here it means the JigsawStack API is having issues
5858
# and most likely the gateway is returning htmls
59-
if "application/json" not in resp.headers["content-type"] and "audio/wav" not in resp.headers["content-type"]:
59+
if "application/json" not in resp.headers["content-type"] \
60+
and "audio/wav" not in resp.headers["content-type"] \
61+
and "image/png" not in resp.headers["content-type"]:
6062
raise_for_code_and_type(
6163
code=500,
6264
message="Failed to parse JigsawStack API response. Please try again.",
@@ -72,9 +74,9 @@ def perform(self) -> Union[T, None]:
7274
err=error.get("error"),
7375
)
7476

75-
if "audio/wav" in resp.headers["content-type"]:
77+
if "audio/wav" or "image/png" in resp.headers["content-type"]:
7678
return cast(T, resp) # we return the response object, instead of the json
77-
79+
7880
return cast(T, resp.json())
7981

8082
def perform_file(self) -> Union[T, None]:

0 commit comments

Comments
 (0)