Skip to content

Commit ed8e899

Browse files
feat(api): manual updates
1 parent 859b4db commit ed8e899

19 files changed

+1880
-218
lines changed

.stats.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 111
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-c7dacca97e28bceff218684bb429481a70aa47aadad983ed9178bfda75ff4cd2.yml
3-
openapi_spec_hash: 28eb1bb901ca10d2e37db4606d2bcfa7
4-
config_hash: 167ad0ca036d0f023c78e6496b4311e8
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-670ea0d2cc44f52a87dd3cadea45632953283e0636ba30788fdbdb22a232ccac.yml
3+
openapi_spec_hash: d8b7d38911fead545adf3e4297956410
4+
config_hash: 5525bda35e48ea6387c6175c4d1651fa

api.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,17 @@ Methods:
127127
Types:
128128

129129
```python
130-
from openai.types import Image, ImageModel, ImagesResponse
130+
from openai.types import (
131+
Image,
132+
ImageEditCompletedEvent,
133+
ImageEditPartialImageEvent,
134+
ImageEditStreamEvent,
135+
ImageGenCompletedEvent,
136+
ImageGenPartialImageEvent,
137+
ImageGenStreamEvent,
138+
ImageModel,
139+
ImagesResponse,
140+
)
131141
```
132142

133143
Methods:

examples/image_stream.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/usr/bin/env python
2+
3+
import base64
4+
from pathlib import Path
5+
6+
from openai import OpenAI
7+
8+
client = OpenAI()
9+
10+
11+
def main() -> None:
12+
"""Example of OpenAI image streaming with partial images."""
13+
stream = client.images.generate(
14+
model="gpt-image-1",
15+
prompt="A cute baby sea otter",
16+
n=1,
17+
size="1024x1024",
18+
stream=True,
19+
partial_images=3,
20+
)
21+
22+
for event in stream:
23+
if event.type == "image_generation.partial_image":
24+
print(f" Partial image {event.partial_image_index + 1}/3 received")
25+
print(f" Size: {len(event.b64_json)} characters (base64)")
26+
27+
# Save partial image to file
28+
filename = f"partial_{event.partial_image_index + 1}.png"
29+
image_data = base64.b64decode(event.b64_json)
30+
with open(filename, "wb") as f:
31+
f.write(image_data)
32+
print(f" 💾 Saved to: {Path(filename).resolve()}")
33+
34+
elif event.type == "image_generation.completed":
35+
print(f"\n✅ Final image completed!")
36+
print(f" Size: {len(event.b64_json)} characters (base64)")
37+
38+
# Save final image to file
39+
filename = "final_image.png"
40+
image_data = base64.b64decode(event.b64_json)
41+
with open(filename, "wb") as f:
42+
f.write(image_data)
43+
print(f" 💾 Saved to: {Path(filename).resolve()}")
44+
45+
else:
46+
print(f"❓ Unknown event: {event}") # type: ignore[unreachable]
47+
48+
49+
if __name__ == "__main__":
50+
try:
51+
main()
52+
except Exception as error:
53+
print(f"Error generating image: {error}")

src/openai/_streaming.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,12 @@ def __stream__(self) -> Iterator[_T]:
5959
if sse.data.startswith("[DONE]"):
6060
break
6161

62-
if sse.event is None or sse.event.startswith("response.") or sse.event.startswith("transcript."):
62+
if sse.event is None or (
63+
sse.event.startswith("response.") or
64+
sse.event.startswith("transcript.") or
65+
sse.event.startswith("image_edit.") or
66+
sse.event.startswith("image_generation.")
67+
):
6368
data = sse.json()
6469
if is_mapping(data) and data.get("error"):
6570
message = None

src/openai/resources/images.py

Lines changed: 1262 additions & 191 deletions
Large diffs are not rendered by default.

