Skip to main content

irepo-artifact

Python 3.10+ 的独立产物下载包。通过 AP 获取链接后 HTTP 下载,不依赖 instance-repo、ap-client、oss2 或 STS。完整 SDK 与未来的 ap-client 均可单向依赖此包。

安装发布版本:

python -m pip install 'irepo-artifact==0.2.0'

源码开发安装:

python -m pip install ./sdk/python-artifact

使用

from irepo_artifact import ArtifactClient

client = ArtifactClient(
    ap_endpoint="https://ap.example.invalid",  # 根地址,不带 /api
    api_key=api_key,
    cluster=cluster,
)
archive = client.download("job-a", output_dir="out/job-a")
expanded = client.download("job-b", output_dir="out/job-b", extract=True)
selected = client.download(
    "job-c", output_dir="out/job-c",
    include_files=["logs", "result.json"], exclude_files=["debug.log"],
)
batch = client.download_many(["job-d", "job-e"], output_dir="out", max_concurrent=8)
group = client.download_group("group-a", output_dir="group-out")

默认保存完整 result.tgz,不解压。extract=True 展开到 artifacts/output/, 保留压缩包。单 Job 的 output_dir 就是 Job 目录;批量与 Group 写入 <output_dir>/jobs/<job_id>/。不要让不同单 Job 共用一个输出目录。

单 Job 成功返回 DownloadResult,失败抛出 ArtifactError 子类。批量返回 dict[job_id, DownloadResult],默认 8 个 Job 并发,重复 Job 去重;各 Job 状态为 success、missing、no_match 或 failed,一项失败不阻止其他项。 结果提供实际 archive_path、files_dir、files 和 channel,调用方无需猜测路径。

文件筛选

先读取完整 manifest,include 取并集,再排除 exclude。只传 exclude 时从全部文件中排除; 两个列表都为空时下载完整包。带 / 的选择器匹配相对路径或目录前缀,不带 / 则匹配 任意层级的完整路径段;不支持 glob。SDK 的每个列表元素是一个选择器,不拆分逗号。

筛选后向 AP 按每批最多 500 个原始路径获取签名链接,下载返回 URL;不自行构造 dataplane 地址。筛选与 extract=True 冲突,选中的压缩文件也按原样保存。无匹配文件时报告 NoMatchingFiles,不下载整包,不覆盖旧输出。按完整 manifest 识别并去掉唯一共同根目录, 目录条目不足时保留原路径;解压完整包也按 AP 风格归一化到 artifacts/output/。

传输与输出

完整包请求 download_mode=both,OSS 优先;只有 proxy 时直接使用 proxy。 未返回 downloads(或为 null/空对象)时使用旧版单 url,也支持 dataplane 地址。 单 URL 仅在 hostname 匹配标准 OSS 域名时标记 channel='oss';其余返回 channel=None,表示无法从响应确认通道,不表示下载失败。

标准区域 OSS 公网域名会在下载和重定向时转换为对应 -internal endpoint, 保留路径、端口及签名查询参数;已有内网域名保持不变。内网 OSS 失败不尝试原公网 地址,有 proxy 链接时仍可回退 proxy。自定义域名和加速域名保持原样,不属于本转换规则。 返回的原始响应保留服务端 URL,不因实际下载地址转换而修改。 OSS 网络、TLS 或 HTTP 下载失败时尝试可用的 proxy,并从头下载;401/403 最多重新签发一次, 429/5xx 同通道最多 3 次尝试后回退。OSS 链接刷新失败仍可使用已有 proxy 链接。 本地 IO 和解压错误不触发切换;不会关闭 TLS 校验。 HTTP 传输成功不代表归档内容有效:默认不解压时不会检查归档完整性; 开启解压后若发现归档损坏,会报错,但不会因此尝试另一通道。 默认 timeout=30 是 socket 阻塞等待上限,不是整个下载的总时长。 签名 URL 不携带 AP 身份头;错误信息不包含 URL 查询参数或响应正文。

