PEP 301 – Distutils 的包索引和元数据
- 作者:
- Richard Jones <richard at python.org>
- 状态:
- 最终版
- 类型:
- 标准跟踪
- 主题:
- 打包
- 创建日期:
- 2002年10月24日
- Python 版本:
- 2.3
- 发布历史:
- 2002年11月08日
摘要
本 PEP 提出了 Distutils 打包系统的几项扩展 [1]。这些增强功能包括一个中央包索引服务器、用于向索引提交包信息的工具,以及扩展包元数据以包含 Trove [2] 信息。
本 PEP 不涉及包依赖问题。它也不涉及 PEP 243 中描述的包存储和下载。它也没有提议建立一个如 PEP 262 中所述的本地包数据库。
现有的包仓库,如 Vaults of Parnassus [3]、CPAN [4] 和 PAUSE [5],将被作为此领域的现有技术进行研究。
基本原理
Python 程序员长期以来一直需要一种简单的方法来发现可供他们使用的现有模块和系统。可以说,其他语言中这些系统的存在对它们的普及做出了重大贡献。Catalog-SIG 的存在以及那里的许多讨论表明,有大量用户认识到这一需求。
Python 引入 Distutils 打包系统简化了共享代码的发布过程,并包含了捕获包元数据的机制,但除了随包一起发布元数据之外,并没有对其做太多处理。
索引的接口应托管在 python.org 域名下,这会赋予它现有目录工作所不具备的合法性。
向目录提交信息的接口应尽可能简单——希望对大多数用户来说只是一行命令。
由于此类系统的复杂性,包依赖问题未被解决。PEP 262 提出了一个这样的系统,但截至本文撰写之时,该 PEP 仍未完成。
包传播(在中央服务器上存储)问题未被解决,因为它们需要对存储和带宽可用性做出假设,而我无法做出这些假设。PEP 243 仍在开发中,正在解决这些以及更多问题。本提案被认为与 PEP 243 中的提案兼容且互补。
规范
该规范分为三个部分:网页界面、Distutils 注册命令 和 Distutils Trove 分类。
网页界面
网页界面是在一个简单的存储之上实现的。该界面可通过 python.org 域名直接访问,或作为 packages.python.org 访问。
存储具有所有元数据字段的列。(名称, 版本) 对用作唯一键。对现有 (名称, 版本) 的额外提交将导致更新操作。
网页界面实现以下命令/接口
- 索引
- 列出已知包,可选择过滤。一个附加的 HTML 页面,搜索,向用户呈现一个表单,用于自定义索引视图。索引将包括一个浏览界面,如 Trove 界面设计第 4.3 节所示。结果将分页,按字母顺序排序,并且只显示最新版本。最新版本信息将使用 Distutils LooseVersion 类确定。
- 显示
- 显示有关包的信息。所有字段都以纯文本形式显示。“url”(或“home_page”)字段是超链接的。
- 提交
- 接受关于包元数据的 POST 提交。“name”和“version”字段是强制性的,因为它们唯一标识索引中的一个条目。提交将自动确定是创建新条目还是更新现有条目。元数据在适当的情况下会进行正确性检查——特别是 Trove 鉴别器会与允许的集合进行比较。更新将根据新提交的信息更新包的所有信息。
还将有一个提交/编辑表单,允许不使用 Distutils 的用户进行手动提交和更新。
- 提交_pkg_info
- 接受 PKG-INFO 文件的 POST 提交,并执行与 submit 接口相同的功能。
- user
- 在索引中注册新用户。需要用户名、密码和电子邮件地址。密码将以 SHA 散列形式存储在索引数据库中。如果用户名已存在于数据库中
- 如果提供了有效的 HTTP 基本认证,密码和电子邮件地址将使用提交信息进行更新,或者
- 如果未提供有效认证,则通知用户该登录名已被占用。
注册将是一个三步过程,包括
- 用户通过 Distutils register 命令或通过网络提交详细信息,
- 索引服务器向用户电子邮件地址发送一封电子邮件,其中包含一个带有随机一次性密钥的 URL,供用户访问以确认注册,以及
- 用户使用密钥访问 URL 并确认注册。
- 角色
- 一个用于更改用户角色分配的界面。
- 密码重置
- 使用提供的电子邮件地址作为密钥,这将重置用户的密码并将新密码发送到用户的电子邮件中。
提交命令将需要 HTTP 基本认证,最好通过 HTTPS 连接。
服务器接口将通过标准 HTTP 响应代码的子集指示命令的成功或失败
| 代码 | 含义 | 注册命令含义 |
|---|---|---|
| 200 | OK | 一切正常 |
| 400 | Bad request | 提交数据格式错误 |
| 401 | Unauthorised | 提供的用户名或密码不正确 |
| 403 | Forbidden | 用户没有权限更新包信息(不是所有者或维护者) |
用户角色
三个用户角色将可分配给用户
- 所有者
- 拥有包名,可以为该包名分配维护者角色。第一个注册包信息的用户被视为包名的所有者。如有必要,管理员用户可以更改此设置。可以提交该包名的更新。
- 维护者
- 可以为特定包名提交和更新信息。
- 管理员
- 可以分配所有者角色和编辑用户详细信息。不特定于包名。
索引存储(Schema)
索引存储在一组关系数据库表中
- 包
- 列出包名并保存包级别元数据(目前仅限稳定发布版本)
- 发布
- 每个包在其发布的每个版本在 releases 中都有一个条目。一行包含包的 PKG-INFO 文件中给出的大部分信息。每个包(名称,版本)有一行。
- trove_鉴别器
- 列出 Trove 鉴别器文本并为每个分配一个唯一 ID。
- 发布_鉴别器
- 每个条目将一个包(名称、版本)映射到一个 discriminator_id。我们映射到发布而不是包,因为鉴别器集合可能在不同发布之间发生变化。
- 日志
- 保存索引中包信息更改的信息。对 packages、releases、roles 和 release_discriminators 表的更改按包 name 和 version 列出,如果更改是特定于发布的。
- 用户
- 保存我们的用户数据库——用户名、电子邮件地址和密码。
- 角色
- 将 user_name 和 role_name 映射到 package_name。
一个附加表 rego_otk 存储注册期间生成的一次性密钥,它本身在索引范围内并不重要。
Distutils register 命令
实现了另一个 Distutils 命令 register,它将包元数据发布到中央索引。register 命令自动处理用户注册;用户有三个选项
- 登录并提交包信息
- 注册为新包开发者
- 发送密码提醒邮件
在设置了 $HOME 环境变量的系统上,用户在退出时会被提示将其用户名/密码保存到其 $HOME 目录中的文件 .pypirc 中。
包条目更改的通知将发送给所有提交了包信息的用户。也就是说,原始提交者和所有后续更新者。
register 命令将包含一个 --verify 选项,该选项对索引执行测试提交,但不实际提交数据。索引将照常执行其提交验证检查,并报告在正常提交期间会报告的任何错误。这对于验证 Trove 鉴别器的正确性很有用。
Distutils Trove 分类
Trove 的鉴别概念将通过新属性“classifiers”添加到包作者可用的元数据集中。分类器列表将通过网络提供,并像这样添加到包中
setup(
name = "roundup",
version = __version__,
classifiers = [
'Development Status :: 4 - Beta',
'Environment :: Console',
'Environment :: Web Environment',
'Intended Audience :: End Users/Desktop',
'Intended Audience :: Developers',
'Intended Audience :: System Administrators',
'License :: OSI Approved :: Python Software Foundation License',
'Operating System :: MacOS :: MacOS X',
'Operating System :: Microsoft :: Windows',
'Operating System :: POSIX',
'Programming Language :: Python',
'Topic :: Communications :: Email',
'Topic :: Office/Business',
'Topic :: Software Development :: Bug Tracking',
],
url = 'http://sourceforge.net/projects/roundup/',
...
)
由于更正式的 Python 结构会涉及深层嵌套,因此决定使用字符串作为分类条目。
原始 Trove 规范中分类命名空间应由斜杠(“/”)分隔的规定,不幸地与许多名称中包含斜杠(例如“OS/2”)相冲突。SourceForge 和 FreshMeat 实现的双冒号解决方案(“::”)解决了这一限制。
模块索引上的分类值列表已从 FreshMeat 和 SourceForge 合并(经他们许可)。此列表将通过 Web 界面和 register 命令的 --list-classifiers 选项以文本列表形式提供,然后可以将其复制到 setup.py 文件中。register 命令的 --verify 选项将根据服务器的列表检查分类器值。
不幸的是,“classifiers”属性的添加不向后兼容。使用它的 setup.py 文件在 Python 2.1.3 下将无法工作。希望 Python 2.2 的一个错误修复版本(很可能是 2.2.3)将放宽 setup() 命令的参数检查,以允许新的关键字,即使它们实际上没有被使用。最好是产生警告,而不是阻碍性的错误。在包被宣传为与早于 2.2.3 或 2.3 的 python 版本兼容的情况下,应不鼓励使用新关键字。
在 PKG-INFO 中,分类器列表项将显示为单独的 Classifier: 条目
Name: roundup
Version: 0.5.2
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console (Text Based)
.
.
Classifier: Topic :: Software Development :: Bug Tracking
Url: http://sourceforge.net/projects/roundup/
实施
服务器可在以下网址访问:
代码可从 SourceForge 项目获取:
register 命令已集成到 Python 2.3 中。
被拒绝的提案
最初,索引服务器将返回自定义标头(受 PEP 243 启发)
- X-Pypi-Status
- “成功”或“失败”。
- X-Pypi-Reason
- 失败原因的描述,或成功情况下的附加信息。
然而,有人指出 [6] 这是一个糟糕的方案。
参考资料
版权
本文档已置于公共领域。
致谢
Anthony Baxter、Martin v. Loewis 和 David Goodger 在初稿期间给予的鼓励和反馈。
A.M. Kuchling 的支持,包括托管第二个原型。
Greg Stein 建议注册命令应解释 HTTP 响应代码而不是自定义 X-PyPI-* 标头。
Distutils 和 Catalog SIG 的众多参与者多年来提供的想法。
来源:https://github.com/python/peps/blob/main/peps/pep-0301.rst