
开发工具构建工具【免费下载链接】hatchModern, extensible Python project management项目地址https://gitcode.com/gh_mirrors/ha/hatch点击查看免费下载Hatch 的hatch publish命令在将构建产物上传到 PyPI 或私有索引时需要一套灵活且安全的认证机制。本篇指南以 Hatch 官方 How-To 文档 docs/how-to/publish/auth.md 为骨架结合仓库源码 src/hatch/publish/auth.py 与 src/hatch/cli/publish/init.py完整讲解用户名与密码的逐级解析顺序、~/.pypirc与repos表的联动、交互式凭据的持久化规则以及面向 CI 的 Trusted Publishing 与 API Token 自动化发布方案。读完本文你将能精确控制 Hatch 发布时的认证来源并避免常见的安全隐患。认证在 Hatch 发布流程中的位置在深入认证细节之前先明确它在整个发布链路中的角色。hatch publish默认使用内置的index发布插件其核心入口是 src/hatch/publish/index.py 中的IndexPublisher.publish方法它先解析目标仓库配置然后实例化AuthenticationCredentials见 src/hatch/publish/auth.py来获取用户名与密码最后交给 src/hatch/index/core.py 的PackageIndex完成上传。在PackageIndex.upload_artifact中凭据以auth(self.user, self.auth)的形式作为 HTTP 基本认证发送src/hatch/index/core.py。也就是说认证解析是每次上传前必经的一步而AuthenticationCredentials正是这套解析逻辑的实现核心。理解它的查找顺序就等于掌握了 Hatch 认证的全部规则。用户名Username的解析优先级根据官方文档Hatch 按下述优先级依次查找用户名先命中的值生效--user/-u命令行选项HATCH_INDEX_USER环境变量repos表中该仓库配置的user字段~/.pypirc文件交互式提示输入。若以上全部缺失则回退使用__token__作为用户名。这一顺序在 src/hatch/publish/auth.py 的AuthenticationCredentials.__get_username方法中有直接的代码印证username ( self._options.get(user) or self._repo_config.get(user) or self._read_pypirc() or self._read_previous_working_user_data() ) if username is not None: return username if self._options[no_prompt]: self._app.abort(Missing required option: user) self.__username_was_read True return self._app.prompt(fUsername for {self._repo_config[url]} [__token__]) or __token__CLI 选项与环境变量命令行选项定义在 src/hatch/cli/publish/init.pyhatch publish --user myusername --auth mypassword # 或缩写形式 hatch publish -u myusername -a mypassword其中--auth/-a对应的是密码见下文。环境变量HATCH_INDEX_USER与HATCH_INDEX_AUTH的常量定义位于 src/hatch/config/constants.py 的PublishEnvVars类中CLI 通过 click 的envvar参数直接绑定class PublishEnvVars: USER HATCH_INDEX_USER AUTH HATCH_INDEX_AUTH REPO HATCH_INDEX_REPO # ...因此HATCH_INDEX_USER与--user完全等价适合在不暴露命令行历史的情况下注入凭据。repos 表中的 user 字段publish.index.repos表是 Hatch 配置文件中的命名仓库集合每个仓库都可以独立覆盖顶层选项详见 docs/plugins/publisher/package-index.md。若在某个仓库条目中设置了user则发布到该仓库时它优先于~/.pypirc和交互提示[publish.index.repos.private] url https://pypi.example.com/legacy/ user release-bot auth s3cr3t-token在源码层面IndexPublisher.get_repos会为每个仓库配置config.setdefault(key, value)填充顶层默认值src/hatch/publish/index.py而AuthenticationCredentials通过self._repo_config.get(user)读取该字段。关于仓库的命名、保留名main/test与选择方式可参阅 docs/how-to/publish/repo.md。~/.pypirc 的读取规则AuthenticationCredentials._read_pypirc使用标准库configparser解析~/.pypirc匹配逻辑有两条路径按 section 名匹配若.pypirc中存在与当前--repo值同名的 section未指定--repo时默认pypi直接取该 section 的username与password按仓库 URL 匹配遍历所有 section找到repository字段值等于当前仓库 URL 的那一项取其凭据。需要特别注意的是_read_pypirc在返回用户名的同时会顺带把该 section 的password赋给内部属性self.__password ...这解释了官方文档中密码查找顺序的第 1 条——如果用户名由.pypirc提供则密码也直接取自.pypirc。这是一个隐式绑定用户名和密码在同一 section 内成对使用。一个典型的~/.pypirc结构如下标准格式由 Python 打包规范定义[distutils] index-servers pypi private [pypi] username __token__ password pypi-xxxxxxxxxxxxxxxx [private] repository https://pypi.example.com/legacy/ username release-bot password s3cr3t-token回退用户名token若上述所有来源均未提供用户名且允许交互Hatch 会提示Username for 仓库URL [__token__]默认值即为__token__。这与 PyPI 的 API Token 机制用户名固定为__token__完全对齐当你在 PyPI 上使用pypi-开头的令牌时无需输入真实账号名直接回车即可。密码Password的解析优先级密码的查找顺序与用户名不同且与用户名来源存在联动~/.pypirc文件仅当用户名由它提供时才会读取其密码--auth/-a命令行选项HATCH_INDEX_AUTH环境变量repos表中该仓库配置的auth字段基于 keyring 的各类操作系统级凭据服务macOS Keychain、Windows Credential Locker、Linux Secret Service 等交互式提示输入。源码实现位于AuthenticationCredentials.__get_passwordpassword self._options.get(auth) or self._repo_config.get(auth) if password is not None: return password import keyring keyring_service self._repo_config[url] password keyring.get_password(keyring_service, self.username) if password is not None: return password if self._options[no_prompt]: self._app.abort(Missing required option: auth) self.__password_was_read True return self._app.prompt(Password / Token, hide_inputTrue)密码来源联动关系对照源码可以发现几条重要的联动细节.pypirc只在用户名来自它时参与密码解析。__get_password方法开头的注释明确写道this method doesnt consider.pypircas the__passwordattribute would have been set when it was looked up during username retrieval——即.pypirc的密码在_read_pypirc阶段就已提前注入__get_password不再重复读取。keyring 的服务名是仓库 URLkeyring.get_password(self._repo_config[url], self.username)即凭据以仓库 URL 用户名为键存储。这意味着同一用户名在不同索引上会使用不同的 keyring 条目互不干扰。--auth与HATCH_INDEX_AUTH由同一 click 选项承载--auth通过envvarPublishEnvVars.AUTH绑定HATCH_INDEX_AUTH见 src/hatch/cli/publish/init.py因此两者在解析层面等价统一落入options[auth]。一个典型解析示例假设你执行以下命令向私有仓库上传hatch publish --repo private --user release-bot未传--auth则密码解析路径为HATCH_INDEX_AUTH若设置→repos表的auth字段 → keyring 查询服务名 私有仓库 URL用户名 release-bot→ 交互提示。如果~/.pypirc中存在名为private的 section则用户名与密码都会优先从.pypirc直接取用--user反而会被忽略——因为用户名的第 4 优先级已经命中。交互式凭据的持久化规则当用户名或密码最终来自交互提示而非任何配置文件时Hatch 会在成功发布后将其持久化规则如下见官方文档与 src/hatch/publish/auth.py 的write_updated_data用户名写入 Hatch 缓存目录下的previous_working_users.jsoncache_dir / previous_working_users.json以仓库名为键记录上次成功使用的用户名密码写入 keyring 支持的凭据服务服务名同样为仓库 URL。持久化动作由IndexPublisher.publish末尾的credentials.write_updated_data()触发src/hatch/publish/index.py且只在实际发生过凭据读取__username_was_read/__password_was_read为真时才写入。这样设计的好处是首次交互输入一次后后续发布可直接从缓存与 keyring 复用凭据无需重复输入而previous_working_users.json还能让交互提示框自动预填上次成功的用户名。关于 Hatch 缓存目录的位置与自定义HATCH_CACHE_DIR可参考 docs/config/hatch.md。相关 CLI 标志交互行为受两个标志控制src/hatch/cli/publish/init.py-n/--no-prompt禁用所有提示。若缺少用户名或密码Hatch 直接以Missing required option: user/Missing required option: auth中止而不是等待输入——这正是 CI 场景下防止任务卡死的开关--initialize-auth即使没有发布任何产物也保存首次认证信息。适用于先认证、后构建的流程测试用例test_initialize_auth见 tests/cli/publish/test_publish.py验证了该行为。自动化发布Trusted Publishing 与 API Token对于自动化向 PyPI 发布如 CI/CD 流水线官方文档明确建议两种方式均避免将明文密码写入仓库或日志Trusted PublishingOIDC 可信发布基于 OpenID Connect 的免凭据认证由 PyPI 侧的 Trusted Publisher 机制与发布方的 OIDC 身份例如 GitHub Actions 的id-token权限联合完成。官方推荐配合 PyPA 的pypi-publishGitHub Action 使用典型的 CI 步骤包括先构建hatch build再以hatch publish或等效动作上传全程不出现用户名与密码按项目生成的 API Token在 PyPI 账户中为单个项目创建 token将其作为密码、以__token__作为用户名注入。由于用户名固定为__token__正好对应 Hatch 的回退机制可用环境变量注入HATCH_INDEX_USER__token__ HATCH_INDEX_AUTHpypi-xxxxxxxxxxxxxxxx hatch publish在 CI 中推荐配合--no-prompt确保凭据缺失时快速失败而不是挂起等待输入。同时注意不要把 token 直接写进命令或配置文件并提交到仓库优先使用 CI 平台的 Secret 机制注入HATCH_INDEX_AUTH。测试与验证仓库中的行为证据仓库的测试套件 tests/cli/publish/test_publish.py 对上述规则提供了可复现的验证值得作为学习参考keyring_storefixture 用mocker.patch模拟keyring.get_password/keyring.set_password将 keyring 替换为内存字典隔离真实系统凭据服务test_missing_auth验证-n模式下缺少密码会输出Missing required option: auth并中止test_initialize_auth验证--initialize-auth在无产物发布时也能保存认证信息多组测试通过config_file.model.publish[index][auth] ...在配置层注入auth印证了repos表/顶层auth字段的生效路径。这些测试全部标记为requires_docker与requires_internet因为它们依赖仓库自带的 devpi 测试索引见 tests/index/server你可以据此在本地搭建私有索引完整复现认证流程。小结Hatch 的发布认证设计围绕层层回退、按需持久化展开用户名与密码各自拥有独立的 56 级解析链~/.pypirc的密码与用户名隐式绑定keyring 以仓库 URL 为服务名隔离不同索引的凭据交互输入的结果则分别落入缓存与系统凭据服务。对开发者而言本地开发可直接借助.pypirc或交互提示而自动化发布应优先采用 Trusted Publishing 或 API Token并配合--no-prompt保证 CI 的确定性。完整的命令选项列表可查阅 docs/cli/reference.md发布总览见 docs/publish.md。赞分享开发工具构建工具【免费下载链接】hatchModern, extensible Python project management项目地址https://gitcode.com/gh_mirrors/ha/hatch点击查看免费下载相关推荐OneUptime CLI 认证体系详解API 密钥、命名上下文与凭据解析优先级OneUptime CLI 认证体系详解API 密钥、命名上下文与凭据解析优先级 OneUptime 提供了命令行工具 oneuptime oneupt可观测性后端运维前端云原生微服务AI AgentGSD彻底解决AI编码质量衰退的终极上下文工程方案GSD彻底解决AI编码质量衰退的终极上下文工程方案 你是否曾遇到过这样的困境当你使用AI编码助手时初始阶段一切顺利但随着项目复杂度增加代码质量开始明显人工智能AI 应用提示工程开发工具工作流自动化AI AgentMosquitto 与 MQTT v3.1用户名密码认证的引入、演进与源码级实现解析Mosquitto 与 MQTT v3.1用户名密码认证的引入、演进与源码级实现解析 本文基于 Eclipse Mosquitto 仓库中发布于 2010 年物联网消息队列后端上一篇LMCache Transfer Channel 吞吐基准测试工具全解析架构、用法与性能调优下一篇5分钟掌握Godot游戏资源提取解决.pck文件访问难题创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考