Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

irepo-artifact

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

发布后安装:

python -m pip install 'irepo-artifact==0.2.4.dev0'

源码开发安装:

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=oss。OSS 链接签发返回 502/503 时按需请求 download_mode=proxy;取得 OSS 链接后探测内网端点,不可达时也请求 proxy, 可达时使用 OSS。OSS 实际下载发生远端故障时,为该 Job 另行请求 proxy 链接并从头下载。单 Job 与批量下载使用相同策略。 未返回 downloads(或为 null/空对象)时使用旧版单 url,也支持 dataplane 地址。 单 URL 仅在 hostname 匹配标准 OSS 域名时标记 channel='oss';其余返回 channel=None,表示无法从响应确认通道,不表示下载失败。

标准区域 OSS 公网域名会在下载和重定向时转换为对应 -internal endpoint, 保留路径、端口及签名查询参数;已有内网域名保持不变。内网 OSS 失败不尝试原公网 地址。自定义域名和加速域名保持原样,不属于本转换规则。 返回的原始响应保留服务端 URL,不因实际下载地址转换而修改。 OSS 网络、TLS 或 HTTP 下载失败时申请并尝试 proxy,从头下载;401/403 最多重新签发一次, 429/5xx 同通道最多 3 次尝试后回退。 本地 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,表示转换后的候选地址,不表示已完成该通道下载。 日志中的下载地址(包括 internal_url)和服务端接口隐藏全部查询参数,显示为 ?<redacted>。 完整整包链接仍保留在 result.artifacts_response 中,可由调用方显式读取用于 curl;SDK 不自动写入 JSON 文件。 不输出 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?<redacted> links_received

OSS 内网短探测

整包下载先取得一个 Job 的 OSS 链接,在首次 OSS 下载前对最终内网地址做 TCP 连接探测, 连接超时为 min(0.5, timeout) 秒,不发送 HEAD 或签名查询参数。 每次 download()、download_many()、download_group() 调用共享一次结果(假设同次调用的 OSS endpoint 可作为整批网络环境样本),并发线程和后续批次不重复探测;调用结束即丢弃, 没有跨调用缓存。首个 Job 无产物或没有 OSS 链接时,在后续批次中继续寻找样本。 探测失败则为相关 Job 请求 proxy;探测成功仍使用原 timeout 下载 OSS,逐 Job 失败后 申请 proxy 回退。旧版单 URL 响应和筛选下载保持原有行为。返回的原始元数据保持完整。

TCP 成功不保证 TLS/HTTP 下载成功;连接超时不包含 DNS 和所有候选地址的严格总耗时限制。 同次调用中网络恢复后不会重新探测,下一次调用重新判断。

Metadata

Release files for irepo-artifact 0.2.4.dev0

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.4.dev0
File Size Uploaded Provenance Actions
irepo_artifact-0.2.4.dev0.tar.gz 30.2 kB Without provenance Details for irepo_artifact-0.2.4.dev0.tar.gz

Built distribution (wheel)

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

Total release size: 57.2 kB

Release files / irepo_artifact-0.2.4.dev0.tar.gz

Download URL irepo_artifact-0.2.4.dev0.tar.gz
Size 30.2 kB
Tags Source
SHA-256 checksum
How to use checksums
039e33aaf7c1f33f84b596e83aac16373907c9ebf7243fc65cad33a33096ecbf
BLAKE2b-256 checksum
How to use checksums
f3d383b7bc8561059245a28cfdda01c41c40b7cfeb48edab80a5f43cf8e82249
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.4.dev0-py3-none-any.whl

Download URL irepo_artifact-0.2.4.dev0-py3-none-any.whl
Size 27.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
129642afd2b9facb2488ad8d0788af649f1692e252d7ed66c0da832d52714bf8
BLAKE2b-256 checksum
How to use checksums
4b0d50340303df5789be1f545e0a741859259361302674993901f1305db0e8dd
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.4.dev0

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