跳转到内容

文件与集合

公共 URL

通过 Files API 上传的每个文件默认都存储在私有存储中 — 获取文件需要您的 API 密钥。公共 URL 将存储的文件转换为 xAI CDN 上的永久、可共享链接,任何人都可以打开 — 无需 API 密钥。

创建后,您仍可完全控制:

  • 随时撤销:通过一次 API 调用立即使 URL 失效。
  • 自动过期:通过设置 expires_after(1 小时至 30 天)或让 URL 继承文件自身的过期时间,使两者同时消失。

创建公共 URL 不会修改底层的私有文件,撤销它也不会删除文件 — 两者生命周期独立。

如果您需要访问控制(例如仅限登录用户),请保持文件私有,并通过您自己的后端使用经过身份验证的 GET /v1/files/{file_id}/content 端点来提供服务。

TIP

使用 Imagine API 生成图像或视频?您 可以通过 storage_options.public_url生成资源的同一请求中创建公共 URL。参见 Imagine → Files API 集成

快速开始

python
import os
from xai_sdk import Client

client = Client(api_key=os.getenv("XAI_API_KEY"))

# 1. Upload (or reference an existing) file
file = client.files.upload("/path/to/diagram.png")

# 2. Create the public URL
resp = client.files.create_public_url(file.id)

print(resp.public_url)
# https://files-cdn.x.ai/<token>/file_abc123.png

# 3. When you're done sharing, revoke it
client.files.revoke_public_url(file.id)
bash
# 1. Upload (or reference an existing) file
FILE_ID=$(curl -s https://api.x.ai/v1/files \\
  -H "Authorization: Bearer $XAI_API_KEY" \\
  -F purpose=assistants \\
  -F file=@/path/to/diagram.png | jq -r '.id')

# 2. Create the public URL (empty JSON body uses defaults)
curl -s -X POST "https://api.x.ai/v1/files/$FILE_ID/public-url" \\
  -H "Authorization: Bearer $XAI_API_KEY" \\
  -H "Content-Type: application/json" \\
  -d '{}'
# {"public_url":"https://files-cdn.x.ai/<token>/file_abc123.png"}

# 3. When you're done sharing, revoke
curl -s -X POST "https://api.x.ai/v1/files/$FILE_ID/public-url/revoke" \\
  -H "Authorization: Bearer $XAI_API_KEY"

WARNING

公共 URL 只能为已存在于您的 Files API 存储中的文件创建。您 无法在上传过程中创建公共 URL — 请先上传文件,然后调用 create_public_url (或在 Imagine 请求中使用 storage_options.public_url)。

过期行为

您可以在创建时通过 expires_after(以秒为单位)选择性地设置公共 URL 的过期时间。一旦截止时间过去,URL 将自动撤销 — 后续请求将返回 404,您无需进行后续的 API 调用来清理。底层文件不受影响,仍可通过经过身份验证的 Files API 访问。

URL 的实际过期时间来自两个输入:您在创建时是否传递了 expires_after,以及底层文件是否有自己的过期时间

  • 文件无过期时间,未设置 expires_after — URL 永不过期。它将一直存在,直到您明确调用 revoke_public_url 或删除底层文件。
  • 文件无过期时间,expires_after 设置为 N — URL 将在 N 秒后自动撤销。文件本身不受影响。
  • 文件在时间 T 有自己的过期时间,未设置 expires_after — URL 继承文件的过期时间。两者在 T 时同时消失。
  • 文件在时间 T 有自己的过期时间,expires_after 设置为 N — URL 将在 N 秒后自动撤销。N 必须 ≤ 文件的剩余生命周期,否则请求将被拒绝。

expires_after 必须在 3600 秒(1 小时)2592000 秒(30 天) 之间。公共 URL 的寿命不可能超过其文件 — 请求的 expires_after 大于文件的剩余生命周期将被拒绝。

python
import os
from datetime import timedelta
from xai_sdk import Client

client = Client(api_key=os.getenv("XAI_API_KEY"))
file = client.files.upload("/path/to/photo.png")

# 1. Indefinite: omit expires_after on a file with no expiry.
# Must call revoke_public_url to explicitly revoke the public URL.
resp = client.files.create_public_url(file.id)
assert not resp.HasField("expires_at")

# 2. URL-bound: pass expires_after as int seconds or a timedelta
resp = client.files.create_public_url(file.id, expires_after=timedelta(hours=24))
print(f"Expires at: {resp.expires_at.seconds}")

# 3. Inherited: file has its own expiration, omit expires_after on the URL
ttl_file = client.files.upload(
    b"\\x89PNG\\r\\n\\x1a\\n" + b"\\x00" * 32,
    filename="short-lived.png",
    expires_after=timedelta(hours=2),
)
resp = client.files.create_public_url(ttl_file.id)
# resp.expires_at matches the file's expires_at
bash
# 1. Indefinite — file has no expiry.
# Must call POST /public-url/revoke to explicitly revoke.
curl -s -X POST "https://api.x.ai/v1/files/$FILE_ID/public-url" \\
  -H "Authorization: Bearer $XAI_API_KEY" \\
  -H "Content-Type: application/json" -d '{}'
# {"public_url":"..."} <- no expires_at field