src/openai/types/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,19 @@
6060
from .image_generate_params import ImageGenerateParams as ImageGenerateParams
6161
from .eval_retrieve_response import EvalRetrieveResponse as EvalRetrieveResponse
6262
from .file_chunking_strategy import FileChunkingStrategy as FileChunkingStrategy
63+
from .image_gen_stream_event import ImageGenStreamEvent as ImageGenStreamEvent
6364
from .upload_complete_params import UploadCompleteParams as UploadCompleteParams
6465
from .container_create_params import ContainerCreateParams as ContainerCreateParams
6566
from .container_list_response import ContainerListResponse as ContainerListResponse
6667
from .embedding_create_params import EmbeddingCreateParams as EmbeddingCreateParams
68+
from .image_edit_stream_event import ImageEditStreamEvent as ImageEditStreamEvent
6769
from .completion_create_params import CompletionCreateParams as CompletionCreateParams
6870
from .moderation_create_params import ModerationCreateParams as ModerationCreateParams
6971
from .vector_store_list_params import VectorStoreListParams as VectorStoreListParams
7072
from .container_create_response import ContainerCreateResponse as ContainerCreateResponse
7173
from .create_embedding_response import CreateEmbeddingResponse as CreateEmbeddingResponse
74+
from .image_gen_completed_event import ImageGenCompletedEvent as ImageGenCompletedEvent
75+
from .image_edit_completed_event import ImageEditCompletedEvent as ImageEditCompletedEvent
7276
from .moderation_create_response import ModerationCreateResponse as ModerationCreateResponse
7377
from .vector_store_create_params import VectorStoreCreateParams as VectorStoreCreateParams
7478
from .vector_store_search_params import VectorStoreSearchParams as VectorStoreSearchParams
@@ -79,8 +83,10 @@
7983
from .vector_store_search_response import VectorStoreSearchResponse as VectorStoreSearchResponse
8084
from .websocket_connection_options import WebsocketConnectionOptions as WebsocketConnectionOptions
8185
from .image_create_variation_params import ImageCreateVariationParams as ImageCreateVariationParams
86+
from .image_gen_partial_image_event import ImageGenPartialImageEvent as ImageGenPartialImageEvent
8287
from .static_file_chunking_strategy import StaticFileChunkingStrategy as StaticFileChunkingStrategy
8388
from .eval_custom_data_source_config import EvalCustomDataSourceConfig as EvalCustomDataSourceConfig
89+
from .image_edit_partial_image_event import ImageEditPartialImageEvent as ImageEditPartialImageEvent
8490
from .moderation_image_url_input_param import ModerationImageURLInputParam as ModerationImageURLInputParam
8591
from .auto_file_chunking_strategy_param import AutoFileChunkingStrategyParam as AutoFileChunkingStrategyParam
8692
from .moderation_multi_modal_input_param import ModerationMultiModalInputParam as ModerationMultiModalInputParam
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from typing_extensions import Literal
4+
5+
from .._models import BaseModel
6+
7+
__all__ = ["ImageEditCompletedEvent", "Usage", "UsageInputTokensDetails"]
8+
9+
10+
class UsageInputTokensDetails(BaseModel):
11+
image_tokens: int
12+
"""The number of image tokens in the input prompt."""
13+
14+
text_tokens: int
15+
"""The number of text tokens in the input prompt."""
16+
17+
18+
class Usage(BaseModel):
19+
input_tokens: int
20+
"""The number of tokens (images and text) in the input prompt."""
21+
22+
input_tokens_details: UsageInputTokensDetails
23+
"""The input tokens detailed information for the image generation."""
24+
25+
output_tokens: int
26+
"""The number of image tokens in the output image."""
27+
28+
total_tokens: int
29+
"""The total number of tokens (images and text) used for the image generation."""
30+
31+
32+
class ImageEditCompletedEvent(BaseModel):
33+
b64_json: str
34+
"""Base64-encoded final edited image data, suitable for rendering as an image."""
35+
36+
background: Literal["transparent", "opaque", "auto"]
37+
"""The background setting for the edited image."""
38+
39+
created_at: int
40+
"""The Unix timestamp when the event was created."""
41+
42+
output_format: Literal["png", "webp", "jpeg"]
43+
"""The output format for the edited image."""
44+
45+
quality: Literal["low", "medium", "high", "auto"]
46+
"""The quality setting for the edited image."""
47+
48+
size: Literal["1024x1024", "1024x1536", "1536x1024", "auto"]
49+
"""The size of the edited image."""
50+
51+
type: Literal["image_edit.completed"]
52+
"""The type of the event. Always `image_edit.completed`."""
53+
54+
usage: Usage
55+
"""For `gpt-image-1` only, the token usage information for the image generation."""

src/openai/types/image_edit_params.py

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
from .._types import FileTypes
99
from .image_model import ImageModel
1010

