S3 API
S3 兼容对象存储辅助能力位于 ptool.s3 和 p.s3 下。
ptool.s3.connect
v0.10.0- 引入。
ptool.s3.connect(options) 打开一个 S3 兼容对象存储连接,并返回一个 Connection 对象。
options 字段:
bucket(string,必填):bucket 名称。region(string,选填):AWS 区域或服务提供商区域。endpoint(string,选填):自定义的 S3 兼容 endpoint URL,例如 MinIO、R2 或其他对象存储服务。access_key_id(string,选填):访问密钥 ID。secret_access_key(string,选填):访问密钥 secret。session_token(string,选填):会话令牌。root(string,选填):应用到所有对象操作的根前缀。allow_anonymous(boolean,选填):当为true时,如果未配置凭证,则允许未签名请求。默认为false。
环境变量回退:
- 显式传入的
options值优先。 - 缺失的
region、endpoint、access_key_id、secret_access_key和session_token会回退到:AWS_REGIONAWS_ENDPOINT、AWS_ENDPOINT_URL或AWS_S3_ENDPOINTAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_SESSION_TOKEN
- 环境变量回退使用
ptool的运行时环境视图,因此通过p.os.setenv(...)设置的值也会被ptool.s3.connect(...)看到。
示例:
local s3 = ptool.s3.connect({
bucket = "artifacts",
region = "auto",
endpoint = "https://<account>.r2.cloudflarestorage.com",
access_key_id = p.os.getenv("AWS_ACCESS_KEY_ID"),
secret_access_key = p.os.getenv("AWS_SECRET_ACCESS_KEY"),
root = "builds/",
})
Connection
v0.10.0- 引入。
Connection 表示由 ptool.s3.connect() 返回的已打开对象存储连接。
它实现为 Lua userdata。
方法:
conn:read(path[, options])->stringconn:write(path, content[, options])->tableconn:delete(path)->nilconn:exists(path)->booleanconn:list([prefix])->tableconn:stat(path)->table
路径规则:
- 除非另有说明,对象路径必须是非空字符串。
- 前导
/会被忽略,因此/foo/bar.txt和foo/bar.txt指向同一个对象。 - 当连接配置了
root时,路径会相对于root解析。
条目 table 结构:
path(string):相对于连接根路径的对象路径。size(integer):对象大小,单位为字节。etag(string | nil):对象的 ETag(如果可用)。last_modified(string | nil):最后修改时间戳(如果可用)。content_type(string | nil):对象内容类型(如果可用)。version(string | nil):对象版本(如果可用)。metadata(table | nil):用户定义的对象元信息(如果可用)。is_file(boolean):该条目是否为文件。is_dir(boolean):该条目是否为目录。mode(string):"file"、"dir"或"unknown"之一。
read
v0.10.0- 引入。Unreleased - Changed。
规范 API 名称:ptool.s3.Connection:read。
conn:read(path[, options]) 以原始字节读取对象,并返回 Lua 字符串。
path(string,必填):对象路径。options(table,选填):读取选项。- 返回:
string。
options 字段:
range(table,选填):使用半开区间[start, end)读取字节范围。start(integer,选填):要包含的首个字节偏移。end(integer,选填):要排除的首个字节偏移。
行为:
- 省略
range时读取整个对象。 { start = N }从字节N读取到结尾。{ end = N }从开头读取到字节N之前,但不包含字节N。{ start = A, end = B }读取从字节A到B - 1的内容。
示例:
local s3 = ptool.s3.connect({ bucket = "artifacts" })
local content = s3:read("releases/v1.0.0/notes.txt")
print(content)
local prefix = s3:read("releases/v1.0.0/notes.txt", {
range = { start = 0, end = 5 },
})
print(prefix)
write
v0.10.0- 引入。Unreleased - Changed。
规范 API 名称:ptool.s3.Connection:write。
conn:write(path, content[, options]) 将 Lua 字符串作为原始字节写入对象,并返回条目表。
path(string,必填):对象路径。content(string,必填):要上传的字节内容。options(table,选填):写入选项。- 返回:
table。
options 字段:
content_type(string,选填):设置对象内容类型。cache_control(string,选填):设置对象 cache-control 头。content_disposition(string,选填):设置对象 content-disposition 头。content_encoding(string,选填):设置对象 content-encoding 头。metadata(table,选填):将用户定义元信息设置为字符串键值对。if_not_exists(boolean,选填):仅当对象尚不存在时写入。默认为false。if_match(string,选填):仅当当前 ETag 匹配时写入。if_none_match(string,选填):仅当当前 ETag 不匹配时写入。
行为:
content会按字节原样上传。- 嵌入的 NUL 字节和非 UTF-8 字节会被保留。
- 返回的条目可避免为了常见元信息立刻再调用一次
stat()。 - 某些 S3 兼容服务可能不会在写入响应中回显用户定义的
metadata或etag。发生这种情况时,这些字段会保持为nil,直到后续调用stat()。
示例:
local s3 = ptool.s3.connect({ bucket = "artifacts" })
local entry = s3:write("tmp/hello.txt", "hello\n", {
content_type = "text/plain; charset=utf-8",
metadata = { author = "ptool" },
})
print(entry.path, entry.etag, entry.version)
s3:write("tmp/blob.bin", "\x00\xffABC")
delete
v0.10.0- 引入。
规范 API 名称:ptool.s3.Connection:delete。
conn:delete(path) 删除一个对象。
path(string,必填):对象路径。
exists
v0.10.0- 引入。
规范 API 名称:ptool.s3.Connection:exists。
conn:exists(path) 检查对象是否存在。
path(string,必填):对象路径。- 返回:
boolean。
list
v0.10.0- 引入。
规范 API 名称:ptool.s3.Connection:list。
conn:list([prefix]) 列出某个前缀下的条目,并返回致密 Lua 数组表。
prefix(string,选填):要列出的前缀。默认为连接根路径。- 返回:
table。
示例:
local s3 = ptool.s3.connect({ bucket = "artifacts", root = "builds/" })
local entries = s3:list("2026/")
for _, entry in ipairs(entries) do
print(entry.path, entry.mode, entry.size)
end
stat
v0.10.0- 引入。
规范 API 名称:ptool.s3.Connection:stat。
conn:stat(path) 返回单个对象的元数据。
path(string,必填):对象路径。- 返回:
table。
示例:
local s3 = ptool.s3.connect({ bucket = "artifacts" })
local meta = s3:stat("releases/v1.0.0/app.tar.zst")
print(meta.size, meta.etag, meta.last_modified)