# 2. URL-bound (24h)
curl -s -X POST "https://api.x.ai/v1/files/$FILE_ID/public-url" \\
  -H "Authorization: Bearer $XAI_API_KEY" \\
  -H "Content-Type: application/json" \\
  -d '{"expires_after": 86400}'
# {"public_url":"...","expires_at":1755600000}

# 3. Inherited: upload with file expiration, then create with no expires_after
FILE_ID=$(curl -s https://api.x.ai/v1/files \\
  -H "Authorization: Bearer $XAI_API_KEY" \\
  -F expires_after=7200 \\
  -F purpose=assistants \\
  -F file=@/path/to/photo.png | jq -r '.id')

curl -s -X POST "https://api.x.ai/v1/files/$FILE_ID/public-url" \\
  -H "Authorization: Bearer $XAI_API_KEY" \\
  -H "Content-Type: application/json" -d '{}'
# {"public_url":"...","expires_at":<matches file expiry>}

幂等性

一个文件一次最多只能有一个活动的公共 URL。对已有公共 URL 的文件调用 create_public_url 会返回现有 URL 而不创建新的 — 可以安全地重复调用。

如果在后续调用中传递不同的 expires_after,现有 URL 的过期时间将就地更新。URL 中的令牌保持不变。

python
import os
from xai_sdk import Client

client = Client(api_key=os.getenv("XAI_API_KEY"))
file_id = "file_abc123"

# First call creates the URL
resp1 = client.files.create_public_url(file_id, expires_after=86400)  # 1 day

# Second call returns the same URL, no re-upload
resp2 = client.files.create_public_url(file_id, expires_after=86400)
assert resp1.public_url == resp2.public_url

# Calling again with a different expires_after extends/shortens the expiry
# while keeping the same URL
resp3 = client.files.create_public_url(file_id, expires_after=604800)  # 7 days
assert resp1.public_url == resp3.public_url
assert resp3.expires_at.seconds > resp1.expires_at.seconds

撤销公共 URL

撤销会使 URL 无效并从文件的元数据中清除。原始文件不受影响,继续通过经过身份验证的端点可访问。

python
import os
from xai_sdk import Client

client = Client(api_key=os.getenv("XAI_API_KEY"))

# Revoke a public URL
resp = client.files.revoke_public_url("file_abc123")
print(f"Revoked: {resp.revoked}")    # True
print(f"Was URL: {resp.public_url}") # the URL that just stopped working

# The file itself is still available via authenticated endpoints
file = client.files.get("file_abc123")
print(file.filename)

# Revoke is idempotent and safe to call on:
# - files that never had a public URL (returns revoked=False)
# - files whose URL was already revoked (returns revoked=False)
# - files that have been deleted
client.files.revoke_public_url("file_abc123")  # no-op, no error
bash
curl -s -X POST "https://api.x.ai/v1/files/file_abc123/public-url/revoke" \\
  -H "Authorization: Bearer $XAI_API_KEY"
# {"id":"file_abc123","revoked":true,"public_url":"https://files-cdn.x.ai/..."}

# Calling again is safe — returns revoked=false
curl -s -X POST "https://api.x.ai/v1/files/file_abc123/public-url/revoke" \\
  -H "Authorization: Bearer $XAI_API_KEY"
# {"id":"file_abc123","revoked":false}

撤销是全部或无的。 一个文件一次只能有一个公共 URL,因此撤销会使所有拥有该链接的人都无法访问。如果链接泄露给不当方,唯一的补救措施是撤销并创建新 URL — 新 URL 将有新的令牌,而旧 URL 将永久失效。

查找具有公共 URL 的文件

get_filelist_files 总是返回文件的当前公共 URL 状态。对于每个具有活动公共 URL 的文件,public_urlpublic_url_expires_at 字段都会被填充。

您还可以在 list_files 上使用 filter 参数来查找有或没有活动公共 URL 的文件:

python
import os
from xai_sdk import Client

client = Client(api_key=os.getenv("XAI_API_KEY"))

# All files that currently have a public URL
with_url = client.files.list(filter="public_url != null")
for f in with_url.data:
    print(f.id, f.filename)

# All files that do not currently have a public URL
without_url = client.files.list(filter="public_url = null")
bash
# URL-encode the filter
curl -s "https://api.x.ai/v1/files?filter=public_url%20!%3D%20null" \\
  -H "Authorization: Bearer $XAI_API_KEY"

限制

  • 最大文件大小:50 MiB。 更大的文件仍可通过经过身份验证的 Files API 访问,但不能公开。
  • 受限制的内容类型。 只有以下类型符合条件:
    • image/png (.png)
    • image/jpeg (.jpg)
    • video/mp4 (.mp4)
    • application/pdf (.pdf)
  • 过期时间必须在 1 小时至 30 天之间,且公共 URL 的寿命不能超过其文件。
  • 删除文件会自动撤销公共 URL。 文件删除后(手动或通过过期),您无法保持公共 URL 有效。
  • 每个文件一次只能有一个公共 URL。 create_public_url 是幂等的,重复调用返回相同的 URL。撤销后,下一次 create_public_url 会发布新令牌 — 任何先前共享的 URL 将永久无效。
  • 每个团队最多 1,000 个活动公共 URL。 在创建新 URL 之前,请撤销不再需要的 URL。

相关

本文档为 docs.x.ai 全站中文翻译,由 AI 自动翻译生成。代码示例请以原文为准。