11-
__all__ = ["ImageEditParams"]
11+
__all__ = ["ImageEditParamsBase", "ImageEditParamsNonStreaming", "ImageEditParamsStreaming"]
1212

1313

14-
class ImageEditParams(TypedDict, total=False):
14+
class ImageEditParamsBase(TypedDict, total=False):
1515
image: Required[Union[FileTypes, List[FileTypes]]]
1616
"""The image(s) to edit. Must be a supported image file or an array of images.
1717
@@ -40,6 +40,13 @@ class ImageEditParams(TypedDict, total=False):
4040
be set to either `png` (default value) or `webp`.
4141
"""
4242

43+
input_fidelity: Optional[Literal["high", "low"]]
44+
"""
45+
Control how much effort the model will exert to match the style and features,
46+
especially facial features, of input images. This parameter is only supported
47+
for `gpt-image-1`. Supports `high` and `low`. Defaults to `low`.
48+
"""
49+
4350
mask: FileTypes
4451
"""An additional image whose fully transparent areas (e.g.
4552
@@ -72,6 +79,14 @@ class ImageEditParams(TypedDict, total=False):
7279
`jpeg`, or `webp`. The default value is `png`.
7380
"""
7481

82+
partial_images: Optional[int]
83+
"""The number of partial images to generate.
84+
85+
This parameter is used for streaming responses that return partial images. Value
86+
must be between 0 and 3. When set to 0, the response will be a single image sent
87+
in one streaming event.
88+
"""
89+
7590
quality: Optional[Literal["standard", "low", "medium", "high", "auto"]]
7691
"""The quality of the image that will be generated.
7792
@@ -101,3 +116,26 @@ class ImageEditParams(TypedDict, total=False):
101116
and detect abuse.
102117
[Learn more](https://platform.openai.com/docs/guides/safety-best-practices#end-user-ids).
103118
"""
119+
120+
121+
class ImageEditParamsNonStreaming(ImageEditParamsBase, total=False):
122+
stream: Optional[Literal[False]]
123+
"""Edit the image in streaming mode.
124+
125+
Defaults to `false`. See the
126+
[Image generation guide](https://platform.openai.com/docs/guides/image-generation)
127+
for more information.
128+
"""
129+
130+
131+
class ImageEditParamsStreaming(ImageEditParamsBase):
132+
stream: Required[Literal[True]]
133+
"""Edit the image in streaming mode.
134+
135+
Defaults to `false`. See the
136+
[Image generation guide](https://platform.openai.com/docs/guides/image-generation)
137+
for more information.
138+
"""
139+
140+
141+
ImageEditParams = Union[ImageEditParamsNonStreaming, ImageEditParamsStreaming]
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from typing_extensions import Literal
4+
5+
from .._models import BaseModel
6+
7+
__all__ = ["ImageEditPartialImageEvent"]
8+
9+
10+
class ImageEditPartialImageEvent(BaseModel):
11+
b64_json: str
12+
"""Base64-encoded partial image data, suitable for rendering as an image."""
13+
14+
background: Literal["transparent", "opaque", "auto"]
15+
"""The background setting for the requested edited image."""
16+
17+
created_at: int
18+
"""The Unix timestamp when the event was created."""
19+
20+
output_format: Literal["png", "webp", "jpeg"]
21+
"""The output format for the requested edited image."""
22+
23+
partial_image_index: int
24+
"""0-based index for the partial image (streaming)."""
25+
26+
quality: Literal["low", "medium", "high", "auto"]
27+
"""The quality setting for the requested edited image."""
28+
29+
size: Literal["1024x1024", "1024x1536", "1536x1024", "auto"]
30+
"""The size of the requested edited image."""
31+
32+
type: Literal["image_edit.partial_image"]
33+
"""The type of the event. Always `image_edit.partial_image`."""
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from typing import Union
4+
from typing_extensions import Annotated, TypeAlias
5+
6+
from .._utils import PropertyInfo
7+
from .image_edit_completed_event import ImageEditCompletedEvent
8+
from .image_edit_partial_image_event import ImageEditPartialImageEvent
9+
10+
__all__ = ["ImageEditStreamEvent"]
11+
12+
ImageEditStreamEvent: TypeAlias = Annotated[
13+
Union[ImageEditPartialImageEvent, ImageEditCompletedEvent], PropertyInfo(discriminator="type")
14+
]

0 commit comments

Comments
 (0)