From fb8adf70ed4c1635a14cac04affaf9d9e7bafbbd Mon Sep 17 00:00:00 2001 From: shawnthapa Date: Mon, 9 Feb 2026 17:33:42 -0800 Subject: [PATCH] Deprecate `BaseImageResponse.prompt` after `up_sampled_prompt` proto removal --- src/xai_sdk/image.py | 15 +++++++++++-- src/xai_sdk/proto/v5/image_pb2.py | 34 +++++++++++++++--------------- src/xai_sdk/proto/v5/image_pb2.pyi | 6 ++---- src/xai_sdk/proto/v6/image_pb2.py | 34 +++++++++++++++--------------- src/xai_sdk/proto/v6/image_pb2.pyi | 6 ++---- tests/aio/image_test.py | 17 +++++++++------ tests/server.py | 5 +---- tests/sync/image_test.py | 17 +++++++++------ 8 files changed, 72 insertions(+), 62 deletions(-) diff --git a/src/xai_sdk/image.py b/src/xai_sdk/image.py index 0396bab..ce10a33 100644 --- a/src/xai_sdk/image.py +++ b/src/xai_sdk/image.py @@ -1,4 +1,5 @@ import base64 +import warnings from typing import Any, Sequence, Union import grpc @@ -66,8 +67,18 @@ def prompt(self) -> str: This is different from the prompt used in the request because prompts get rewritten by the system. + + .. deprecated:: + This field is no longer populated by the server and always returns an empty string. + It will be removed in a future release. """ - return self._image.up_sampled_prompt + warnings.warn( + "BaseImageResponse.prompt is deprecated and will be removed in a future release. " + "The field is no longer populated by the server.", + DeprecationWarning, + stacklevel=2, + ) + return "" @property def respect_moderation(self) -> bool: @@ -159,7 +170,7 @@ def _make_span_response_attributes( image_pb2.ImageFormat.Name(request.format).removeprefix("IMG_FORMAT_").lower() ) for index, response in enumerate(responses): - attributes[f"gen_ai.response.{index}.image.up_sampled_prompt"] = response.prompt + attributes[f"gen_ai.response.{index}.image.up_sampled_prompt"] = "" attributes[f"gen_ai.response.{index}.image.respect_moderation"] = response.respect_moderation if request.format == image_pb2.ImageFormat.IMG_FORMAT_URL: if response._image.url: diff --git a/src/xai_sdk/proto/v5/image_pb2.py b/src/xai_sdk/proto/v5/image_pb2.py index b89b90e..eb5714f 100644 --- a/src/xai_sdk/proto/v5/image_pb2.py +++ b/src/xai_sdk/proto/v5/image_pb2.py @@ -25,7 +25,7 @@ from . import usage_pb2 as xai_dot_api_dot_v1_dot_usage__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16xai/api/v1/image.proto\x12\x07xai_api\x1a\x16xai/api/v1/usage.proto\"\xf7\x02\n\x14GenerateImageRequest\x12\x16\n\x06prompt\x18\x01 \x01(\tR\x06prompt\x12.\n\x05image\x18\x05 \x01(\x0b\x32\x18.xai_api.ImageUrlContentR\x05image\x12\x14\n\x05model\x18\x02 \x01(\tR\x05model\x12\x11\n\x01n\x18\x03 \x01(\x05H\x00R\x01n\x88\x01\x01\x12\x12\n\x04user\x18\x04 \x01(\tR\x04user\x12,\n\x06\x66ormat\x18\x0b \x01(\x0e\x32\x14.xai_api.ImageFormatR\x06\x66ormat\x12\x41\n\x0c\x61spect_ratio\x18\x0e \x01(\x0e\x32\x19.xai_api.ImageAspectRatioH\x01R\x0b\x61spectRatio\x88\x01\x01\x12=\n\nresolution\x18\x0f \x01(\x0e\x32\x18.xai_api.ImageResolutionH\x02R\nresolution\x88\x01\x01\x42\x04\n\x02_nB\x0f\n\r_aspect_ratioB\r\n\x0b_resolutionJ\x04\x08\r\x10\x0e\"\x84\x01\n\rImageResponse\x12/\n\x06images\x18\x01 \x03(\x0b\x32\x17.xai_api.GeneratedImageR\x06images\x12\x14\n\x05model\x18\x02 \x01(\tR\x05model\x12,\n\x05usage\x18\x03 \x01(\x0b\x32\x16.xai_api.SamplingUsageR\x05usage\"\xa2\x01\n\x0eGeneratedImage\x12\x18\n\x06\x62\x61se64\x18\x01 \x01(\tH\x00R\x06\x62\x61se64\x12\x12\n\x03url\x18\x03 \x01(\tH\x00R\x03url\x12*\n\x11up_sampled_prompt\x18\x02 \x01(\tR\x0fupSampledPrompt\x12-\n\x12respect_moderation\x18\x04 \x01(\x08R\x11respectModerationB\x07\n\x05image\"\\\n\x0fImageUrlContent\x12\x1b\n\timage_url\x18\x01 \x01(\tR\x08imageUrl\x12,\n\x06\x64\x65tail\x18\x02 \x01(\x0e\x32\x14.xai_api.ImageDetailR\x06\x64\x65tail*S\n\x0bImageDetail\x12\x12\n\x0e\x44\x45TAIL_INVALID\x10\x00\x12\x0f\n\x0b\x44\x45TAIL_AUTO\x10\x01\x12\x0e\n\nDETAIL_LOW\x10\x02\x12\x0f\n\x0b\x44\x45TAIL_HIGH\x10\x03*P\n\x0bImageFormat\x12\x16\n\x12IMG_FORMAT_INVALID\x10\x00\x12\x15\n\x11IMG_FORMAT_BASE64\x10\x01\x12\x12\n\x0eIMG_FORMAT_URL\x10\x02*j\n\x0cImageQuality\x12\x17\n\x13IMG_QUALITY_INVALID\x10\x00\x12\x13\n\x0fIMG_QUALITY_LOW\x10\x01\x12\x16\n\x12IMG_QUALITY_MEDIUM\x10\x02\x12\x14\n\x10IMG_QUALITY_HIGH\x10\x03*\xa7\x03\n\x10ImageAspectRatio\x12\x1c\n\x18IMG_ASPECT_RATIO_INVALID\x10\x00\x12\x18\n\x14IMG_ASPECT_RATIO_1_1\x10\x01\x12\x18\n\x14IMG_ASPECT_RATIO_3_4\x10\x02\x12\x18\n\x14IMG_ASPECT_RATIO_4_3\x10\x03\x12\x19\n\x15IMG_ASPECT_RATIO_9_16\x10\x04\x12\x19\n\x15IMG_ASPECT_RATIO_16_9\x10\x05\x12\x18\n\x14IMG_ASPECT_RATIO_2_3\x10\x06\x12\x18\n\x14IMG_ASPECT_RATIO_3_2\x10\x07\x12\x19\n\x15IMG_ASPECT_RATIO_AUTO\x10\x08\x12\x1b\n\x17IMG_ASPECT_RATIO_9_19_5\x10\t\x12\x1b\n\x17IMG_ASPECT_RATIO_19_5_9\x10\n\x12\x19\n\x15IMG_ASPECT_RATIO_9_20\x10\x0b\x12\x19\n\x15IMG_ASPECT_RATIO_20_9\x10\x0c\x12\x18\n\x14IMG_ASPECT_RATIO_1_2\x10\r\x12\x18\n\x14IMG_ASPECT_RATIO_2_1\x10\x0e*D\n\x0fImageResolution\x12\x1a\n\x16IMG_RESOLUTION_INVALID\x10\x00\x12\x15\n\x11IMG_RESOLUTION_1K\x10\x01\x32Q\n\x05Image\x12H\n\rGenerateImage\x12\x1d.xai_api.GenerateImageRequest\x1a\x16.xai_api.ImageResponse\"\x00\x42Q\n\x0b\x63om.xai_apiB\nImageProtoP\x01\xa2\x02\x03XXX\xaa\x02\x06XaiApi\xca\x02\x06XaiApi\xe2\x02\x12XaiApi\\GPBMetadata\xea\x02\x06XaiApib\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16xai/api/v1/image.proto\x12\x07xai_api\x1a\x16xai/api/v1/usage.proto\"\xf7\x02\n\x14GenerateImageRequest\x12\x16\n\x06prompt\x18\x01 \x01(\tR\x06prompt\x12.\n\x05image\x18\x05 \x01(\x0b\x32\x18.xai_api.ImageUrlContentR\x05image\x12\x14\n\x05model\x18\x02 \x01(\tR\x05model\x12\x11\n\x01n\x18\x03 \x01(\x05H\x00R\x01n\x88\x01\x01\x12\x12\n\x04user\x18\x04 \x01(\tR\x04user\x12,\n\x06\x66ormat\x18\x0b \x01(\x0e\x32\x14.xai_api.ImageFormatR\x06\x66ormat\x12\x41\n\x0c\x61spect_ratio\x18\x0e \x01(\x0e\x32\x19.xai_api.ImageAspectRatioH\x01R\x0b\x61spectRatio\x88\x01\x01\x12=\n\nresolution\x18\x0f \x01(\x0e\x32\x18.xai_api.ImageResolutionH\x02R\nresolution\x88\x01\x01\x42\x04\n\x02_nB\x0f\n\r_aspect_ratioB\r\n\x0b_resolutionJ\x04\x08\r\x10\x0e\"\x84\x01\n\rImageResponse\x12/\n\x06images\x18\x01 \x03(\x0b\x32\x17.xai_api.GeneratedImageR\x06images\x12\x14\n\x05model\x18\x02 \x01(\tR\x05model\x12,\n\x05usage\x18\x03 \x01(\x0b\x32\x16.xai_api.SamplingUsageR\x05usage\"|\n\x0eGeneratedImage\x12\x18\n\x06\x62\x61se64\x18\x01 \x01(\tH\x00R\x06\x62\x61se64\x12\x12\n\x03url\x18\x03 \x01(\tH\x00R\x03url\x12-\n\x12respect_moderation\x18\x04 \x01(\x08R\x11respectModerationB\x07\n\x05imageJ\x04\x08\x02\x10\x03\"\\\n\x0fImageUrlContent\x12\x1b\n\timage_url\x18\x01 \x01(\tR\x08imageUrl\x12,\n\x06\x64\x65tail\x18\x02 \x01(\x0e\x32\x14.xai_api.ImageDetailR\x06\x64\x65tail*S\n\x0bImageDetail\x12\x12\n\x0e\x44\x45TAIL_INVALID\x10\x00\x12\x0f\n\x0b\x44\x45TAIL_AUTO\x10\x01\x12\x0e\n\nDETAIL_LOW\x10\x02\x12\x0f\n\x0b\x44\x45TAIL_HIGH\x10\x03*P\n\x0bImageFormat\x12\x16\n\x12IMG_FORMAT_INVALID\x10\x00\x12\x15\n\x11IMG_FORMAT_BASE64\x10\x01\x12\x12\n\x0eIMG_FORMAT_URL\x10\x02*j\n\x0cImageQuality\x12\x17\n\x13IMG_QUALITY_INVALID\x10\x00\x12\x13\n\x0fIMG_QUALITY_LOW\x10\x01\x12\x16\n\x12IMG_QUALITY_MEDIUM\x10\x02\x12\x14\n\x10IMG_QUALITY_HIGH\x10\x03*\xa7\x03\n\x10ImageAspectRatio\x12\x1c\n\x18IMG_ASPECT_RATIO_INVALID\x10\x00\x12\x18\n\x14IMG_ASPECT_RATIO_1_1\x10\x01\x12\x18\n\x14IMG_ASPECT_RATIO_3_4\x10\x02\x12\x18\n\x14IMG_ASPECT_RATIO_4_3\x10\x03\x12\x19\n\x15IMG_ASPECT_RATIO_9_16\x10\x04\x12\x19\n\x15IMG_ASPECT_RATIO_16_9\x10\x05\x12\x18\n\x14IMG_ASPECT_RATIO_2_3\x10\x06\x12\x18\n\x14IMG_ASPECT_RATIO_3_2\x10\x07\x12\x19\n\x15IMG_ASPECT_RATIO_AUTO\x10\x08\x12\x1b\n\x17IMG_ASPECT_RATIO_9_19_5\x10\t\x12\x1b\n\x17IMG_ASPECT_RATIO_19_5_9\x10\n\x12\x19\n\x15IMG_ASPECT_RATIO_9_20\x10\x0b\x12\x19\n\x15IMG_ASPECT_RATIO_20_9\x10\x0c\x12\x18\n\x14IMG_ASPECT_RATIO_1_2\x10\r\x12\x18\n\x14IMG_ASPECT_RATIO_2_1\x10\x0e*D\n\x0fImageResolution\x12\x1a\n\x16IMG_RESOLUTION_INVALID\x10\x00\x12\x15\n\x11IMG_RESOLUTION_1K\x10\x01\x32Q\n\x05Image\x12H\n\rGenerateImage\x12\x1d.xai_api.GenerateImageRequest\x1a\x16.xai_api.ImageResponse\"\x00\x42Q\n\x0b\x63om.xai_apiB\nImageProtoP\x01\xa2\x02\x03XXX\xaa\x02\x06XaiApi\xca\x02\x06XaiApi\xe2\x02\x12XaiApi\\GPBMetadata\xea\x02\x06XaiApib\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -33,24 +33,24 @@ if not _descriptor._USE_C_DESCRIPTORS: _globals['DESCRIPTOR']._loaded_options = None _globals['DESCRIPTOR']._serialized_options = b'\n\013com.xai_apiB\nImageProtoP\001\242\002\003XXX\252\002\006XaiApi\312\002\006XaiApi\342\002\022XaiApi\\GPBMetadata\352\002\006XaiApi' - _globals['_IMAGEDETAIL']._serialized_start=831 - _globals['_IMAGEDETAIL']._serialized_end=914 - _globals['_IMAGEFORMAT']._serialized_start=916 - _globals['_IMAGEFORMAT']._serialized_end=996 - _globals['_IMAGEQUALITY']._serialized_start=998 - _globals['_IMAGEQUALITY']._serialized_end=1104 - _globals['_IMAGEASPECTRATIO']._serialized_start=1107 - _globals['_IMAGEASPECTRATIO']._serialized_end=1530 - _globals['_IMAGERESOLUTION']._serialized_start=1532 - _globals['_IMAGERESOLUTION']._serialized_end=1600 + _globals['_IMAGEDETAIL']._serialized_start=792 + _globals['_IMAGEDETAIL']._serialized_end=875 + _globals['_IMAGEFORMAT']._serialized_start=877 + _globals['_IMAGEFORMAT']._serialized_end=957 + _globals['_IMAGEQUALITY']._serialized_start=959 + _globals['_IMAGEQUALITY']._serialized_end=1065 + _globals['_IMAGEASPECTRATIO']._serialized_start=1068 + _globals['_IMAGEASPECTRATIO']._serialized_end=1491 + _globals['_IMAGERESOLUTION']._serialized_start=1493 + _globals['_IMAGERESOLUTION']._serialized_end=1561 _globals['_GENERATEIMAGEREQUEST']._serialized_start=60 _globals['_GENERATEIMAGEREQUEST']._serialized_end=435 _globals['_IMAGERESPONSE']._serialized_start=438 _globals['_IMAGERESPONSE']._serialized_end=570 - _globals['_GENERATEDIMAGE']._serialized_start=573 - _globals['_GENERATEDIMAGE']._serialized_end=735 - _globals['_IMAGEURLCONTENT']._serialized_start=737 - _globals['_IMAGEURLCONTENT']._serialized_end=829 - _globals['_IMAGE']._serialized_start=1602 - _globals['_IMAGE']._serialized_end=1683 + _globals['_GENERATEDIMAGE']._serialized_start=572 + _globals['_GENERATEDIMAGE']._serialized_end=696 + _globals['_IMAGEURLCONTENT']._serialized_start=698 + _globals['_IMAGEURLCONTENT']._serialized_end=790 + _globals['_IMAGE']._serialized_start=1563 + _globals['_IMAGE']._serialized_end=1644 # @@protoc_insertion_point(module_scope) diff --git a/src/xai_sdk/proto/v5/image_pb2.pyi b/src/xai_sdk/proto/v5/image_pb2.pyi index 3c9a97c..94d100f 100644 --- a/src/xai_sdk/proto/v5/image_pb2.pyi +++ b/src/xai_sdk/proto/v5/image_pb2.pyi @@ -109,16 +109,14 @@ class ImageResponse(_message.Message): def __init__(self, images: _Optional[_Iterable[_Union[GeneratedImage, _Mapping]]] = ..., model: _Optional[str] = ..., usage: _Optional[_Union[_usage_pb2.SamplingUsage, _Mapping]] = ...) -> None: ... class GeneratedImage(_message.Message): - __slots__ = ("base64", "url", "up_sampled_prompt", "respect_moderation") + __slots__ = ("base64", "url", "respect_moderation") BASE64_FIELD_NUMBER: _ClassVar[int] URL_FIELD_NUMBER: _ClassVar[int] - UP_SAMPLED_PROMPT_FIELD_NUMBER: _ClassVar[int] RESPECT_MODERATION_FIELD_NUMBER: _ClassVar[int] base64: str url: str - up_sampled_prompt: str respect_moderation: bool - def __init__(self, base64: _Optional[str] = ..., url: _Optional[str] = ..., up_sampled_prompt: _Optional[str] = ..., respect_moderation: bool = ...) -> None: ... + def __init__(self, base64: _Optional[str] = ..., url: _Optional[str] = ..., respect_moderation: bool = ...) -> None: ... class ImageUrlContent(_message.Message): __slots__ = ("image_url", "detail") diff --git a/src/xai_sdk/proto/v6/image_pb2.py b/src/xai_sdk/proto/v6/image_pb2.py index 5a8d14e..8c4adab 100644 --- a/src/xai_sdk/proto/v6/image_pb2.py +++ b/src/xai_sdk/proto/v6/image_pb2.py @@ -25,7 +25,7 @@ from . import usage_pb2 as xai_dot_api_dot_v1_dot_usage__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16xai/api/v1/image.proto\x12\x07xai_api\x1a\x16xai/api/v1/usage.proto\"\xf7\x02\n\x14GenerateImageRequest\x12\x16\n\x06prompt\x18\x01 \x01(\tR\x06prompt\x12.\n\x05image\x18\x05 \x01(\x0b\x32\x18.xai_api.ImageUrlContentR\x05image\x12\x14\n\x05model\x18\x02 \x01(\tR\x05model\x12\x11\n\x01n\x18\x03 \x01(\x05H\x00R\x01n\x88\x01\x01\x12\x12\n\x04user\x18\x04 \x01(\tR\x04user\x12,\n\x06\x66ormat\x18\x0b \x01(\x0e\x32\x14.xai_api.ImageFormatR\x06\x66ormat\x12\x41\n\x0c\x61spect_ratio\x18\x0e \x01(\x0e\x32\x19.xai_api.ImageAspectRatioH\x01R\x0b\x61spectRatio\x88\x01\x01\x12=\n\nresolution\x18\x0f \x01(\x0e\x32\x18.xai_api.ImageResolutionH\x02R\nresolution\x88\x01\x01\x42\x04\n\x02_nB\x0f\n\r_aspect_ratioB\r\n\x0b_resolutionJ\x04\x08\r\x10\x0e\"\x84\x01\n\rImageResponse\x12/\n\x06images\x18\x01 \x03(\x0b\x32\x17.xai_api.GeneratedImageR\x06images\x12\x14\n\x05model\x18\x02 \x01(\tR\x05model\x12,\n\x05usage\x18\x03 \x01(\x0b\x32\x16.xai_api.SamplingUsageR\x05usage\"\xa2\x01\n\x0eGeneratedImage\x12\x18\n\x06\x62\x61se64\x18\x01 \x01(\tH\x00R\x06\x62\x61se64\x12\x12\n\x03url\x18\x03 \x01(\tH\x00R\x03url\x12*\n\x11up_sampled_prompt\x18\x02 \x01(\tR\x0fupSampledPrompt\x12-\n\x12respect_moderation\x18\x04 \x01(\x08R\x11respectModerationB\x07\n\x05image\"\\\n\x0fImageUrlContent\x12\x1b\n\timage_url\x18\x01 \x01(\tR\x08imageUrl\x12,\n\x06\x64\x65tail\x18\x02 \x01(\x0e\x32\x14.xai_api.ImageDetailR\x06\x64\x65tail*S\n\x0bImageDetail\x12\x12\n\x0e\x44\x45TAIL_INVALID\x10\x00\x12\x0f\n\x0b\x44\x45TAIL_AUTO\x10\x01\x12\x0e\n\nDETAIL_LOW\x10\x02\x12\x0f\n\x0b\x44\x45TAIL_HIGH\x10\x03*P\n\x0bImageFormat\x12\x16\n\x12IMG_FORMAT_INVALID\x10\x00\x12\x15\n\x11IMG_FORMAT_BASE64\x10\x01\x12\x12\n\x0eIMG_FORMAT_URL\x10\x02*j\n\x0cImageQuality\x12\x17\n\x13IMG_QUALITY_INVALID\x10\x00\x12\x13\n\x0fIMG_QUALITY_LOW\x10\x01\x12\x16\n\x12IMG_QUALITY_MEDIUM\x10\x02\x12\x14\n\x10IMG_QUALITY_HIGH\x10\x03*\xa7\x03\n\x10ImageAspectRatio\x12\x1c\n\x18IMG_ASPECT_RATIO_INVALID\x10\x00\x12\x18\n\x14IMG_ASPECT_RATIO_1_1\x10\x01\x12\x18\n\x14IMG_ASPECT_RATIO_3_4\x10\x02\x12\x18\n\x14IMG_ASPECT_RATIO_4_3\x10\x03\x12\x19\n\x15IMG_ASPECT_RATIO_9_16\x10\x04\x12\x19\n\x15IMG_ASPECT_RATIO_16_9\x10\x05\x12\x18\n\x14IMG_ASPECT_RATIO_2_3\x10\x06\x12\x18\n\x14IMG_ASPECT_RATIO_3_2\x10\x07\x12\x19\n\x15IMG_ASPECT_RATIO_AUTO\x10\x08\x12\x1b\n\x17IMG_ASPECT_RATIO_9_19_5\x10\t\x12\x1b\n\x17IMG_ASPECT_RATIO_19_5_9\x10\n\x12\x19\n\x15IMG_ASPECT_RATIO_9_20\x10\x0b\x12\x19\n\x15IMG_ASPECT_RATIO_20_9\x10\x0c\x12\x18\n\x14IMG_ASPECT_RATIO_1_2\x10\r\x12\x18\n\x14IMG_ASPECT_RATIO_2_1\x10\x0e*D\n\x0fImageResolution\x12\x1a\n\x16IMG_RESOLUTION_INVALID\x10\x00\x12\x15\n\x11IMG_RESOLUTION_1K\x10\x01\x32Q\n\x05Image\x12H\n\rGenerateImage\x12\x1d.xai_api.GenerateImageRequest\x1a\x16.xai_api.ImageResponse\"\x00\x42Q\n\x0b\x63om.xai_apiB\nImageProtoP\x01\xa2\x02\x03XXX\xaa\x02\x06XaiApi\xca\x02\x06XaiApi\xe2\x02\x12XaiApi\\GPBMetadata\xea\x02\x06XaiApib\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16xai/api/v1/image.proto\x12\x07xai_api\x1a\x16xai/api/v1/usage.proto\"\xf7\x02\n\x14GenerateImageRequest\x12\x16\n\x06prompt\x18\x01 \x01(\tR\x06prompt\x12.\n\x05image\x18\x05 \x01(\x0b\x32\x18.xai_api.ImageUrlContentR\x05image\x12\x14\n\x05model\x18\x02 \x01(\tR\x05model\x12\x11\n\x01n\x18\x03 \x01(\x05H\x00R\x01n\x88\x01\x01\x12\x12\n\x04user\x18\x04 \x01(\tR\x04user\x12,\n\x06\x66ormat\x18\x0b \x01(\x0e\x32\x14.xai_api.ImageFormatR\x06\x66ormat\x12\x41\n\x0c\x61spect_ratio\x18\x0e \x01(\x0e\x32\x19.xai_api.ImageAspectRatioH\x01R\x0b\x61spectRatio\x88\x01\x01\x12=\n\nresolution\x18\x0f \x01(\x0e\x32\x18.xai_api.ImageResolutionH\x02R\nresolution\x88\x01\x01\x42\x04\n\x02_nB\x0f\n\r_aspect_ratioB\r\n\x0b_resolutionJ\x04\x08\r\x10\x0e\"\x84\x01\n\rImageResponse\x12/\n\x06images\x18\x01 \x03(\x0b\x32\x17.xai_api.GeneratedImageR\x06images\x12\x14\n\x05model\x18\x02 \x01(\tR\x05model\x12,\n\x05usage\x18\x03 \x01(\x0b\x32\x16.xai_api.SamplingUsageR\x05usage\"|\n\x0eGeneratedImage\x12\x18\n\x06\x62\x61se64\x18\x01 \x01(\tH\x00R\x06\x62\x61se64\x12\x12\n\x03url\x18\x03 \x01(\tH\x00R\x03url\x12-\n\x12respect_moderation\x18\x04 \x01(\x08R\x11respectModerationB\x07\n\x05imageJ\x04\x08\x02\x10\x03\"\\\n\x0fImageUrlContent\x12\x1b\n\timage_url\x18\x01 \x01(\tR\x08imageUrl\x12,\n\x06\x64\x65tail\x18\x02 \x01(\x0e\x32\x14.xai_api.ImageDetailR\x06\x64\x65tail*S\n\x0bImageDetail\x12\x12\n\x0e\x44\x45TAIL_INVALID\x10\x00\x12\x0f\n\x0b\x44\x45TAIL_AUTO\x10\x01\x12\x0e\n\nDETAIL_LOW\x10\x02\x12\x0f\n\x0b\x44\x45TAIL_HIGH\x10\x03*P\n\x0bImageFormat\x12\x16\n\x12IMG_FORMAT_INVALID\x10\x00\x12\x15\n\x11IMG_FORMAT_BASE64\x10\x01\x12\x12\n\x0eIMG_FORMAT_URL\x10\x02*j\n\x0cImageQuality\x12\x17\n\x13IMG_QUALITY_INVALID\x10\x00\x12\x13\n\x0fIMG_QUALITY_LOW\x10\x01\x12\x16\n\x12IMG_QUALITY_MEDIUM\x10\x02\x12\x14\n\x10IMG_QUALITY_HIGH\x10\x03*\xa7\x03\n\x10ImageAspectRatio\x12\x1c\n\x18IMG_ASPECT_RATIO_INVALID\x10\x00\x12\x18\n\x14IMG_ASPECT_RATIO_1_1\x10\x01\x12\x18\n\x14IMG_ASPECT_RATIO_3_4\x10\x02\x12\x18\n\x14IMG_ASPECT_RATIO_4_3\x10\x03\x12\x19\n\x15IMG_ASPECT_RATIO_9_16\x10\x04\x12\x19\n\x15IMG_ASPECT_RATIO_16_9\x10\x05\x12\x18\n\x14IMG_ASPECT_RATIO_2_3\x10\x06\x12\x18\n\x14IMG_ASPECT_RATIO_3_2\x10\x07\x12\x19\n\x15IMG_ASPECT_RATIO_AUTO\x10\x08\x12\x1b\n\x17IMG_ASPECT_RATIO_9_19_5\x10\t\x12\x1b\n\x17IMG_ASPECT_RATIO_19_5_9\x10\n\x12\x19\n\x15IMG_ASPECT_RATIO_9_20\x10\x0b\x12\x19\n\x15IMG_ASPECT_RATIO_20_9\x10\x0c\x12\x18\n\x14IMG_ASPECT_RATIO_1_2\x10\r\x12\x18\n\x14IMG_ASPECT_RATIO_2_1\x10\x0e*D\n\x0fImageResolution\x12\x1a\n\x16IMG_RESOLUTION_INVALID\x10\x00\x12\x15\n\x11IMG_RESOLUTION_1K\x10\x01\x32Q\n\x05Image\x12H\n\rGenerateImage\x12\x1d.xai_api.GenerateImageRequest\x1a\x16.xai_api.ImageResponse\"\x00\x42Q\n\x0b\x63om.xai_apiB\nImageProtoP\x01\xa2\x02\x03XXX\xaa\x02\x06XaiApi\xca\x02\x06XaiApi\xe2\x02\x12XaiApi\\GPBMetadata\xea\x02\x06XaiApib\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -33,24 +33,24 @@ if not _descriptor._USE_C_DESCRIPTORS: _globals['DESCRIPTOR']._loaded_options = None _globals['DESCRIPTOR']._serialized_options = b'\n\013com.xai_apiB\nImageProtoP\001\242\002\003XXX\252\002\006XaiApi\312\002\006XaiApi\342\002\022XaiApi\\GPBMetadata\352\002\006XaiApi' - _globals['_IMAGEDETAIL']._serialized_start=831 - _globals['_IMAGEDETAIL']._serialized_end=914 - _globals['_IMAGEFORMAT']._serialized_start=916 - _globals['_IMAGEFORMAT']._serialized_end=996 - _globals['_IMAGEQUALITY']._serialized_start=998 - _globals['_IMAGEQUALITY']._serialized_end=1104 - _globals['_IMAGEASPECTRATIO']._serialized_start=1107 - _globals['_IMAGEASPECTRATIO']._serialized_end=1530 - _globals['_IMAGERESOLUTION']._serialized_start=1532 - _globals['_IMAGERESOLUTION']._serialized_end=1600 + _globals['_IMAGEDETAIL']._serialized_start=792 + _globals['_IMAGEDETAIL']._serialized_end=875 + _globals['_IMAGEFORMAT']._serialized_start=877 + _globals['_IMAGEFORMAT']._serialized_end=957 + _globals['_IMAGEQUALITY']._serialized_start=959 + _globals['_IMAGEQUALITY']._serialized_end=1065 + _globals['_IMAGEASPECTRATIO']._serialized_start=1068 + _globals['_IMAGEASPECTRATIO']._serialized_end=1491 + _globals['_IMAGERESOLUTION']._serialized_start=1493 + _globals['_IMAGERESOLUTION']._serialized_end=1561 _globals['_GENERATEIMAGEREQUEST']._serialized_start=60 _globals['_GENERATEIMAGEREQUEST']._serialized_end=435 _globals['_IMAGERESPONSE']._serialized_start=438 _globals['_IMAGERESPONSE']._serialized_end=570 - _globals['_GENERATEDIMAGE']._serialized_start=573 - _globals['_GENERATEDIMAGE']._serialized_end=735 - _globals['_IMAGEURLCONTENT']._serialized_start=737 - _globals['_IMAGEURLCONTENT']._serialized_end=829 - _globals['_IMAGE']._serialized_start=1602 - _globals['_IMAGE']._serialized_end=1683 + _globals['_GENERATEDIMAGE']._serialized_start=572 + _globals['_GENERATEDIMAGE']._serialized_end=696 + _globals['_IMAGEURLCONTENT']._serialized_start=698 + _globals['_IMAGEURLCONTENT']._serialized_end=790 + _globals['_IMAGE']._serialized_start=1563 + _globals['_IMAGE']._serialized_end=1644 # @@protoc_insertion_point(module_scope) diff --git a/src/xai_sdk/proto/v6/image_pb2.pyi b/src/xai_sdk/proto/v6/image_pb2.pyi index 7a0fa59..4103882 100644 --- a/src/xai_sdk/proto/v6/image_pb2.pyi +++ b/src/xai_sdk/proto/v6/image_pb2.pyi @@ -110,16 +110,14 @@ class ImageResponse(_message.Message): def __init__(self, images: _Optional[_Iterable[_Union[GeneratedImage, _Mapping]]] = ..., model: _Optional[str] = ..., usage: _Optional[_Union[_usage_pb2.SamplingUsage, _Mapping]] = ...) -> None: ... class GeneratedImage(_message.Message): - __slots__ = ("base64", "url", "up_sampled_prompt", "respect_moderation") + __slots__ = ("base64", "url", "respect_moderation") BASE64_FIELD_NUMBER: _ClassVar[int] URL_FIELD_NUMBER: _ClassVar[int] - UP_SAMPLED_PROMPT_FIELD_NUMBER: _ClassVar[int] RESPECT_MODERATION_FIELD_NUMBER: _ClassVar[int] base64: str url: str - up_sampled_prompt: str respect_moderation: bool - def __init__(self, base64: _Optional[str] = ..., url: _Optional[str] = ..., up_sampled_prompt: _Optional[str] = ..., respect_moderation: bool = ...) -> None: ... + def __init__(self, base64: _Optional[str] = ..., url: _Optional[str] = ..., respect_moderation: bool = ...) -> None: ... class ImageUrlContent(_message.Message): __slots__ = ("image_url", "detail") diff --git a/tests/aio/image_test.py b/tests/aio/image_test.py index cc391d9..977f707 100644 --- a/tests/aio/image_test.py +++ b/tests/aio/image_test.py @@ -26,7 +26,8 @@ def image_asset(): async def test_base64(client: AsyncClient, image_asset: bytes): response = await client.image.sample(prompt="foo", model="grok-2-image", image_format="base64") - assert response.prompt == "foo" + with pytest.warns(DeprecationWarning, match="BaseImageResponse.prompt is deprecated"): + assert response.prompt == "" assert image_asset == await response.image @@ -34,7 +35,8 @@ async def test_base64(client: AsyncClient, image_asset: bytes): async def test_url(client: AsyncClient, image_asset: bytes): response = await client.image.sample(prompt="foo", model="grok-2-image", image_format="url") - assert response.prompt == "foo" + with pytest.warns(DeprecationWarning, match="BaseImageResponse.prompt is deprecated"): + assert response.prompt == "" assert image_asset == await response.image @@ -45,7 +47,8 @@ async def test_batch(client: AsyncClient, image_asset: bytes): assert len(responses) == 2 for r in responses: - assert r.prompt == "foo" + with pytest.warns(DeprecationWarning, match="BaseImageResponse.prompt is deprecated"): + assert r.prompt == "" assert image_asset == await r.image @@ -143,7 +146,7 @@ async def test_sample_creates_span_with_correct_attributes( "gen_ai.usage.cached_prompt_text_tokens": response.usage.cached_prompt_text_tokens, "gen_ai.usage.prompt_text_tokens": response.usage.prompt_text_tokens, "gen_ai.usage.prompt_image_tokens": response.usage.prompt_image_tokens, - "gen_ai.response.0.image.up_sampled_prompt": response.prompt, + "gen_ai.response.0.image.up_sampled_prompt": "", "gen_ai.response.0.image.respect_moderation": response.respect_moderation, } @@ -234,9 +237,9 @@ async def test_sample_batch_creates_span_with_correct_attributes( "gen_ai.usage.cached_prompt_text_tokens": responses[0].usage.cached_prompt_text_tokens, "gen_ai.usage.prompt_text_tokens": responses[0].usage.prompt_text_tokens, "gen_ai.usage.prompt_image_tokens": responses[0].usage.prompt_image_tokens, - "gen_ai.response.0.image.up_sampled_prompt": responses[0].prompt, - "gen_ai.response.1.image.up_sampled_prompt": responses[1].prompt, - "gen_ai.response.2.image.up_sampled_prompt": responses[2].prompt, + "gen_ai.response.0.image.up_sampled_prompt": "", + "gen_ai.response.1.image.up_sampled_prompt": "", + "gen_ai.response.2.image.up_sampled_prompt": "", "gen_ai.response.0.image.respect_moderation": responses[0].respect_moderation, "gen_ai.response.1.image.respect_moderation": responses[1].respect_moderation, "gen_ai.response.2.image.respect_moderation": responses[2].respect_moderation, diff --git a/tests/server.py b/tests/server.py index cbc4c6a..d8a600b 100644 --- a/tests/server.py +++ b/tests/server.py @@ -647,16 +647,13 @@ def GenerateImage(self, request: image_pb2.GenerateImageRequest, context: grpc.S if request.format == image_pb2.ImageFormat.IMG_FORMAT_URL: return image_pb2.ImageResponse( model=request.model, - images=[ - image_pb2.GeneratedImage(up_sampled_prompt=request.prompt, url=self._url) for _ in range(request.n) - ], + images=[image_pb2.GeneratedImage(url=self._url) for _ in range(request.n)], ) else: return image_pb2.ImageResponse( model=request.model, images=[ image_pb2.GeneratedImage( - up_sampled_prompt=request.prompt, base64="data:image/jpeg;base64," + base64.b64encode(read_image()).decode(), ) for _ in range(request.n) diff --git a/tests/sync/image_test.py b/tests/sync/image_test.py index 6260208..b3047ed 100644 --- a/tests/sync/image_test.py +++ b/tests/sync/image_test.py @@ -24,14 +24,16 @@ def image_asset(): def test_base64(client: Client, image_asset: bytes): response = client.image.sample(prompt="foo", model="grok-2-image", image_format="base64") - assert response.prompt == "foo" + with pytest.warns(DeprecationWarning, match="BaseImageResponse.prompt is deprecated"): + assert response.prompt == "" assert image_asset == response.image def test_url(client: Client, image_asset: bytes): response = client.image.sample(prompt="foo", model="grok-2-image", image_format="url") - assert response.prompt == "foo" + with pytest.warns(DeprecationWarning, match="BaseImageResponse.prompt is deprecated"): + assert response.prompt == "" assert image_asset == response.image @@ -41,7 +43,8 @@ def test_batch(client: Client, image_asset: bytes): assert len(responses) == 2 for r in responses: - assert r.prompt == "foo" + with pytest.warns(DeprecationWarning, match="BaseImageResponse.prompt is deprecated"): + assert r.prompt == "" assert image_asset == r.image @@ -135,7 +138,7 @@ def test_sample_creates_span_with_correct_attributes( "gen_ai.usage.cached_prompt_text_tokens": response.usage.cached_prompt_text_tokens, "gen_ai.usage.prompt_text_tokens": response.usage.prompt_text_tokens, "gen_ai.usage.prompt_image_tokens": response.usage.prompt_image_tokens, - "gen_ai.response.0.image.up_sampled_prompt": response.prompt, + "gen_ai.response.0.image.up_sampled_prompt": "", "gen_ai.response.0.image.respect_moderation": response.respect_moderation, } @@ -222,9 +225,9 @@ def test_sample_batch_creates_span_with_correct_attributes( "gen_ai.usage.cached_prompt_text_tokens": responses[0].usage.cached_prompt_text_tokens, "gen_ai.usage.prompt_text_tokens": responses[0].usage.prompt_text_tokens, "gen_ai.usage.prompt_image_tokens": responses[0].usage.prompt_image_tokens, - "gen_ai.response.0.image.up_sampled_prompt": responses[0].prompt, - "gen_ai.response.1.image.up_sampled_prompt": responses[1].prompt, - "gen_ai.response.2.image.up_sampled_prompt": responses[2].prompt, + "gen_ai.response.0.image.up_sampled_prompt": "", + "gen_ai.response.1.image.up_sampled_prompt": "", + "gen_ai.response.2.image.up_sampled_prompt": "", "gen_ai.response.0.image.respect_moderation": responses[0].respect_moderation, "gen_ai.response.1.image.respect_moderation": responses[1].respect_moderation, "gen_ai.response.2.image.respect_moderation": responses[2].respect_moderation,