模型能力
持久保存生成的输出
在任意 Imagine 请求中使用 storage_options,即可将生成的 asset 持久保存到你的 Files API 存储中,之后可通过经过身份验证的 Files API 获取。此外,设置 storage_options.public_url 还可以为该 asset 生成永久、可分享的 public URL;这是任何人都能打开的免身份验证链接,在你撤销之前会一直有效。
存储与 public URL 创建彼此独立:你可以只进行私有存储而不创建 public URL,也可以在存储时创建 public URL。无论哪种方式,response 仍会包含默认始终返回的临时 generation URL。
快速开始
生成图像、将其持久保存到 Files,并获得可分享的 public URL;所有操作都在一次调用中完成:
import os
import xai_sdk
client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))
response = client.image.sample(
prompt="A serene Japanese garden in winter",
model="grok-imagine-image-quality",
storage_options={"filename": "garden.jpg", "public_url": True},
)
# Ephemeral, short-lived URL.
print(f"Ephemeral: {response.url}")
# Persistent file in your Files API storage.
print(f"File ID: {response.file_output.file_id}")
# Permanent, shareable public URL.
print(f"Public URL: {response.public_url}")Response body 如下:
{
"data": [
{
"url": "https://imgen.x.ai/xai-imgen/xai-tmp-imgen-abc123.jpg",
"file_output": {
"file_id": "file_7de029f4-eb66-42ee-87f8-b2a9d9e7466a",
"filename": "garden.jpg",
"public_url": "https://files-cdn.x.ai/ZsqeMtdcSYWPPHTQdxXDKQ/file_7de029f4-eb66-42ee-87f8-b2a9d9e7466a.jpg"
}
}
]
}需要注意的要点:
data[i].url是临时 Imagine URL,生命周期较短,适合立即使用。无论是否指定storage_options,它都会返回。data[i].file_output.file_id是生成 asset 的稳定 Files API 标识符。data[i].file_output.public_url是永久 public URL。可用于在应用中分享、嵌入和长期存储。
storage_options 参考
| 字段 | 类型 | 说明 |
|---|---|---|
filename | string(必填) | 存储文件的 filename。public URL 路径上的扩展名来自该 filename。 |
expires_after | integer(可选) | 从当前时间到存储文件过期的秒数。必须介于 3600(1 小时)和 2592000(30 天)之间。省略该字段表示永久存储。 |
public_url | boolean 或 object(可选) | 设置为 true 可使用默认设置创建 public URL,也可以传入 object 进行配置。省略该字段(或设为 false)表示私有存储。 |
public_url.expires_after | integer(可选) | 从当前时间到 public URL 过期的秒数。必须介于 3600(1 小时)和 2592000(30 天)之间。详见 过期行为。 |
filename 为必填项。仅传入 storage_options={"filename": "..."} 而不设置其他字段,会将 asset 私有地持久保存:存储文件不会过期,也不会创建 public URL。如果之后改变主意,随时可以对已存储的 create_public_url 调用 file_id。
response = client.image.sample(
prompt="A red circle on a white background",
model="grok-imagine-image-quality",
storage_options={"filename": "circle.jpg"}, # store privately, no public URL
)
print(response.file_output.file_id) # file_...
print(response.file_output.filename) # circle.jpg
print(response.public_url) # None — public URL was not requested过期行为
storage_options 提供两个相互独立的过期控制项:storage_options.expires_after 控制存储文件何时自动删除,storage_options.public_url.expires_after 控制public URL 则控制何时自动撤销。省略 public_url.expires_after 时,URL 会继承文件的过期时间(如果文件没有过期时间,则 URL 永不过期)。
public URL 的生命周期永远不能超过其文件,并且两个值都必须介于1 小时和 30 天之间。完整规则请参阅 Public URLs → 过期行为;以下示例展示了这两个控制项如何在 Imagine 请求中组合使用。
import os
import xai_sdk
client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))
# Permanent file, public URL expires in 24h.
response = client.image.sample(
prompt="A futuristic city skyline at night",
model="grok-imagine-image-quality",
storage_options={"filename": "skyline.jpg", "public_url": {"expires_after": 86400}}, # 24h
)
print(response.file_output.file_id) # file_...
print(response.public_url) # https://files-cdn.x.ai/<token>/file_....jpg
print(response.file_output.public_url_expires_at) # protobuf Timestamp, ~24h from now
# File and public URL both expire in 2h (URL inherits the file's expiry).
response = client.image.sample(
prompt="A futuristic city skyline at night",
model="grok-imagine-image-quality",
storage_options={"filename": "skyline.jpg", "expires_after": 7200, "public_url": True},
)
print(response.file_output.file_id) # file_...
print(response.public_url)
print(response.file_output.expires_at) # ~2h from now
print(response.file_output.public_url_expires_at) # matches file's expires_at
# File expires in 24h, public URL expires in 1h (independent, shorter).
response = client.image.sample(
prompt="A futuristic city skyline at night",
model="grok-imagine-image-quality",
storage_options={
"filename": "skyline.jpg",
"expires_after": 86400,
"public_url": {"expires_after": 3600},
},
)
print(response.file_output.file_id) # file_...
print(response.public_url)
print(response.file_output.expires_at) # ~24h from now
print(response.file_output.public_url_expires_at) # ~1h from now (URL dies before file)该 file_output Response
每个设置了 storage_options 的 Imagine response 都会在每个生成的 asset 上包含一个 file_output block:
| 字段 | 始终存在 | 含义 |
|---|---|---|
file_id | 是 | 稳定的 Files API 标识符。将其用于 client.files.* 操作。 |
filename | 是 | 你在 storage_options。 |
expires_at | 仅在文件设置了过期时间时 | 文件过期时的 Unix timestamp。 |
public_url | 仅当设置了 storage_options.public_url 且创建成功时 | 永久、可分享的 URL。 |
public_url_expires_at | 仅当 public URL 设置了过期时间时 | public URL 失效时的 Unix timestamp。永久 URL 不包含该字段。 |
public_url_error | 仅在部分失败时 | asset 已存储但 public URL 创建失败时返回的可读错误。详见 Public URL 错误。 |
Python SDK 还会将 response.public_url 和 response.public_url_error 作为 ImageResponse 和 VideoResponse。
多个输出(n > 1)
在一次调用中请求多张图像时,每张图像都会获得自己的 file_id 以及具有唯一 token 的 public_url。这些文件完全独立,撤销或删除其中一个不会影响其他文件。
import os
import xai_sdk
client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))
responses = client.image.sample_batch(
prompt="A cat wearing a hat, four different art styles",
model="grok-imagine-image-quality",
n=4,
storage_options={"filename": "cat-styles.jpg", "public_url": True},
)
for r in responses:
print(r.file_output.file_id, r.public_url)存储图像编辑输出
storage_options 在 /v1/images/edits 上的工作方式与 /v1/images/generations 相同。编辑结果会存储为新文件。
import os
import xai_sdk
client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))
response = client.image.sample(
prompt="Add a party hat to the dog",
model="grok-imagine-image-quality",
image_url="https://docs.x.ai/assets/api-examples/images/style-realistic.png",
storage_options={"filename": "party-dog.png", "public_url": True},
)
print(response.file_output.file_id) # new file, not the input
print(response.public_url)存储视频输出
视频 endpoint(/v1/videos/generations、/v1/videos/edits、/v1/videos/extensions)使用相同的 storage_options 结构。由于视频生成是异步的,file_output.public_url 会填充在视频生成完成后的已完成 response 中。
import os
import xai_sdk
client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))
# SDK handles polling automatically and returns the completed video.
response = client.video.generate(
prompt="A ball bouncing slowly on a flat surface",
model="grok-imagine-video-1.5",
duration=5,
storage_options={"filename": "bouncing-ball.mp4", "public_url": True},
)
print(response.url) # ephemeral vidgen URL
print(response.file_output.file_id) # file_...
print(response.public_url) # https://files-cdn.x.ai/<token>/file_....mp4Image-to-video、视频编辑和视频扩展均以相同方式接受 storage_options。
Public URL 错误
在极少数情况下,即使 asset 生成和存储成功,public URL 创建也可能失败,例如出现暂时性基础设施问题,或 team 达到 active URL quota。此时不会让整个请求失败,response 仍会包含有效的 file_output.file_id 和原始 asset URL,仅将 public_url 替换为 public_url_error:
{
"data": [
{
"url": "https://imgen.x.ai/.../xai-tmp-imgen-abc123.jpg",
"file_output": {
"file_id": "file_abc123",
"filename": "poster.jpg",
"public_url_error": "Public URL creation timed out. The file was stored successfully."
}
}
]
}如果看到 public_url_error,文件仍在你的存储中;你可以直接通过 Files API 重试 public URL 创建,而无需重新生成 asset:
import os
import xai_sdk
client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))
response = client.image.sample(
prompt="A vintage poster",
model="grok-imagine-image-quality",
storage_options={"filename": "poster.jpg", "public_url": True},
)
if response.public_url_error:
# The image is stored — just retry the public URL on the file directly.
resp = client.files.create_public_url(response.file_output.file_id)
public_url = resp.public_url
else:
public_url = response.public_url
print(public_url)管理通过 Imagine 创建的文件
通过 storage_options 创建的文件都是完整的一等 Files API 文件。使用 Files API 列出、获取、更新和删除这些文件,并使用 public URL endpoint 撤销或重新创建 URL:
import os
import xai_sdk
client = xai_sdk.Client(api_key=os.getenv("XAI_API_KEY"))
response = client.image.sample(
prompt="A futuristic city",
model="grok-imagine-image-quality",
storage_options={"filename": "city.jpg", "public_url": True},
)
file_id = response.file_output.file_id
# Inspect file metadata
file = client.files.get(file_id)
# Stop sharing publicly (keeps the file in your storage)
client.files.revoke_public_url(file_id)
# Generate a new public URL later with a different expiry
client.files.create_public_url(file_id, expires_after=604800) # 7 days
# Delete the file entirely (also tears down any active public URL)
client.files.delete(file_id)限制
每个 team 最多可拥有 1,000 个活跃 public URL。 达到上限时,response 会设置
public_url_error;请撤销未使用的 URL 以释放名额。过期限制(参见 过期行为):
两个
expires_after值都必须介于 1 小时和 30 天。public_url.expires_after必须小于或等于文件的expires_after。
自定义 filename 会影响 public URL 路径。 传入
storage_options.filename = "my-cover.png"会使 public URL 以.png结尾。存储的 content type 仍由生成的 asset 决定,而不是由 filename 决定。response_format不影响存储。storage_options无论请求url还是b64_json。public URL 与临时 URL 相互独立。 二者在同一个 response 中返回,但具有独立生命周期。撤销 public URL 不会影响临时 URL。
所有验证都是同步的。 无效的存储配置会在生成开始前被拒绝,因此不会将计算资源浪费在格式错误的请求上。
相关内容
Files API 集成 — 概览以及组合使用输入与输出的完整示例。
将文件引用为输入 — 输入方向:传入已存储的
file_id来替代 URL。Files → Public URLs — 任意文件的 public URL 生命周期,无论文件以何种方式创建。
管理文件 — 上传、列出、获取、更新和删除文件。