Skip to content

Commit 8ee185f

Browse files
njbrakeclaude
andcommitted
feat: return the typed ImagesResponse from image_generation
Now that the regenerated core types the /v1/images/generations response (gateway enrich_spec injects any-llm's ImagesResponse), return the typed model from both OtariClient.image_generation and AsyncOtariClient.image_generation instead of an untyped dict, matching embedding / rerank / moderation. Updates tests and the README example to use attribute access. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 6201018 commit 8ee185f

5 files changed

Lines changed: 18 additions & 16 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,10 +238,10 @@ result = client.image_generation(
238238
prompt="A watercolor fox in a misty forest",
239239
)
240240

241-
print(result["data"][0]["url"])
241+
print(result.data[0].url)
242242
```
243243

244-
The gateway returns the OpenAI-compatible image payload as a dict.
244+
The gateway returns a typed OpenAI-compatible `ImagesResponse`.
245245

246246
### Audio
247247

src/otari/async_client.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
from otari._client.models.chat_completion_chunk import ChatCompletionChunk
6363
from otari._client.models.count_tokens_response import CountTokensResponse
6464
from otari._client.models.create_embedding_response import CreateEmbeddingResponse
65+
from otari._client.models.images_response import ImagesResponse
6566
from otari._client.models.model_object import ModelObject
6667
from otari._client.models.moderation_response import ModerationResponse
6768
from otari._client.models.rerank_response import RerankResponse
@@ -313,12 +314,11 @@ async def image_generation(
313314
model: str,
314315
prompt: str,
315316
**kwargs: Any,
316-
) -> dict[str, Any]:
317+
) -> ImagesResponse:
317318
"""Generate images from a text prompt.
318319
319-
Returns the gateway's OpenAI-compatible image payload as a dict
320-
(``{"created": ..., "data": [...]}``). The generated core models this
321-
response as an opaque object, so the parsed JSON is returned unchanged.
320+
Returns the gateway's OpenAI-compatible
321+
:class:`~otari._client.models.images_response.ImagesResponse`.
322322
323323
Args:
324324
model: Model identifier (e.g. ``"openai:dall-e-3"``).
@@ -332,7 +332,7 @@ async def image_generation(
332332
result = await self._call(
333333
lambda: self._images.create_image_v1_images_generations_post(request)
334334
)
335-
return cast("dict[str, Any]", result)
335+
return cast("ImagesResponse", result)
336336

337337
# -- Audio --------------------------------------------------------------
338338

src/otari/client.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
from otari._client.models.chat_completion_chunk import ChatCompletionChunk
6363
from otari._client.models.count_tokens_response import CountTokensResponse
6464
from otari._client.models.create_embedding_response import CreateEmbeddingResponse
65+
from otari._client.models.images_response import ImagesResponse
6566
from otari._client.models.model_object import ModelObject
6667
from otari._client.models.moderation_response import ModerationResponse
6768
from otari._client.models.rerank_response import RerankResponse
@@ -339,12 +340,11 @@ def image_generation(
339340
model: str,
340341
prompt: str,
341342
**kwargs: Any,
342-
) -> dict[str, Any]:
343+
) -> ImagesResponse:
343344
"""Generate images from a text prompt.
344345
345-
Returns the gateway's OpenAI-compatible image payload as a dict
346-
(``{"created": ..., "data": [...]}``). The generated core models this
347-
response as an opaque object, so the parsed JSON is returned unchanged.
346+
Returns the gateway's OpenAI-compatible
347+
:class:`~otari._client.models.images_response.ImagesResponse`.
348348
349349
Args:
350350
model: Model identifier (e.g. ``"openai:dall-e-3"``).
@@ -356,7 +356,7 @@ def image_generation(
356356
ImageGenerationRequest, {"model": model, "prompt": prompt, **kwargs}
357357
)
358358
result = self._call(lambda: self._images.create_image_v1_images_generations_post(request))
359-
return cast("dict[str, Any]", result)
359+
return cast("ImagesResponse", result)
360360

361361
# -- Audio --------------------------------------------------------------
362362

tests/unit/test_async_client.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,12 @@ async def test_streaming_error_maps(self) -> None:
171171

172172

173173
class TestImages:
174-
async def test_image_generation_returns_dict(self, mock_rest: Any) -> None:
174+
async def test_image_generation_returns_typed(self, mock_rest: Any) -> None:
175175
mock = mock_rest(status=200, body=IMAGE_RESPONSE)
176176
client = AsyncOtariClient(api_base="http://localhost:8000", api_key="vk")
177177
result = await client.image_generation(model="openai:dall-e-3", prompt="a cat")
178-
assert result == IMAGE_RESPONSE
178+
assert result.created == 1
179+
assert result.data[0].url == "https://example.com/image.png"
179180
assert mock.last.url.endswith("/v1/images/generations")
180181

181182

tests/unit/test_client.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,11 +385,12 @@ def test_platform_mode_streaming_sends_bearer(self) -> None:
385385

386386

387387
class TestImages:
388-
def test_image_generation_returns_dict(self, mock_rest: Any) -> None:
388+
def test_image_generation_returns_typed(self, mock_rest: Any) -> None:
389389
mock = mock_rest(status=200, body=IMAGE_RESPONSE)
390390
client = OtariClient(api_base="http://localhost:8000", api_key="vk")
391391
result = client.image_generation(model="openai:dall-e-3", prompt="a cat")
392-
assert result == IMAGE_RESPONSE
392+
assert result.created == 1
393+
assert result.data[0].url == "https://example.com/image.png"
393394
assert mock.last.url.endswith("/v1/images/generations")
394395
body = mock.last.json_body
395396
assert body["model"] == "openai:dall-e-3"

0 commit comments

Comments
 (0)