输出路径及父目录不允许符号链接;系统临时目录若含符号链接别名,请显式选择解析后的真实路径。 已有 result.tgz 或 artifacts/ 时默认拒绝,显式 overwrite=True 才替换这两个 受管理位置,其他用户文件保持不变。传输与解压使用暂存内容;失败保留旧结果。 覆盖成功后退役旧模式输出,例如筛选下载完成后删除旧压缩包。提交异常会尝试回滚; 多个路径替换不保证进程崩溃时的事务性。进程锁文件存放在当前用户的系统临时目录中,按输出路径隔离, 不会添加导出文件;锁文件不应手工删除。进程退出 (包括强制终止)后操作系统自动释放锁。回滚自身失败时保留 .artifact-* 中的备份供恢复。

服务端前提与兼容

整包兼容双通道 downloads 和旧版单 url 响应。文件 manifest/签发接口当前要求服务端 proxy 配置, 否则报告服务端错误;请确认目标服务已支持所需接口。API Key 只发往 AP。

权限由 AP artifact 接口统一校验,SDK 不再发起 Job 详情预检查。 旧 IREPO_ARTIFACT_CHECK_JOB_ACCESS 环境变量已删除,不再影响行为。

请求配置与 AP export 接入(0.1.0.dev2)

client = ArtifactClient(
    ap_endpoint="https://ap.example.invalid",
    api_key=api_key, cluster=cluster,
    headers={"X-Custom": "value"},
    api_prefix="/api",  # 直连或 endpoint 已含 /api 时传空字符串
    timeout=30,        # 正数秒,控制面与下载共用的 socket 等待上限
    manifest_wait_timeout=1800,  # 每个 Job 获取 manifest 的累计等待预算
    layout="ap_export",  # 对齐 AP 的共同根规则;无匹配时成功返回空 output
)

headers 仅用于 AP 请求,显式 api_key/cluster 覆盖同名头,不传播到签名 URL。 默认 layout="sdk" 保留旧版 SDK 的无匹配异常及共同根行为。 timeout 是控制面与下载共用的 socket 等待上限,不是整个下载总时限。 0.2.0 优先请求 /jobs/{job_id}/artifacts/manifest,收到 202 preparing 后按 Retry-After 轮询(无效或缺省值使用 2 秒)。首次请求返回 404/405 时尝试旧接口 /jobs/{job_id}/artifacts-manifest?require_file_download=true;旧接口仍只接受 200。 权限错误、409、网络错误、429/5xx、无效响应及 preparing 后的失败均不触发协议回退。 manifest 请求的网络错误及 HTTP 408、429、500、502、503、504 最多尝试 3 次,其他状态不重试。 HTTP 退避从 0.5 秒开始翻倍、上限 2 秒;与服务端 Retry-After(秒数或 HTTP 日期)取较大值。 成功的 preparing 响应开启下一轮请求,202 的轮询等待规则保持不变。 筛选文件返回 401/403 时刷新当前批次的剩余链接和有效期,每个文件最多触发一次鉴权刷新。

manifest_wait_timeout 默认 1800 秒,必须是有限正数。每个 Job 独立计时,请求、轮询、重试、 退避和旧接口回退共用预算;不包含后续文件签名、下载及解压,也不是整个 Group 的总时限。 不读取 AP 专属环境变量。AP 集成可传入 manifest_wait_timeout=client.config.artifact_manifest_wait_timeout。

两条 manifest 路由均返回 404 时保留为协议失败,不能据此认定没有产物;有效响应的 manifest: null 才明确表示缺失。错误信息保留新旧接口状态,不包含响应正文。 0.1.2 及此前的 0.1.0.dev3 起版本仅请求旧接口。

DownloadResult 与 ArtifactError 均提供 artifacts_response、manifest_response,未取得对应 JSON 对象时为 None。原始对象保留未知字段,校验失败和产物缺失也可读取;批量失败结果提供同名字段。 链接刷新成功且通道可用时替换整份整包响应,刷新失败保留此前对象;文件 URL 刷新不覆盖 manifest。 这些字段不出现在默认 repr/str 中,调用方自行决定是否保存含签名链接的 JSON。

SDK 不写 artifacts.json 或 artifacts-manifest.json。AP 整包模式保存 artifacts_response;筛选模式 保存 manifest_response,并继续自行生成 {"job_id": job_id, "url": None, "mode": "selected_files"}。 筛选模式不会额外请求整包链接,artifacts_response 为 None。AP 仍负责 job.json、metrics.json、 缺失时保留/清理导出目录和 skipped 统计。示例:

from irepo_artifact import ArtifactError
try:
    result = client.download("job-a", output_dir="out/job-a", extract=True)
    metadata = result.artifacts_response
except ArtifactError as error:
    metadata = error.artifacts_response
    # 调用方可保存 metadata,再依据异常类型决定跳过或报错。
    raise

单个下载通道返回 404,或错误正文前 64 KiB 含 NoSuchKey,表示该通道缺失。 OSS 缺失仍会尝试 proxy;只有所有可用下载通道均确认缺失时才报告 ArtifactNotFound。 若同时出现普通下载故障,则报错而非按缺失跳过。正文读取失败时保留原 HTTP 状态处理,异常不包含正文。

解压保留文件、目录的普通权限位和修改时间,不恢复归档属主或 setuid/setgid/sticky 位。 支持最终输出目录范围内的相对符号链接、硬链接,以及按归档顺序覆盖的重复文件; 拒绝越界链接和设备文件。layout="ap_export" 的筛选下载保留 AP 的 artifacts 目录 0700 权限。

调试日志(0.1.2 起)

ArtifactClient(..., verbose=True) 启用精简 stderr 日志;默认 False,实例间开关独立, 不修改 root logger,也不读取 AP 环境变量。AP 统一构造入口可传入 verbose=client.config.verbose,但须先升级到包含此参数的 SDK 版本(0.1.2.dev0 尚不支持)。

日志仅包含服务端请求方法和接口、Job/Group 标识、返回的通道及下载地址,以及请求失败的 HTTP 状态或错误类型;文件链接带文件路径,刷新链接沿用相同日志。 标准 OSS 地址转换时同一行附带 internal_url,表示转换后的候选地址,不表示已完成该通道下载。 下载地址保留完整签名查询参数,可复制用于 curl;服务端请求接口的查询参数仍隐藏。 不输出 AP 认证头、API Key、响应正文、下载进度或解压日志。 未知单 URL 的通道记录为 unknown。日志写入失败不改变下载结果。

[irepo-artifact] job=j1 POST https://ap.example/api/jobs/artifacts
[irepo-artifact] job=j1 channel=proxy url=https://dp.example/result.tgz?signature=example links_received

Metadata

Release files for irepo-artifact 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for irepo-artifact 0.2.0
File Size Uploaded Provenance Actions
irepo_artifact-0.2.0.tar.gz 27.2 kB Without provenance Details for irepo_artifact-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for irepo-artifact 0.2.0
File Interpreter ABI Platform Actions
irepo_artifact-0.2.0-py3-none-any.whl Python 3 none any Details for irepo_artifact-0.2.0-py3-none-any.whl

Total release size: 51.6 kB

Release files / irepo_artifact-0.2.0.tar.gz

Download URL irepo_artifact-0.2.0.tar.gz
Size 27.2 kB
Tags Source
SHA-256 checksum
How to use checksums
404b4251dfadf141f9385223c5e075a6db3f0c36556816452ecc111241e6a29b
BLAKE2b-256 checksum
How to use checksums
39fd75cefa172521d6b96df03c9ccead0212abe038a705e6489098a6da50aa09
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.19

Release files / irepo_artifact-0.2.0-py3-none-any.whl

Download URL irepo_artifact-0.2.0-py3-none-any.whl
Size 24.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
814501511197f57b57366c7723148c1021a357b241bbf99b8fa18d4829536bc4
BLAKE2b-256 checksum
How to use checksums
1478a3d8158d2f2051b7d5b982cdb8a72f0a4636c19a1fa7b2fb01185c07ab38
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.19

Security for irepo-artifact 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page